triiiceratops 0.9.12 → 0.10.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/dist/ArrowCounterClockwise-aFffCOKw.js +136 -0
- package/dist/X-DZEgXrJ8.js +877 -0
- package/dist/annotation_tool_point-CZKsj4Nk.js +290 -0
- package/dist/components/AnnotationOverlay.svelte +179 -86
- package/dist/components/DemoHeader.svelte +12 -0
- package/dist/components/LeftFab.svelte +21 -9
- package/dist/components/OSDViewer.svelte +24 -4
- package/dist/components/SearchPanel.svelte +4 -1
- package/dist/components/TriiiceratopsViewer.svelte +114 -47
- 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-BEIf-_QA.js +108 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +0 -1
- package/dist/paraglide/messages/_index.d.ts +31 -0
- package/dist/paraglide/messages/_index.js +32 -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/paraglide/messages/settings_transparent_background.d.ts +4 -0
- package/dist/paraglide/messages/settings_transparent_background.js +34 -0
- 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 +5 -0
- package/dist/state/manifests.svelte.js +42 -13
- package/dist/state/viewer.svelte.d.ts +14 -13
- package/dist/state/viewer.svelte.js +63 -74
- package/dist/triiiceratops-bundle.js +3208 -3124
- package/dist/triiiceratops-element.iife.js +99 -0
- package/dist/triiiceratops.css +1 -1
- package/dist/types/config.d.ts +5 -0
- 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-DpZQA17w.js +0 -10435
- package/dist/chunks/openseadragon-5MHeYuQz.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
|
@@ -3,18 +3,25 @@
|
|
|
3
3
|
import PuzzlePiece from 'phosphor-svelte/lib/PuzzlePiece';
|
|
4
4
|
import X from 'phosphor-svelte/lib/X';
|
|
5
5
|
import { VIEWER_STATE_KEY, type ViewerState } from '../state/viewer.svelte';
|
|
6
|
-
import { m } from '../state/i18n.svelte';
|
|
6
|
+
import { m, language } from '../state/i18n.svelte';
|
|
7
7
|
|
|
8
8
|
const viewerState = getContext<ViewerState>(VIEWER_STATE_KEY);
|
|
9
9
|
|
|
10
|
-
let sortedPluginButtons = $derived(
|
|
11
|
-
|
|
10
|
+
let sortedPluginButtons = $derived.by(() => {
|
|
11
|
+
// Read language to trigger re-evaluation
|
|
12
|
+
language.current;
|
|
13
|
+
return [...viewerState.pluginMenuButtons].sort(
|
|
12
14
|
(a, b) => (a.order ?? 100) - (b.order ?? 100),
|
|
13
|
-
)
|
|
14
|
-
);
|
|
15
|
+
);
|
|
16
|
+
});
|
|
15
17
|
|
|
16
18
|
let isOpen = $state(false);
|
|
17
19
|
|
|
20
|
+
let pluginsTooltip = $derived.by(() => {
|
|
21
|
+
language.current;
|
|
22
|
+
return m.plugins_tooltip();
|
|
23
|
+
});
|
|
24
|
+
|
|
18
25
|
function toggleOpen() {
|
|
19
26
|
isOpen = !isOpen;
|
|
20
27
|
}
|
|
@@ -32,7 +39,13 @@
|
|
|
32
39
|
>
|
|
33
40
|
{#each sortedPluginButtons as button (button.id)}
|
|
34
41
|
{@const Icon = button.icon}
|
|
35
|
-
|
|
42
|
+
{@const tooltip =
|
|
43
|
+
// @ts-ignore - access message dynamically
|
|
44
|
+
typeof m[button.tooltip] === 'function'
|
|
45
|
+
? // @ts-ignore
|
|
46
|
+
m[button.tooltip]()
|
|
47
|
+
: button.tooltip}
|
|
48
|
+
<div class="tooltip tooltip-right" data-tip={tooltip}>
|
|
36
49
|
<button
|
|
37
50
|
aria-label={button.tooltip}
|
|
38
51
|
class="btn btn-lg btn-circle shadow-lg {button.isActive?.()
|
|
@@ -49,13 +62,12 @@
|
|
|
49
62
|
{/each}
|
|
50
63
|
</div>
|
|
51
64
|
|
|
52
|
-
|
|
53
|
-
<div class="tooltip tooltip-right" data-tip={m.plugins_tooltip()}>
|
|
65
|
+
<div class="tooltip tooltip-right" data-tip={pluginsTooltip}>
|
|
54
66
|
<button
|
|
55
67
|
class="btn btn-lg btn-secondary btn-circle shadow-xl transition-transform duration-300 {isOpen
|
|
56
68
|
? 'rotate-90'
|
|
57
69
|
: ''}"
|
|
58
|
-
aria-label={
|
|
70
|
+
aria-label={pluginsTooltip}
|
|
59
71
|
onclick={toggleOpen}
|
|
60
72
|
>
|
|
61
73
|
{#if isOpen}
|
|
@@ -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
|
|
@@ -218,13 +231,17 @@
|
|
|
218
231
|
<div class="w-full h-full relative">
|
|
219
232
|
<div
|
|
220
233
|
bind:this={container}
|
|
221
|
-
class="w-full h-full osd-background
|
|
234
|
+
class="w-full h-full osd-background {viewerState.config
|
|
235
|
+
.transparentBackground
|
|
236
|
+
? ''
|
|
237
|
+
: 'bg-base-100'}"
|
|
222
238
|
></div>
|
|
223
239
|
|
|
224
240
|
<!-- Render annotations -->
|
|
225
241
|
{#each renderedAnnotations as anno (anno.id)}
|
|
226
242
|
{#if anno.type === 'RECTANGLE'}
|
|
227
243
|
<div
|
|
244
|
+
id="annotation-visual-{anno.id}"
|
|
228
245
|
class="absolute border-2 transition-colors cursor-pointer pointer-events-auto {anno.isSearchHit
|
|
229
246
|
? 'border-yellow-400 bg-yellow-400/40 hover:bg-yellow-400/60'
|
|
230
247
|
: 'border-red-500 bg-red-500/20 hover:bg-red-500/40'}"
|
|
@@ -233,6 +250,7 @@
|
|
|
233
250
|
top: {anno.rect.y}px;
|
|
234
251
|
width: {anno.rect.width}px;
|
|
235
252
|
height: {anno.rect.height}px;
|
|
253
|
+
pointer-events: {anno.pointerEvents};
|
|
236
254
|
"
|
|
237
255
|
title={anno.tooltip}
|
|
238
256
|
></div>
|
|
@@ -244,10 +262,12 @@
|
|
|
244
262
|
top: {anno.bounds.y}px;
|
|
245
263
|
width: {anno.bounds.width}px;
|
|
246
264
|
height: {anno.bounds.height}px;
|
|
265
|
+
pointer-events: {anno.pointerEvents};
|
|
247
266
|
"
|
|
248
267
|
>
|
|
249
268
|
<title>{anno.tooltip}</title>
|
|
250
269
|
<polygon
|
|
270
|
+
id="annotation-visual-{anno.id}"
|
|
251
271
|
points={anno.points.map((p: any) => p.join(',')).join(' ')}
|
|
252
272
|
class="cursor-pointer transition-colors {anno.isSearchHit
|
|
253
273
|
? 'fill-yellow-400/40 stroke-yellow-400 hover:fill-yellow-400/60'
|
|
@@ -45,7 +45,10 @@
|
|
|
45
45
|
<!-- Drawer / Panel -->
|
|
46
46
|
{#if viewerState.showSearchPanel}
|
|
47
47
|
<div
|
|
48
|
-
class="h-full bg-base-200 shadow-2xl z-100 flex flex-col
|
|
48
|
+
class="h-full bg-base-200 shadow-2xl z-100 flex flex-col transition-[width] duration-200 {viewerState
|
|
49
|
+
.config.transparentBackground
|
|
50
|
+
? ''
|
|
51
|
+
: 'border-l border-base-300'}"
|
|
49
52
|
style="width: {width}"
|
|
50
53
|
role="dialog"
|
|
51
54
|
aria-label={m.search_panel_title()}
|
|
@@ -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(() => {
|
|
@@ -187,13 +223,19 @@
|
|
|
187
223
|
else if (body) resource = body;
|
|
188
224
|
}
|
|
189
225
|
|
|
190
|
-
// Check if resource is valid (Manifesto sometimes returns empty objects for v3 bodies)
|
|
191
|
-
|
|
226
|
+
// Check if resource is valid (Manifesto sometimes returns empty wrapper objects for v3 bodies)
|
|
227
|
+
// The wrapper may have getServices() that returns manifest-level services, so we can't rely on that.
|
|
228
|
+
// Instead, check if the resource has actual content (id, __jsonld, or a service property)
|
|
229
|
+
const resourceJson = resource?.__jsonld || resource;
|
|
230
|
+
const hasContent =
|
|
192
231
|
resource &&
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
232
|
+
(resource.id ||
|
|
233
|
+
resource['@id'] ||
|
|
234
|
+
(resourceJson &&
|
|
235
|
+
(resourceJson.service ||
|
|
236
|
+
resourceJson.id ||
|
|
237
|
+
resourceJson['@id'])));
|
|
238
|
+
if (resource && !hasContent) {
|
|
197
239
|
resource = null;
|
|
198
240
|
}
|
|
199
241
|
|
|
@@ -214,28 +256,27 @@
|
|
|
214
256
|
const getId = (thing: any) => thing.id || thing['@id'];
|
|
215
257
|
|
|
216
258
|
// Start of service detection logic
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
259
|
+
// Check raw json service FIRST - Manifesto's getServices() often returns
|
|
260
|
+
// manifest-level services instead of the image body's services
|
|
261
|
+
let services: any[] = [];
|
|
262
|
+
const rJson = resource.__jsonld || resource;
|
|
263
|
+
if (rJson.service) {
|
|
264
|
+
services = Array.isArray(rJson.service)
|
|
265
|
+
? rJson.service
|
|
266
|
+
: [rJson.service];
|
|
220
267
|
}
|
|
221
268
|
|
|
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
|
-
}
|
|
269
|
+
// Fallback to getServices() only if raw json didn't have services
|
|
270
|
+
if (!services.length && resource.getServices) {
|
|
271
|
+
services = resource.getServices();
|
|
231
272
|
}
|
|
232
273
|
|
|
233
|
-
// console.log('Found services:', services);
|
|
234
|
-
|
|
235
274
|
if (services.length > 0) {
|
|
236
275
|
// Find a valid image service
|
|
237
276
|
const service = services.find((s: any) => {
|
|
238
|
-
const type = s.getType
|
|
277
|
+
const type = s.getType
|
|
278
|
+
? s.getType()
|
|
279
|
+
: s.type || s['@type'] || '';
|
|
239
280
|
const profile = s.getProfile ? s.getProfile() : s.profile || '';
|
|
240
281
|
return (
|
|
241
282
|
type === 'ImageService1' ||
|
|
@@ -284,12 +325,18 @@
|
|
|
284
325
|
<div
|
|
285
326
|
bind:this={rootElement}
|
|
286
327
|
id="triiiceratops-viewer"
|
|
287
|
-
class="flex w-full h-full relative
|
|
328
|
+
class="flex w-full h-full relative overflow-hidden {internalViewerState
|
|
329
|
+
.config.transparentBackground
|
|
330
|
+
? ''
|
|
331
|
+
: 'bg-base-100'}"
|
|
288
332
|
>
|
|
289
333
|
<!-- Left Column -->
|
|
290
334
|
{#if isLeftSidebarVisible}
|
|
291
335
|
<div
|
|
292
|
-
class="flex-none flex flex-row z-20
|
|
336
|
+
class="flex-none flex flex-row z-20 transition-all {internalViewerState
|
|
337
|
+
.config.transparentBackground
|
|
338
|
+
? ''
|
|
339
|
+
: 'bg-base-200 border-r border-base-300'}"
|
|
293
340
|
>
|
|
294
341
|
<!-- Gallery (when docked left) -->
|
|
295
342
|
{#if internalViewerState.showThumbnailGallery && internalViewerState.dockSide === 'left'}
|
|
@@ -301,7 +348,10 @@
|
|
|
301
348
|
{#each internalViewerState.pluginPanels as panel (panel.id)}
|
|
302
349
|
{#if panel.isVisible() && panel.position === 'left'}
|
|
303
350
|
<div class="h-full relative pointer-events-auto">
|
|
304
|
-
<panel.component
|
|
351
|
+
<panel.component
|
|
352
|
+
{...panel.props ?? {}}
|
|
353
|
+
locale={language.current}
|
|
354
|
+
/>
|
|
305
355
|
</div>
|
|
306
356
|
{/if}
|
|
307
357
|
{/each}
|
|
@@ -323,7 +373,12 @@
|
|
|
323
373
|
{/if}
|
|
324
374
|
|
|
325
375
|
<!-- Main Viewer Area -->
|
|
326
|
-
<div
|
|
376
|
+
<div
|
|
377
|
+
class="flex-1 relative min-h-0 w-full h-full {internalViewerState
|
|
378
|
+
.config.transparentBackground
|
|
379
|
+
? ''
|
|
380
|
+
: 'bg-base-100'}"
|
|
381
|
+
>
|
|
327
382
|
{#if manifestData?.isFetching}
|
|
328
383
|
<div class="w-full h-full flex items-center justify-center">
|
|
329
384
|
<span
|
|
@@ -367,7 +422,10 @@
|
|
|
367
422
|
{#each internalViewerState.pluginPanels as panel (panel.id)}
|
|
368
423
|
{#if panel.isVisible() && panel.position === 'overlay'}
|
|
369
424
|
<div class="absolute inset-0 z-40 pointer-events-none">
|
|
370
|
-
<panel.component
|
|
425
|
+
<panel.component
|
|
426
|
+
{...panel.props ?? {}}
|
|
427
|
+
locale={language.current}
|
|
428
|
+
/>
|
|
371
429
|
</div>
|
|
372
430
|
{/if}
|
|
373
431
|
{/each}
|
|
@@ -396,7 +454,10 @@
|
|
|
396
454
|
{#each internalViewerState.pluginPanels as panel (panel.id)}
|
|
397
455
|
{#if panel.isVisible() && panel.position === 'bottom'}
|
|
398
456
|
<div class="relative w-full z-40 pointer-events-auto">
|
|
399
|
-
<panel.component
|
|
457
|
+
<panel.component
|
|
458
|
+
{...panel.props ?? {}}
|
|
459
|
+
locale={language.current}
|
|
460
|
+
/>
|
|
400
461
|
</div>
|
|
401
462
|
{/if}
|
|
402
463
|
{/each}
|
|
@@ -405,7 +466,10 @@
|
|
|
405
466
|
<!-- Right Column -->
|
|
406
467
|
{#if isRightSidebarVisible}
|
|
407
468
|
<div
|
|
408
|
-
class="flex-none flex flex-row z-20
|
|
469
|
+
class="flex-none flex flex-row z-20 transition-all {internalViewerState
|
|
470
|
+
.config.transparentBackground
|
|
471
|
+
? ''
|
|
472
|
+
: 'bg-base-200 border-l border-base-300'}"
|
|
409
473
|
>
|
|
410
474
|
<!-- Search Panel -->
|
|
411
475
|
{#if internalViewerState.showSearchPanel}
|
|
@@ -425,7 +489,10 @@
|
|
|
425
489
|
{#each internalViewerState.pluginPanels as panel (panel.id)}
|
|
426
490
|
{#if panel.isVisible() && panel.position === 'right'}
|
|
427
491
|
<div class="h-full relative pointer-events-auto">
|
|
428
|
-
<panel.component
|
|
492
|
+
<panel.component
|
|
493
|
+
{...panel.props ?? {}}
|
|
494
|
+
locale={language.current}
|
|
495
|
+
/>
|
|
429
496
|
</div>
|
|
430
497
|
{/if}
|
|
431
498
|
{/each}
|
|
@@ -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-DZEgXrJ8.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';
|