triiiceratops 0.8.1 → 0.9.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 (94) hide show
  1. package/dist/chunks/TriiiceratopsViewer-BGtsfUPF.js +10298 -0
  2. package/dist/chunks/openseadragon-BTypULhm.js +12427 -0
  3. package/dist/components/AnnotationOverlay.svelte +288 -0
  4. package/dist/components/AnnotationOverlay.svelte.d.ts +3 -0
  5. package/dist/components/CanvasNavigation.svelte +32 -0
  6. package/dist/components/CanvasNavigation.svelte.d.ts +11 -0
  7. package/dist/components/DemoHeader.svelte +703 -0
  8. package/dist/components/DemoHeader.svelte.d.ts +9 -0
  9. package/dist/components/FloatingMenu.svelte +208 -0
  10. package/dist/components/FloatingMenu.svelte.d.ts +3 -0
  11. package/dist/components/LeftFab.svelte +69 -0
  12. package/dist/components/LeftFab.svelte.d.ts +3 -0
  13. package/dist/components/MetadataDialog.svelte +151 -0
  14. package/dist/components/MetadataDialog.svelte.d.ts +3 -0
  15. package/dist/components/OSDViewer.svelte +260 -0
  16. package/dist/components/OSDViewer.svelte.d.ts +8 -0
  17. package/dist/components/SearchPanel.svelte +150 -0
  18. package/dist/components/SearchPanel.svelte.d.ts +3 -0
  19. package/dist/components/ThemeToggle.svelte +118 -0
  20. package/dist/components/ThemeToggle.svelte.d.ts +3 -0
  21. package/dist/components/ThumbnailGallery.svelte +601 -0
  22. package/dist/components/ThumbnailGallery.svelte.d.ts +36 -0
  23. package/dist/components/TriiiceratopsViewer.svelte +434 -0
  24. package/dist/components/TriiiceratopsViewer.svelte.d.ts +20 -0
  25. package/dist/components/TriiiceratopsViewerElement.svelte +139 -0
  26. package/dist/components/TriiiceratopsViewerElement.svelte.d.ts +27 -0
  27. package/dist/components/TriiiceratopsViewerElementImage.svelte +143 -0
  28. package/dist/components/TriiiceratopsViewerElementImage.svelte.d.ts +27 -0
  29. package/dist/custom-element-image.d.ts +1 -0
  30. package/dist/custom-element-image.js +2 -0
  31. package/dist/custom-element.d.ts +1 -0
  32. package/dist/custom-element.js +3 -0
  33. package/dist/{src/lib/index.d.ts → index.d.ts} +1 -0
  34. package/dist/index.js +10 -4480
  35. package/dist/plugins/image-manipulation/ImageManipulationPanel.svelte +134 -0
  36. package/dist/plugins/image-manipulation/ImageManipulationPanel.svelte.d.ts +10 -0
  37. package/dist/{src/lib/plugins → plugins}/image-manipulation/ImageManipulationPlugin.svelte.d.ts +2 -2
  38. package/dist/plugins/image-manipulation/ImageManipulationPlugin.svelte.js +122 -0
  39. package/dist/{src/lib/plugins → plugins}/image-manipulation/filters.d.ts +1 -1
  40. package/dist/plugins/image-manipulation/filters.js +48 -0
  41. package/dist/plugins/image-manipulation/index.js +2 -0
  42. package/dist/plugins/image-manipulation/types.js +7 -0
  43. package/dist/state/i18n.svelte.d.ts +4 -0
  44. package/dist/state/i18n.svelte.js +18 -0
  45. package/dist/state/manifests.svelte.js +210 -0
  46. package/dist/state/manifests.test.d.ts +1 -0
  47. package/dist/state/manifests.test.js +242 -0
  48. package/dist/{src/lib/state → state}/viewer.svelte.d.ts +4 -4
  49. package/dist/state/viewer.svelte.js +693 -0
  50. package/dist/theme/colorUtils.js +196 -0
  51. package/dist/theme/colorUtils.test.d.ts +1 -0
  52. package/dist/theme/colorUtils.test.js +90 -0
  53. package/dist/theme/index.js +52 -0
  54. package/dist/{src/lib/theme → theme}/themeManager.d.ts +4 -1
  55. package/dist/theme/themeManager.js +177 -0
  56. package/dist/theme/types.js +40 -0
  57. package/dist/triiiceratops-bundle.js +4676 -0
  58. package/dist/triiiceratops-element-image.js +1 -1
  59. package/dist/triiiceratops-element.js +1 -1
  60. package/dist/types/config.js +1 -0
  61. package/dist/{src/lib/types → types}/plugin.d.ts +3 -3
  62. package/dist/types/plugin.js +36 -0
  63. package/dist/utils/annotationAdapter.js +354 -0
  64. package/dist/utils/annotationAdapter.test.d.ts +1 -0
  65. package/dist/utils/annotationAdapter.test.js +91 -0
  66. package/package.json +6 -5
  67. package/dist/chunks/TriiiceratopsViewer-CyamQrMe.js +0 -22698
  68. package/dist/plugin-De14WKQl.js +0 -546
  69. package/dist/plugins/image-manipulation.js +0 -454
  70. package/dist/src/lib/components/AnnotationOverlay.svelte.d.ts +0 -1
  71. package/dist/src/lib/components/CanvasNavigation.svelte.d.ts +0 -1
  72. package/dist/src/lib/components/FloatingMenu.svelte.d.ts +0 -1
  73. package/dist/src/lib/components/LeftFab.svelte.d.ts +0 -1
  74. package/dist/src/lib/components/MetadataDialog.svelte.d.ts +0 -1
  75. package/dist/src/lib/components/OSDViewer.svelte.d.ts +0 -1
  76. package/dist/src/lib/components/SearchPanel.svelte.d.ts +0 -1
  77. package/dist/src/lib/components/ThumbnailGallery.svelte.d.ts +0 -1
  78. package/dist/src/lib/components/TriiiceratopsViewer.svelte.d.ts +0 -1
  79. package/dist/src/lib/custom-element-image.d.ts +0 -0
  80. package/dist/src/lib/custom-element.d.ts +0 -0
  81. package/dist/src/lib/paraglide/messages/de.d.ts +0 -96
  82. package/dist/src/lib/paraglide/messages/en.d.ts +0 -96
  83. package/dist/src/lib/paraglide/messages.d.ts +0 -272
  84. package/dist/src/lib/paraglide/runtime.d.ts +0 -52
  85. package/dist/src/lib/plugins/image-manipulation/ImageManipulationPanel.svelte.d.ts +0 -1
  86. package/dist/src/lib/state/i18n.svelte.d.ts +0 -5
  87. /package/dist/{src/lib/plugins → plugins}/image-manipulation/index.d.ts +0 -0
  88. /package/dist/{src/lib/plugins → plugins}/image-manipulation/types.d.ts +0 -0
  89. /package/dist/{src/lib/state → state}/manifests.svelte.d.ts +0 -0
  90. /package/dist/{src/lib/theme → theme}/colorUtils.d.ts +0 -0
  91. /package/dist/{src/lib/theme → theme}/index.d.ts +0 -0
  92. /package/dist/{src/lib/theme → theme}/types.d.ts +0 -0
  93. /package/dist/{src/lib/types → types}/config.d.ts +0 -0
  94. /package/dist/{src/lib/utils → utils}/annotationAdapter.d.ts +0 -0
@@ -0,0 +1,288 @@
1
+ <script lang="ts">
2
+ import { getContext } from 'svelte';
3
+ import CaretDown from 'phosphor-svelte/lib/CaretDown';
4
+ import Eye from 'phosphor-svelte/lib/Eye';
5
+ import EyeSlash from 'phosphor-svelte/lib/EyeSlash';
6
+ import { manifestsState } from '../state/manifests.svelte';
7
+ import { VIEWER_STATE_KEY, type ViewerState } from '../state/viewer.svelte';
8
+ import { m } from '../state/i18n.svelte';
9
+
10
+ const viewerState = getContext<ViewerState>(VIEWER_STATE_KEY);
11
+
12
+ let annotations = $derived.by(() => {
13
+ if (!viewerState.manifestId || !viewerState.canvasId) {
14
+ return [];
15
+ }
16
+ const manifestAnnotations = manifestsState.getAnnotations(
17
+ viewerState.manifestId,
18
+ viewerState.canvasId,
19
+ );
20
+ // Add search hits for current canvas
21
+ // These behave as ephemeral annotations
22
+ const searchAnnotations = viewerState.currentCanvasSearchAnnotations;
23
+
24
+ return [...manifestAnnotations, ...searchAnnotations];
25
+ });
26
+
27
+ // Helper to get ID from annotation object
28
+ function getAnnotationId(anno: any): string {
29
+ return (
30
+ anno.id ||
31
+ anno['@id'] ||
32
+ (typeof anno.getId === 'function' ? anno.getId() : '') ||
33
+ ''
34
+ );
35
+ }
36
+
37
+ // Effect to initialize visibility when annotations load
38
+ $effect(() => {
39
+ // When annotations array changes (e.g. canvas change)
40
+ if (annotations.length > 0) {
41
+ const shouldBeVisible =
42
+ viewerState.config.annotations?.visible ?? true;
43
+
44
+ if (shouldBeVisible) {
45
+ const newSet = new Set<string>();
46
+ annotations.forEach((a: any) => {
47
+ const id = getAnnotationId(a);
48
+ if (id) newSet.add(id);
49
+ });
50
+ viewerState.visibleAnnotationIds = newSet;
51
+ } else {
52
+ viewerState.visibleAnnotationIds = new Set();
53
+ }
54
+ } else {
55
+ viewerState.visibleAnnotationIds = new Set();
56
+ }
57
+ });
58
+
59
+ // Derived state for "All Visible" status
60
+ let isAllVisible = $derived.by(() => {
61
+ if (annotations.length === 0) return false;
62
+ return annotations.every((a: any) => {
63
+ const id = getAnnotationId(a);
64
+ return !id || viewerState.visibleAnnotationIds.has(id);
65
+ });
66
+ });
67
+
68
+ function toggleAnnotation(id: string) {
69
+ if (viewerState.visibleAnnotationIds.has(id)) {
70
+ viewerState.visibleAnnotationIds.delete(id);
71
+ } else {
72
+ viewerState.visibleAnnotationIds.add(id);
73
+ }
74
+ // Reassign to trigger reactivity
75
+ viewerState.visibleAnnotationIds = new Set(
76
+ viewerState.visibleAnnotationIds,
77
+ );
78
+ }
79
+
80
+ function toggleAllAnnotations() {
81
+ if (isAllVisible) {
82
+ // Hide all
83
+ viewerState.visibleAnnotationIds = new Set();
84
+ } else {
85
+ // Show all
86
+ const newSet = new Set<string>();
87
+ annotations.forEach((a: any) => {
88
+ const id = getAnnotationId(a);
89
+ if (id) newSet.add(id);
90
+ });
91
+ viewerState.visibleAnnotationIds = newSet;
92
+ }
93
+ }
94
+
95
+ let renderedAnnotations = $derived.by(() => {
96
+ if (!annotations.length) return [];
97
+
98
+ return annotations.map((anno: any) => {
99
+ let content = '';
100
+ let isHtml = false;
101
+
102
+ // Extract content (support IIIF v2 and v3)
103
+ if (typeof anno.getBody === 'function') {
104
+ const body = anno.getBody();
105
+ if (body && body.length) {
106
+ const getValue = (b: any) => {
107
+ const val = b.getValue ? b.getValue() : null;
108
+ if (val) return val;
109
+ return '';
110
+ };
111
+ content = body
112
+ .map((b: any) => getValue(b))
113
+ .filter(Boolean)
114
+ .join(' ');
115
+ isHtml = body.some((b: any) => {
116
+ const fmt = b.getFormat ? b.getFormat() : '';
117
+ return (
118
+ fmt === 'text/html' || fmt === 'application/html'
119
+ );
120
+ });
121
+ }
122
+ if (!content && typeof anno.getLabel === 'function') {
123
+ const label = anno.getLabel();
124
+ if (label) content = label;
125
+ }
126
+ } else {
127
+ // Raw JSON Parsing (Fallback)
128
+ const getText = (r: any) => {
129
+ if (!r) return '';
130
+ return r.chars || r.value || r['cnt:chars'] || '';
131
+ };
132
+ const isHtmlFormat = (r: any) => {
133
+ if (!r) return false;
134
+ return r.format === 'text/html' || r.type === 'TextualBody';
135
+ };
136
+ if (anno.resource) {
137
+ if (Array.isArray(anno.resource)) {
138
+ content = anno.resource
139
+ .map((r: any) => getText(r))
140
+ .join(' ');
141
+ if (anno.resource.some((r: any) => isHtmlFormat(r)))
142
+ isHtml = true;
143
+ } else {
144
+ content = getText(anno.resource);
145
+ if (isHtmlFormat(anno.resource)) isHtml = true;
146
+ }
147
+ } else if (anno.body) {
148
+ if (Array.isArray(anno.body)) {
149
+ content = anno.body
150
+ .map((b: any) => getText(b))
151
+ .join(' ');
152
+ if (anno.body.some((b: any) => isHtmlFormat(b)))
153
+ isHtml = true;
154
+ } else {
155
+ content = getText(anno.body);
156
+ if (isHtmlFormat(anno.body)) isHtml = true;
157
+ }
158
+ }
159
+ if (!content) {
160
+ const fallback = anno.label || anno.name || anno.title;
161
+ if (fallback)
162
+ content = Array.isArray(fallback)
163
+ ? fallback.join(' ')
164
+ : fallback;
165
+ }
166
+ }
167
+
168
+ return {
169
+ id: getAnnotationId(anno),
170
+ content,
171
+ isHtml,
172
+ label:
173
+ (typeof anno.getLabel === 'function'
174
+ ? anno.getLabel()
175
+ : anno.label) || '',
176
+ };
177
+ });
178
+ });
179
+ </script>
180
+
181
+ <!-- Unified Annotation Toolbar -->
182
+ {#if viewerState.showAnnotations}
183
+ <div
184
+ class="absolute top-4 right-4 z-40 pointer-events-auto transition-all duration-300"
185
+ >
186
+ <!-- z-index increased for Leaflet (z-400 is map) -->
187
+ <details class="group relative">
188
+ <summary
189
+ class="flex items-center gap-2 bg-base-200/90 backdrop-blur shadow-lg rounded-full px-4 py-2 cursor-pointer list-none hover:bg-base-200 transition-all select-none border border-base-300 pointer-events-auto"
190
+ >
191
+ <!-- Toggle Button -->
192
+ <button
193
+ class="btn btn-xs btn-circle btn-ghost"
194
+ onclick={(e) => {
195
+ e.preventDefault();
196
+ toggleAllAnnotations();
197
+ }}
198
+ title={isAllVisible
199
+ ? m.hide_all_annotations()
200
+ : m.show_all_annotations()}
201
+ >
202
+ {#if isAllVisible}
203
+ <Eye size={16} weight="bold" />
204
+ {:else}
205
+ <EyeSlash size={16} weight="bold" />
206
+ {/if}
207
+ </button>
208
+
209
+ <!-- Badge Text -->
210
+ <span class="text-sm font-medium">
211
+ {m.annotations_count({ count: annotations.length })}
212
+ <span class="opacity-50 text-xs font-normal ml-1">
213
+ {m.visible_count({
214
+ count: viewerState.visibleAnnotationIds.size,
215
+ })}
216
+ </span>
217
+ </span>
218
+
219
+ <CaretDown
220
+ size={16}
221
+ weight="bold"
222
+ class="group-open:rotate-180 transition-transform opacity-80"
223
+ />
224
+ </summary>
225
+
226
+ <!-- Expanded List -->
227
+ <div
228
+ class="absolute right-0 mt-2 w-96 bg-base-200/95 backdrop-blur shadow-xl rounded-box p-0 max-h-[60vh] overflow-y-auto border border-base-300 flex flex-col divide-y divide-base-300"
229
+ >
230
+ {#each renderedAnnotations as anno, i}
231
+ {@const isVisible = viewerState.visibleAnnotationIds.has(
232
+ anno.id,
233
+ )}
234
+ <!-- List Item Row: Click toggles visibility -->
235
+ <button
236
+ class="w-full text-left p-3 hover:bg-base-300 transition-colors cursor-pointer flex gap-3 group/item items-start focus:outline-none focus:bg-base-300"
237
+ onclick={(e) => {
238
+ e.preventDefault();
239
+ toggleAnnotation(anno.id);
240
+ }}
241
+ >
242
+ <!-- Visual Toggle Indicator (formerly a button) -->
243
+ <div
244
+ class="btn btn-xs btn-circle btn-ghost mt-0.5 shrink-0 pointer-events-none"
245
+ >
246
+ {#if isVisible}
247
+ <Eye size={16} weight="bold" />
248
+ {:else}
249
+ <EyeSlash size={16} weight="bold" />
250
+ {/if}
251
+ </div>
252
+
253
+ <div class="flex-1 min-w-0">
254
+ <div class="flex items-start justify-between">
255
+ <span class="font-bold text-sm text-primary"
256
+ >#{i + 1}</span
257
+ >
258
+ <!-- Only show label separately if it's different from the content being displayed -->
259
+ {#if anno.label && anno.label !== anno.content}
260
+ <span
261
+ class="text-xs opacity-50 truncate max-w-[150px]"
262
+ >{anno.label}</span
263
+ >
264
+ {/if}
265
+ </div>
266
+ <div
267
+ class="text-sm prose prose-sm max-w-none prose-p:my-0 prose-a:text-blue-500 wrap-break-word text-left {isVisible
268
+ ? ''
269
+ : 'opacity-50'}"
270
+ >
271
+ <!-- eslint-disable-next-line svelte/no-at-html-tags -->
272
+ {#if anno.isHtml}
273
+ {@html anno.content}
274
+ {:else}
275
+ {anno.content || '(No content)'}
276
+ {/if}
277
+ </div>
278
+ </div>
279
+ </button>
280
+ {:else}
281
+ <div class="p-4 text-center opacity-50 text-sm">
282
+ No annotations available.
283
+ </div>
284
+ {/each}
285
+ </div>
286
+ </details>
287
+ </div>
288
+ {/if}
@@ -0,0 +1,3 @@
1
+ declare const AnnotationOverlay: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type AnnotationOverlay = ReturnType<typeof AnnotationOverlay>;
3
+ export default AnnotationOverlay;
@@ -0,0 +1,32 @@
1
+ <script>
2
+ import CaretLeft from 'phosphor-svelte/lib/CaretLeft';
3
+ import CaretRight from 'phosphor-svelte/lib/CaretRight';
4
+ import { m } from '../state/i18n.svelte';
5
+ let { viewerState } = $props();
6
+ </script>
7
+
8
+ <div
9
+ class="select-none absolute left-1/2 -translate-x-1/2 bg-base-200/90 backdrop-blur rounded-full shadow-lg flex items-center gap-4 z-10 border border-base-300 transition-all duration-200 bottom-4"
10
+ >
11
+ <button
12
+ class="btn btn-circle btn-sm btn-ghost"
13
+ disabled={!viewerState.hasPrevious}
14
+ onclick={() => viewerState.previousCanvas()}
15
+ aria-label={m.previous_canvas()}
16
+ >
17
+ <CaretLeft size={20} weight="bold" />
18
+ </button>
19
+
20
+ <span class="text-sm font-mono tabular-nums text-nowrap">
21
+ {viewerState.currentCanvasIndex + 1} / {viewerState.canvases.length}
22
+ </span>
23
+
24
+ <button
25
+ class="btn btn-circle btn-sm btn-ghost"
26
+ disabled={!viewerState.hasNext}
27
+ onclick={() => viewerState.nextCanvas()}
28
+ aria-label={m.next_canvas()}
29
+ >
30
+ <CaretRight size={20} weight="bold" />
31
+ </button>
32
+ </div>
@@ -0,0 +1,11 @@
1
+ export default CanvasNavigation;
2
+ type CanvasNavigation = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<$$ComponentProps>): void;
5
+ };
6
+ declare const CanvasNavigation: import("svelte").Component<{
7
+ viewerState: any;
8
+ }, {}, "">;
9
+ type $$ComponentProps = {
10
+ viewerState: any;
11
+ };