@manifest-editor/creators 1.0.2

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/index.cjs ADDED
@@ -0,0 +1,2082 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
31
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
+
33
+ // src/ContentResource/IIIFBrowserCreator/iiif-browser-form.lazy.tsx
34
+ var iiif_browser_form_lazy_exports = {};
35
+ __export(iiif_browser_form_lazy_exports, {
36
+ default: () => IIIFBrowserCreatorForm
37
+ });
38
+ function IIIFBrowserCreatorForm(props) {
39
+ const vault = (0, import_shell3.usePreviewVault)();
40
+ const { addHistory, clearHistory } = (0, import_shell3.usePreviewHistory)();
41
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_shell3.PreviewVaultBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
42
+ import_iiif_browser.IIIFExplorer,
43
+ {
44
+ window: false,
45
+ hideHeader: true,
46
+ outputTypes: ["Canvas", "CanvasList", "CanvasRegion", "ImageService", "ImageServiceRegion"],
47
+ vault,
48
+ output: { type: "content-state" },
49
+ homepageCollection: import_shell3.HOMEPAGE_COLLECTION,
50
+ clearHomepageCollection: clearHistory,
51
+ onHistory: addHistory,
52
+ height: 500,
53
+ outputTargets: [
54
+ {
55
+ type: "callback",
56
+ label: "Select",
57
+ cb: (resource) => props.runCreate({ output: resource })
58
+ }
59
+ ],
60
+ allowRemoveEntry: true
61
+ }
62
+ ) });
63
+ }
64
+ var import_iiif_browser, import_shell3, import_jsx_runtime23;
65
+ var init_iiif_browser_form_lazy = __esm({
66
+ "src/ContentResource/IIIFBrowserCreator/iiif-browser-form.lazy.tsx"() {
67
+ "use strict";
68
+ import_iiif_browser = require("@manifest-editor/iiif-browser");
69
+ import_shell3 = require("@manifest-editor/shell");
70
+ import_jsx_runtime23 = require("react/jsx-runtime");
71
+ }
72
+ });
73
+
74
+ // src/Manifest/ManifestBrowserCreator/manifest-browser-form.lazy.tsx
75
+ var manifest_browser_form_lazy_exports = {};
76
+ __export(manifest_browser_form_lazy_exports, {
77
+ default: () => ManifestBrowserCreatorForm
78
+ });
79
+ function ManifestBrowserCreatorForm(props) {
80
+ const vault = (0, import_shell4.usePreviewVault)();
81
+ const { addHistory, clearHistory } = (0, import_shell4.usePreviewHistory)();
82
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_jsx_runtime36.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_shell4.PreviewVaultBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
83
+ import_iiif_browser3.IIIFExplorer,
84
+ {
85
+ window: false,
86
+ hideHeader: true,
87
+ outputTypes: ["Manifest", "Collection"],
88
+ vault,
89
+ output: { type: "content-state" },
90
+ homepageCollection: import_shell4.HOMEPAGE_COLLECTION,
91
+ clearHomepageCollection: clearHistory,
92
+ onHistory: addHistory,
93
+ outputTargets: [
94
+ {
95
+ type: "callback",
96
+ label: "Select",
97
+ cb: (resource) => props.runCreate({ output: resource })
98
+ }
99
+ ],
100
+ allowRemoveEntry: true
101
+ }
102
+ ) }) });
103
+ }
104
+ var import_iiif_browser3, import_shell4, import_jsx_runtime36;
105
+ var init_manifest_browser_form_lazy = __esm({
106
+ "src/Manifest/ManifestBrowserCreator/manifest-browser-form.lazy.tsx"() {
107
+ "use strict";
108
+ import_iiif_browser3 = require("@manifest-editor/iiif-browser");
109
+ import_shell4 = require("@manifest-editor/shell");
110
+ import_jsx_runtime36 = require("react/jsx-runtime");
111
+ }
112
+ });
113
+
114
+ // src/index.ts
115
+ var src_exports = {};
116
+ __export(src_exports, {
117
+ allCreators: () => allCreators,
118
+ audioAnnotation: () => audioAnnotation,
119
+ emptyAnnotationPage: () => emptyAnnotationPage,
120
+ emptyCanvas: () => emptyCanvas,
121
+ htmlAnnotation: () => htmlAnnotation,
122
+ htmlBodyCreator: () => htmlBodyCreator,
123
+ iiifBrowserCreator: () => iiifBrowserCreator,
124
+ imageServiceAnnotation: () => imageServiceAnnotation,
125
+ imageServiceCreator: () => imageServiceCreator,
126
+ imageUrlAnnotation: () => imageUrlAnnotation,
127
+ imageUrlCreator: () => imageUrlCreator,
128
+ internalCanvas: () => internalCanvas,
129
+ manifestBrowserCreator: () => manifestBrowserCreator,
130
+ noBodyAnnotation: () => noBodyAnnotation,
131
+ plaintextCreator: () => plaintextCreator,
132
+ videoAnnotation: () => videoAnnotation,
133
+ webPageCreator: () => webPageCreator,
134
+ youTubeBodyCreator: () => youTubeBodyCreator
135
+ });
136
+ module.exports = __toCommonJS(src_exports);
137
+
138
+ // src/Canvas/EmptyCanvas/index.tsx
139
+ var import_components = require("@manifest-editor/components");
140
+ var import_jsx_runtime = require("react/jsx-runtime");
141
+ var emptyCanvas = {
142
+ id: "@manifest-editor/empty-canvas",
143
+ create: createEmptyCanvas,
144
+ label: "Empty canvas",
145
+ summary: "No content",
146
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.EmptyCanvasIcon, {}),
147
+ resourceType: "Canvas",
148
+ resourceFields: ["id", "type", "label", "height", "width", "items"],
149
+ supports: {
150
+ parentTypes: ["Manifest"],
151
+ parentFields: ["items"]
152
+ }
153
+ };
154
+ async function createEmptyCanvas(data, ctx) {
155
+ const canvasId = ctx.generateId("canvas");
156
+ const page = ctx.embed({
157
+ id: ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" }),
158
+ type: "AnnotationPage",
159
+ items: []
160
+ });
161
+ return {
162
+ id: canvasId,
163
+ type: "Canvas",
164
+ label: data.label || { en: [""] },
165
+ height: data.height || 1e3,
166
+ width: data.width || 1e3,
167
+ items: [page]
168
+ };
169
+ }
170
+
171
+ // ../ui/icons/TextFormatIcon.tsx
172
+ var import_jsx_runtime2 = require("react/jsx-runtime");
173
+ var TextFormatIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", height: "1em", width: "1em", ...props, children: [
174
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
175
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M5 17v2h14v-2H5zm4.5-4.2h5l.9 2.2h2.1L12.75 4h-1.5L6.5 15h2.1l.9-2.2zM12 5.98 13.87 11h-3.74L12 5.98z" })
176
+ ] });
177
+
178
+ // src/ContentResource/PlaintextCreator/create-plaintext.tsx
179
+ var import_editors = require("@manifest-editor/editors");
180
+
181
+ // ../ui/atoms/Button.tsx
182
+ var import_styled_components = __toESM(require("styled-components"), 1);
183
+ var ButtonReset = import_styled_components.default.button`
184
+ border: none;
185
+ outline: none;
186
+ background-color: transparent;
187
+ margin: 0;
188
+ padding: 0;
189
+ font-size: inherit;
190
+ color: inherit;
191
+ cursor: pointer;
192
+ &:hover {
193
+ color: inherit;
194
+ }
195
+ `;
196
+ var Button = import_styled_components.default.button`
197
+ padding: 0.5rem 1rem;
198
+ color: ${(props) => props.theme.color.main || "none"};
199
+ background-color: ${(props) => props.theme.color.white || "white"};
200
+ border-radius: inherit;
201
+ border: none;
202
+ cursor: pointer;
203
+ display: flex;
204
+ align-items: center;
205
+ font-size: 0.85em;
206
+ :disabled {
207
+ opacity: 0.65;
208
+ cursor: not-allowed;
209
+ }
210
+
211
+ &:hover {
212
+ background: #eee;
213
+ }
214
+ `;
215
+ var SmallButton = (0, import_styled_components.default)(Button)`
216
+ padding: 0.25em ${(props) => props.theme.padding.xs || "0.4em"};
217
+ height: unset;
218
+ background: none;
219
+ `;
220
+ var SecondaryButton = (0, import_styled_components.default)(Button)`
221
+ {
222
+ padding: 0 ${(props) => props.theme.padding.medium || "1rem"};
223
+ color: ${(props) => props.theme.color.main || "#B84C74;"};
224
+ background-color: ${(props) => props.theme.color.white || "white"};
225
+ border: 1px solid ${(props) => props.theme.color.main || "#B84C74;"};
226
+ border-radius: 0.25rem;
227
+ cursor: pointer;
228
+ height: 2rem;
229
+ display: flex;
230
+ align-items: center;
231
+ white-space: nowrap;
232
+ font-size: 0.75rem;
233
+
234
+ :disabled {
235
+ opacity: 0.65;
236
+ cursor: not-allowed;
237
+ }
238
+ }
239
+ `;
240
+ var CalltoButton = (0, import_styled_components.default)(Button)`
241
+ padding: 0 ${(props) => props.theme.padding.medium || "1rem"};
242
+ color: ${(props) => props.theme.color.white || "white"};
243
+ background-color: ${(props) => props.theme.color.main || "#B84C74;"};
244
+ border: 1px solid #eee;
245
+ border-radius: 0.25rem;
246
+ cursor: pointer;
247
+ justify-content: center;
248
+ display: flex;
249
+ align-items: center;
250
+ &:hover {
251
+ background-color: ${(props) => props.theme.color.mainHover || "#B84C74;"};
252
+ }
253
+ `;
254
+ var ButtonGroup = import_styled_components.default.div`
255
+ display: flex;
256
+ flex-direction: row;
257
+ flex-wrap: wrap;
258
+ align-items: flex-start;
259
+ justify-content: ${(props) => props.$right ? "flex-end" : "flex-start"};
260
+ `;
261
+
262
+ // ../ui/atoms/PaddedSidebarContainer.tsx
263
+ var import_styled_components2 = __toESM(require("styled-components"), 1);
264
+ var PaddedSidebarContainer = import_styled_components2.default.div`
265
+ padding: 0 0.7em;
266
+ margin: 0.7em 0;
267
+ flex: 1;
268
+ overflow: visible;
269
+ `;
270
+
271
+ // src/ContentResource/PlaintextCreator/create-plaintext.tsx
272
+ var import_react = require("react");
273
+ var import_jsx_runtime3 = require("react/jsx-runtime");
274
+ async function createPlaintext(data, ctx) {
275
+ return ctx.embed({
276
+ id: data.url,
277
+ type: "Text",
278
+ label: data.label,
279
+ format: "text/plain"
280
+ });
281
+ }
282
+ function CreatePlaintextForm(props) {
283
+ const [label, setLabel] = (0, import_react.useState)({ en: ["View as text"] });
284
+ const onSubmit = (e) => {
285
+ e.preventDefault();
286
+ const data = new FormData(e.target);
287
+ const formData = Object.fromEntries(data.entries());
288
+ if (formData.url) {
289
+ props.runCreate({ url: formData.url, label });
290
+ }
291
+ };
292
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { onSubmit, children: [
293
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
294
+ import_editors.LanguageFieldEditor,
295
+ {
296
+ focusId: "label",
297
+ label: "Label",
298
+ fields: label,
299
+ onSave: (e) => setLabel(e.toInternationalString())
300
+ }
301
+ ),
302
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_editors.InputContainer, { $wide: true, children: [
303
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_editors.InputLabel, { htmlFor: "id", children: "Link to plaintext" }),
304
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_editors.Input, { id: "url", name: "url", defaultValue: "" })
305
+ ] }),
306
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Button, { type: "submit", children: "Create" })
307
+ ] }) });
308
+ }
309
+
310
+ // src/ContentResource/PlaintextCreator/index.tsx
311
+ var import_jsx_runtime4 = require("react/jsx-runtime");
312
+ var plaintextCreator = {
313
+ id: "@manifest-editor/plaintext-creator",
314
+ create: createPlaintext,
315
+ label: "Plaintext",
316
+ summary: "Add link to an plaintext",
317
+ icon: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TextFormatIcon, {}),
318
+ render(ctx) {
319
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CreatePlaintextForm, { ...ctx });
320
+ },
321
+ resourceType: "ContentResource",
322
+ resourceFields: ["label", "format"],
323
+ supports: {
324
+ parentFields: ["seeAlso", "rendering", "homepage"]
325
+ },
326
+ staticFields: {
327
+ format: "text/plain"
328
+ }
329
+ };
330
+
331
+ // src/ContentResource/WebPageCreator/create-web-page.tsx
332
+ var import_editors2 = require("@manifest-editor/editors");
333
+ var import_react2 = require("react");
334
+ var import_jsx_runtime5 = require("react/jsx-runtime");
335
+ async function createWebPage(data, ctx) {
336
+ return ctx.embed({
337
+ id: data.url,
338
+ type: "Text",
339
+ label: data.label,
340
+ format: "text/html"
341
+ });
342
+ }
343
+ function CreateWebPageForm(props) {
344
+ const [label, setLabel] = (0, import_react2.useState)({ en: [""] });
345
+ const onSubmit = (e) => {
346
+ e.preventDefault();
347
+ const data = new FormData(e.target);
348
+ const formData = Object.fromEntries(data.entries());
349
+ if (formData.url) {
350
+ props.runCreate({ url: formData.url, label });
351
+ }
352
+ };
353
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("form", { onSubmit, children: [
354
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
355
+ import_editors2.LanguageFieldEditor,
356
+ {
357
+ focusId: "label",
358
+ label: "Label",
359
+ fields: label,
360
+ onSave: (e) => setLabel(e.toInternationalString())
361
+ }
362
+ ),
363
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_editors2.InputContainer, { $wide: true, children: [
364
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_editors2.InputLabel, { htmlFor: "id", children: "Link" }),
365
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_editors2.Input, { id: "url", name: "url", defaultValue: "" })
366
+ ] }),
367
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Button, { type: "submit", children: "Create link" })
368
+ ] }) });
369
+ }
370
+
371
+ // ../ui/icons/LinkIcon.tsx
372
+ var import_jsx_runtime6 = require("react/jsx-runtime");
373
+ function LinkIcon() {
374
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", height: "24px", viewBox: "0 0 24 24", width: "24px", fill: "#000000", children: [
375
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
376
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z" })
377
+ ] });
378
+ }
379
+
380
+ // src/ContentResource/WebPageCreator/index.tsx
381
+ var import_jsx_runtime7 = require("react/jsx-runtime");
382
+ var webPageCreator = {
383
+ id: "@manifest-editor/web-page-creator",
384
+ create: createWebPage,
385
+ label: "Web page",
386
+ summary: "Add link to an external web page",
387
+ icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(LinkIcon, {}),
388
+ render(ctx) {
389
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CreateWebPageForm, { ...ctx });
390
+ },
391
+ resourceType: "ContentResource",
392
+ resourceFields: ["label", "format"],
393
+ supports: {
394
+ parentFields: ["seeAlso", "rendering", "homepage"]
395
+ }
396
+ };
397
+
398
+ // src/ContentResource/HTMLBodyCreator/create-html-body.tsx
399
+ var import_editors3 = require("@manifest-editor/editors");
400
+ var import_shell = require("@manifest-editor/shell");
401
+ var import_react3 = require("react");
402
+ var import_jsx_runtime8 = require("react/jsx-runtime");
403
+ async function createHtmlBody(data, ctx) {
404
+ return ctx.embed({
405
+ id: ctx.generateId(`html/${data.language}`),
406
+ language: data.language,
407
+ type: "TextualBody",
408
+ format: "text/html",
409
+ value: data.body || ""
410
+ });
411
+ }
412
+ function CreateHTMLBodyForm(props) {
413
+ const { i18n } = (0, import_shell.useConfig)();
414
+ const [body, setBodyValue] = (0, import_react3.useState)("<p></p>");
415
+ const [language, setLang] = (0, import_react3.useState)(i18n.defaultLanguage);
416
+ const onSubmit = () => {
417
+ props.runCreate({
418
+ language,
419
+ body
420
+ });
421
+ };
422
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(PaddedSidebarContainer, { children: [
423
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_editors3.InputContainer, { children: [
424
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_editors3.InputLabel, { children: "HTML Body" }),
425
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
426
+ import_editors3.RichTextLanguageField,
427
+ {
428
+ value: body,
429
+ language,
430
+ onUpdateLanguage: (lng) => setLang(lng),
431
+ languages: i18n.availableLanguages,
432
+ onUpdate: (e) => setBodyValue(e)
433
+ }
434
+ )
435
+ ] }),
436
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { onClick: () => onSubmit(), children: "Create" })
437
+ ] });
438
+ }
439
+
440
+ // src/ContentResource/HTMLBodyCreator/index.tsx
441
+ var import_jsx_runtime9 = require("react/jsx-runtime");
442
+ var htmlBodyCreator = {
443
+ id: "@manifest-editor/html-body-creator",
444
+ create: createHtmlBody,
445
+ label: "HTML Body",
446
+ summary: "Add HTML annotation body",
447
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TextFormatIcon, {}),
448
+ render(ctx) {
449
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CreateHTMLBodyForm, { ...ctx });
450
+ },
451
+ resourceType: "ContentResource",
452
+ resourceFields: ["id", "language", "type", "format", "value"],
453
+ supports: {
454
+ parentTypes: ["Annotation"],
455
+ parentFields: ["body"]
456
+ },
457
+ staticFields: {
458
+ type: "TextualBody",
459
+ format: "text/html"
460
+ }
461
+ };
462
+
463
+ // src/Annotation/HTMLAnnotation/create-html-annotation.tsx
464
+ var import_react4 = require("react");
465
+ var import_editors4 = require("@manifest-editor/editors");
466
+ var import_jsx_runtime10 = require("react/jsx-runtime");
467
+ async function createHtmlAnnotation(data, ctx) {
468
+ const annotation = {
469
+ id: ctx.generateId("annotation"),
470
+ type: "Annotation"
471
+ };
472
+ const targetType = ctx.options.targetType;
473
+ const languages = Object.keys(data.body);
474
+ const bodies = [];
475
+ for (const language of languages) {
476
+ const body = data.body[language].join("\n");
477
+ if (body) {
478
+ bodies.push(
479
+ await ctx.create(
480
+ "@manifest-editor/html-body-creator",
481
+ {
482
+ language,
483
+ body
484
+ },
485
+ { parent: { resource: annotation, property: "items" } }
486
+ )
487
+ );
488
+ }
489
+ }
490
+ if (targetType === "Annotation") {
491
+ return ctx.embed({
492
+ ...annotation,
493
+ motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
494
+ body: bodies,
495
+ target: ctx.getTarget()
496
+ });
497
+ }
498
+ if (targetType === "Canvas") {
499
+ const canvasId = ctx.generateId("canvas");
500
+ const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
501
+ const annotationResource = ctx.embed({
502
+ ...annotation,
503
+ motivation: "painting",
504
+ body: bodies,
505
+ target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
506
+ });
507
+ const page = ctx.embed({
508
+ id: pageId,
509
+ type: "AnnotationPage",
510
+ items: [annotationResource]
511
+ });
512
+ return ctx.embed({
513
+ id: canvasId,
514
+ type: "Canvas",
515
+ label: data.label || { en: ["Untitled HTML canvas"] },
516
+ height: data.height || 1e3,
517
+ width: data.width || 1e3,
518
+ items: [page]
519
+ });
520
+ }
521
+ }
522
+ function CreateHTMLAnnotation(props) {
523
+ const [body, setBody] = (0, import_react4.useState)({ en: [""] });
524
+ const onSubmit = () => {
525
+ props.runCreate({
526
+ body
527
+ });
528
+ };
529
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(PaddedSidebarContainer, { children: [
530
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_editors4.InputContainer, { children: [
531
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_editors4.InputLabel, { children: "HTML Body" }),
532
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
533
+ import_editors4.LanguageFieldEditor,
534
+ {
535
+ focusId: "html-content",
536
+ label: "HTML Content",
537
+ fields: body,
538
+ onSave: (e) => setBody(e.toInternationalString())
539
+ }
540
+ )
541
+ ] }),
542
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { onClick: () => onSubmit(), children: "Create" })
543
+ ] });
544
+ }
545
+
546
+ // src/Annotation/HTMLAnnotation/index.tsx
547
+ var import_components2 = require("@manifest-editor/components");
548
+ var import_jsx_runtime11 = require("react/jsx-runtime");
549
+ var htmlAnnotation = {
550
+ id: "@manifest-editor/html-annotation",
551
+ create: createHtmlAnnotation,
552
+ label: "HTML",
553
+ summary: "HTML annotation",
554
+ icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_components2.HTMLIcon, {}),
555
+ render(ctx) {
556
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CreateHTMLAnnotation, { ...ctx });
557
+ },
558
+ resourceType: "Annotation",
559
+ resourceFields: ["id", "type", "motivation", "body", "target"],
560
+ additionalTypes: ["Canvas"],
561
+ supports: {
562
+ initialData: true,
563
+ parentTypes: ["AnnotationPage", "Manifest"],
564
+ parentFields: ["items"]
565
+ },
566
+ staticFields: {
567
+ type: "Annotation"
568
+ }
569
+ };
570
+
571
+ // ../ui/icons/ThumbnailStripIcon.tsx
572
+ var import_jsx_runtime12 = require("react/jsx-runtime");
573
+ var ThumbnailStripIcon = () => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
574
+ "svg",
575
+ {
576
+ xmlns: "http://www.w3.org/2000/svg",
577
+ height: "24px",
578
+ viewBox: "0 0 24 24",
579
+ width: "24px",
580
+ fill: "#000000",
581
+ transform: "scale(-1, 1)",
582
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("g", { children: [
583
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("rect", { fill: "none", height: "24", width: "24" }),
584
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M16,20H2V4h14V20z M18,8h4V4h-4V8z M18,20h4v-4h-4V20z M18,14h4v-4h-4V14z" })
585
+ ] })
586
+ }
587
+ );
588
+
589
+ // src/AnnotationPage/EmptyAnnotationPage/index.tsx
590
+ var import_jsx_runtime13 = require("react/jsx-runtime");
591
+ var emptyAnnotationPage = {
592
+ id: "@manifest-editor/empty-annotation-page",
593
+ create: createEmptyAnnotationPage,
594
+ label: "Empty annotation page",
595
+ summary: "AnnotationPage with nothing",
596
+ icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ThumbnailStripIcon, {}),
597
+ resourceType: "AnnotationPage",
598
+ resourceFields: ["id", "type", "items"],
599
+ supports: {
600
+ parentTypes: ["Manifest", "Canvas", "Range"],
601
+ parentFieldMap: {
602
+ Manifest: ["annotations"],
603
+ Canvas: ["items", "annotations"],
604
+ Range: ["annotations"]
605
+ }
606
+ }
607
+ };
608
+ async function createEmptyAnnotationPage(data, ctx) {
609
+ return ctx.embed({
610
+ id: ctx.generateId("annotations"),
611
+ type: "AnnotationPage",
612
+ items: []
613
+ });
614
+ }
615
+
616
+ // src/ContentResource/YouTubeCreator/index.tsx
617
+ var import_components3 = require("@manifest-editor/components");
618
+
619
+ // src/ContentResource/YouTubeCreator/create-youtube-body.tsx
620
+ var import_editors5 = require("@manifest-editor/editors");
621
+ var import_jsx_runtime14 = require("react/jsx-runtime");
622
+ var ytRegex = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/|shorts\/)|(?:(?:watch)?\?vi?=|&vi?=))([^#&?]*).*/;
623
+ function getYouTubeId(url) {
624
+ const id = (url || "").match(ytRegex);
625
+ return id ? id[1] : null;
626
+ }
627
+ async function createYoutubeBody(data, ctx) {
628
+ const id = getYouTubeId(data.youtubeUrl);
629
+ const body = ctx.embed({
630
+ id: `https://www.youtube.com/watch?v=${id}`,
631
+ type: "Video",
632
+ service: [
633
+ {
634
+ profile: "http://digirati.com/objectifier",
635
+ params: {
636
+ data: `https://www.youtube.com/embed/${id}`
637
+ }
638
+ },
639
+ {
640
+ id: `https://www.youtube.com/watch?v=${id}`,
641
+ profile: "https://www.youtube.com"
642
+ }
643
+ ]
644
+ });
645
+ if (ctx.options.targetType === "Canvas") {
646
+ const canvasId = ctx.generateId("canvas");
647
+ const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
648
+ const annotation = await ctx.embed({
649
+ id: ctx.generateId("annotation", { id: pageId, type: "AnnotationPage" }),
650
+ type: "Annotation",
651
+ motivation: "painting",
652
+ body: [body],
653
+ target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
654
+ });
655
+ const page = ctx.embed({
656
+ id: pageId,
657
+ type: "AnnotationPage",
658
+ items: [annotation]
659
+ });
660
+ return ctx.embed({
661
+ id: canvasId,
662
+ type: "Canvas",
663
+ label: data.label || { en: ["Untitled YouTube canvas"] },
664
+ height: data.height || 1e3,
665
+ width: data.width || 1e3,
666
+ duration: data.duration || 1,
667
+ items: [page]
668
+ });
669
+ }
670
+ if (ctx.options.targetType === "Annotation" || ctx.options.targetType === "Canvas") {
671
+ return ctx.embed({
672
+ id: ctx.generateId("annotation"),
673
+ type: "Annotation",
674
+ motivation: "painting",
675
+ body: [body],
676
+ target: ctx.getTarget()
677
+ });
678
+ }
679
+ return body;
680
+ }
681
+ function YouTubeForm(props) {
682
+ const onSubmit = (e) => {
683
+ e.preventDefault();
684
+ const data = new FormData(e.target);
685
+ const formData = Object.fromEntries(data.entries());
686
+ if (formData.youtubeUrl) {
687
+ props.runCreate({ youtubeUrl: formData.youtubeUrl });
688
+ }
689
+ };
690
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("form", { onSubmit, children: [
691
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_editors5.InputContainer, { $wide: true, children: [
692
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_editors5.InputLabel, { htmlFor: "id", children: "Link to YouTube" }),
693
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_editors5.Input, { id: "youtubeUrl", name: "youtubeUrl", defaultValue: "" })
694
+ ] }),
695
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button, { type: "submit", children: "Create" })
696
+ ] }) });
697
+ }
698
+
699
+ // src/ContentResource/YouTubeCreator/index.tsx
700
+ var import_jsx_runtime15 = require("react/jsx-runtime");
701
+ var youTubeBodyCreator = {
702
+ id: "@manifest-editor/youtube",
703
+ create: createYoutubeBody,
704
+ label: "YouTube",
705
+ summary: "Embed YouTube",
706
+ icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_components3.YouTubeIcon, {}),
707
+ resourceType: "ContentResource",
708
+ additionalTypes: ["Canvas", "Annotation"],
709
+ resourceFields: ["id", "type", "service"],
710
+ render: (ctx) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(YouTubeForm, { ...ctx }),
711
+ supports: {
712
+ parentTypes: ["Annotation", "Manifest", "AnnotationPage"],
713
+ parentFieldMap: {
714
+ Annotation: ["body"],
715
+ Manifest: ["items"],
716
+ AnnotationPage: ["items"]
717
+ }
718
+ },
719
+ staticFields: {
720
+ type: "Video"
721
+ }
722
+ };
723
+
724
+ // src/ContentResource/ImageUrlCreator/create-image-url.tsx
725
+ var import_editors6 = require("@manifest-editor/editors");
726
+ var import_shell2 = require("@manifest-editor/shell");
727
+ var import_jsx_runtime16 = require("react/jsx-runtime");
728
+ async function createImageUrl(data, ctx) {
729
+ if (!data.height || !data.width) {
730
+ const dimensions = await (0, import_shell2.getImageDimensions)(data.url);
731
+ if (dimensions) {
732
+ data.height = dimensions.height;
733
+ data.width = dimensions.width;
734
+ }
735
+ }
736
+ return ctx.embed({
737
+ id: data.url,
738
+ type: "Image",
739
+ format: data.format || await (0, import_shell2.getFormat)(data.url),
740
+ height: data.height,
741
+ width: data.width,
742
+ service: data.service ? Array.isArray(data.service) ? data.service : [data.service] : void 0
743
+ });
744
+ }
745
+ function CreateImageUrlForm(props) {
746
+ const onSubmit = (e) => {
747
+ e.preventDefault();
748
+ const data = new FormData(e.target);
749
+ const formData = Object.fromEntries(data.entries());
750
+ if (formData.url) {
751
+ props.runCreate({ url: formData.url });
752
+ }
753
+ };
754
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("form", { onSubmit, children: [
755
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_editors6.InputContainer, { $wide: true, children: [
756
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_editors6.InputLabel, { htmlFor: "id", children: "Link to Image" }),
757
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_editors6.Input, { id: "url", name: "url", defaultValue: "" })
758
+ ] }),
759
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Button, { type: "submit", children: "Create" })
760
+ ] }) });
761
+ }
762
+
763
+ // src/ContentResource/ImageUrlCreator/index.tsx
764
+ var import_components4 = require("@manifest-editor/components");
765
+ var import_jsx_runtime17 = require("react/jsx-runtime");
766
+ var imageUrlCreator = {
767
+ id: "@manifest-editor/image-url-creator",
768
+ create: createImageUrl,
769
+ label: "Image",
770
+ summary: "Image from a URL",
771
+ icon: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_components4.AddImageIcon, {}),
772
+ render(ctx) {
773
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CreateImageUrlForm, { ...ctx });
774
+ },
775
+ resourceType: "ContentResource",
776
+ resourceFields: ["format"],
777
+ supports: {
778
+ parentFields: ["logo", "body", "thumbnail"]
779
+ },
780
+ staticFields: {
781
+ type: "Image"
782
+ }
783
+ };
784
+
785
+ // src/ContentResource/ImageServiceCreator/create-image-service.tsx
786
+ var import_image_3 = require("@iiif/parser/image-3");
787
+ var import_editors7 = require("@manifest-editor/editors");
788
+ var import_jsx_runtime18 = require("react/jsx-runtime");
789
+ async function createImageServer(data, ctx) {
790
+ const request = (0, import_image_3.createImageServiceRequest)(data.service);
791
+ const imageId = (0, import_image_3.imageServiceRequestToString)({
792
+ identifier: request.identifier,
793
+ server: request.server,
794
+ scheme: request.scheme,
795
+ type: "image",
796
+ size: {
797
+ max: !data.size?.width && !data.size?.height,
798
+ confined: false,
799
+ upscaled: false,
800
+ ...data.size || {}
801
+ },
802
+ format: "jpg",
803
+ // This isn't how it should be modelled, always full,
804
+ // region: data.selector ? data.selector : { full: true },
805
+ region: { full: true },
806
+ rotation: { angle: 0 },
807
+ quality: "default",
808
+ prefix: request.prefix,
809
+ originalPath: request.originalPath
810
+ });
811
+ const resource = ctx.embed({
812
+ id: imageId,
813
+ type: "Image",
814
+ format: data.format || "image/jpeg",
815
+ height: data.height || data.service.height,
816
+ width: data.width || data.service.width,
817
+ service: data.embedService === false ? void 0 : [data.service]
818
+ });
819
+ return resource;
820
+ }
821
+ function CreateImageServerForm(props) {
822
+ const onSubmit = (e) => {
823
+ e.preventDefault();
824
+ const data = new FormData(e.target);
825
+ const formData = Object.fromEntries(data.entries());
826
+ const url = formData.url;
827
+ if (url) {
828
+ const canon = (0, import_image_3.canonicalServiceUrl)(url);
829
+ fetch(canon).then((r) => r.json()).then((service) => {
830
+ if (service["@id"]) {
831
+ service.id = service["@id"];
832
+ }
833
+ if (service["@type"]) {
834
+ service.type = service["@type"];
835
+ }
836
+ props.runCreate({ url: formData.url, service });
837
+ });
838
+ }
839
+ };
840
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("form", { onSubmit, children: [
841
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_editors7.InputContainer, { $wide: true, children: [
842
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_editors7.InputLabel, { htmlFor: "id", children: "Link to image service" }),
843
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_editors7.Input, { id: "url", name: "url", defaultValue: "" })
844
+ ] }),
845
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Button, { type: "submit", children: "Create" })
846
+ ] }) });
847
+ }
848
+
849
+ // src/ContentResource/ImageServiceCreator/index.tsx
850
+ var import_jsx_runtime19 = require("react/jsx-runtime");
851
+ var imageServiceCreator = {
852
+ id: "@manifest-editor/image-service-creator",
853
+ create: createImageServer,
854
+ label: "Image Service",
855
+ summary: "Add an image from Image Service",
856
+ icon: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TextFormatIcon, {}),
857
+ render(ctx) {
858
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CreateImageServerForm, { ...ctx });
859
+ },
860
+ resourceType: "ContentResource",
861
+ resourceFields: ["id", "type", "height", "width", "format", "service"],
862
+ supports: {
863
+ parentFields: ["logo", "body", "thumbnail"]
864
+ },
865
+ staticFields: {
866
+ type: "Image"
867
+ }
868
+ };
869
+
870
+ // src/side-effects/reposition-multiple-images.ts
871
+ var import_image_32 = require("@iiif/parser/image-3");
872
+ var import_editor_api = require("@manifest-editor/editor-api");
873
+ var import_editors8 = require("@manifest-editor/editors");
874
+ var repositionMultipleImages = {
875
+ canvasInteraction: true,
876
+ spatial: true,
877
+ async run(result, { vault, options }) {
878
+ if (result && result.type === "Annotation" && options.targetType === "Annotation") {
879
+ const fullAnno = vault.get(result);
880
+ const target = fullAnno.target;
881
+ if (!(target && target.source?.type === "Canvas")) {
882
+ return;
883
+ }
884
+ const canvasRef = target.source;
885
+ const canvas = vault.get(canvasRef);
886
+ if (!canvas.items) {
887
+ return;
888
+ }
889
+ const annoPage = vault.get(canvas.items[0]);
890
+ if (!annoPage) {
891
+ return;
892
+ }
893
+ if (annoPage.items.length < 2) {
894
+ return;
895
+ }
896
+ const bodies = vault.get(fullAnno.body);
897
+ const body = bodies[0];
898
+ const selector = fullAnno.body[0]?.selector;
899
+ const serviceList = body.service || [];
900
+ const imageService = serviceList.find((s) => (0, import_image_32.isImageService)(s));
901
+ if (imageService) {
902
+ if (imageService.width && imageService.height) {
903
+ if (imageService.width !== body.width) {
904
+ vault.modifyEntityField({ id: body.id, type: "ContentResource" }, "width", imageService.width);
905
+ }
906
+ if (imageService.height !== body.height) {
907
+ vault.modifyEntityField({ id: body.id, type: "ContentResource" }, "height", imageService.height);
908
+ }
909
+ }
910
+ }
911
+ let width = imageService?.width || body.width;
912
+ let height = imageService?.height || body.height;
913
+ if (selector) {
914
+ if ((selector.type === "iiif:ImageApiSelector" || selector.type === "ImageApiSelector") && selector.region) {
915
+ const [x, y, width_, height_] = selector.region.split(",");
916
+ width = Number(width_) || width;
917
+ height = Number(height_) || height;
918
+ }
919
+ }
920
+ const editor = new import_editor_api.EditorInstance({ vault, reference: result });
921
+ const imagePosition = (0, import_editors8.centerRectangles)(
922
+ canvas,
923
+ {
924
+ width,
925
+ height
926
+ },
927
+ 0.6
928
+ );
929
+ editor.annotation.target.setPosition(imagePosition);
930
+ }
931
+ }
932
+ };
933
+
934
+ // src/side-effects/resize-resource-to-empty-canvas.ts
935
+ var import_editor_api2 = require("@manifest-editor/editor-api");
936
+ var resizeResourceToEmptyCanvas = {
937
+ canvasInteraction: true,
938
+ spatial: true,
939
+ async run(result, { vault, options }) {
940
+ if (result && result.type === "Annotation" && options.targetType === "Annotation") {
941
+ const fullAnno = vault.get(result);
942
+ const target = fullAnno.target;
943
+ if (!(target && target.source?.type === "Canvas")) {
944
+ return;
945
+ }
946
+ const canvasRef = target.source;
947
+ const canvas = vault.get(canvasRef);
948
+ if (!canvas.items) {
949
+ return;
950
+ }
951
+ const annoPage = vault.get(canvas.items[0]);
952
+ if (!annoPage) {
953
+ return;
954
+ }
955
+ if (annoPage.items.length > 1) {
956
+ return;
957
+ }
958
+ const bodies = vault.get(fullAnno.body);
959
+ if (bodies.length !== 1) {
960
+ return;
961
+ }
962
+ const body = bodies[0];
963
+ const selector = fullAnno.body[0]?.selector;
964
+ const service = (body.service || [])[0];
965
+ let width = service?.width || body.width;
966
+ let height = service?.height || body.height;
967
+ const duration = body.duration || service?.duration;
968
+ if (selector) {
969
+ if ((selector.type === "iiif:ImageApiSelector" || selector.type === "ImageApiSelector") && selector.region) {
970
+ const [x, y, width_, height_] = selector.region.split(",");
971
+ width = Number(width_) || width;
972
+ height = Number(height_) || height;
973
+ }
974
+ }
975
+ const editor = new import_editor_api2.EditorInstance({ vault, reference: canvasRef });
976
+ vault.batch(() => {
977
+ if (typeof width !== "undefined") {
978
+ editor.technical.width.set(width);
979
+ }
980
+ if (typeof height !== "undefined") {
981
+ editor.technical.height.set(height);
982
+ }
983
+ if (typeof duration !== "undefined") {
984
+ editor.technical.duration.set(duration);
985
+ }
986
+ });
987
+ }
988
+ }
989
+ };
990
+
991
+ // src/side-effects/resize-to-fit-service.ts
992
+ var import_iiif_image_api = require("@atlas-viewer/iiif-image-api");
993
+ var resizeToFitService = {
994
+ canvasInteraction: true,
995
+ spatial: true,
996
+ async run(result, { vault, options }) {
997
+ if (result && result.type === "Annotation" && options.targetType === "Annotation") {
998
+ const fullAnno = vault.get(result);
999
+ const target = fullAnno.target;
1000
+ if (!(target && target.source?.type === "Canvas")) {
1001
+ return;
1002
+ }
1003
+ const canvasRef = target.source;
1004
+ const canvas = vault.get(canvasRef);
1005
+ if (!canvas.items) {
1006
+ return;
1007
+ }
1008
+ const annoPage = vault.get(canvas.items[0]);
1009
+ if (!annoPage) {
1010
+ return;
1011
+ }
1012
+ const resourceBody = Array.isArray(fullAnno.body) ? fullAnno.body[0] : fullAnno.body;
1013
+ if (resourceBody.type === "SpecificResource" && resourceBody.selector) {
1014
+ return;
1015
+ }
1016
+ const bodies = vault.get(fullAnno.body);
1017
+ const body = bodies[0];
1018
+ const serviceList = body.service || [];
1019
+ const imageService = serviceList.find((s) => (0, import_iiif_image_api.isImageService)(s));
1020
+ if (imageService) {
1021
+ if (imageService.width && imageService.height) {
1022
+ if (imageService.width !== body.width) {
1023
+ vault.modifyEntityField({ id: body.id, type: "ContentResource" }, "width", imageService.width);
1024
+ }
1025
+ if (imageService.height !== body.height) {
1026
+ vault.modifyEntityField({ id: body.id, type: "ContentResource" }, "height", imageService.height);
1027
+ }
1028
+ }
1029
+ }
1030
+ }
1031
+ }
1032
+ };
1033
+
1034
+ // src/Annotation/ImageServiceAnnotation/create-service-annotation.tsx
1035
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1036
+ async function createImageServiceAnnotation(data, ctx) {
1037
+ const annotation = {
1038
+ id: ctx.generateId("annotation"),
1039
+ type: "Annotation"
1040
+ };
1041
+ const targetType = ctx.options.targetType;
1042
+ const resource = await ctx.create("@manifest-editor/image-service-creator", data, {
1043
+ parent: { resource: annotation, property: "body" }
1044
+ });
1045
+ if (targetType === "Annotation") {
1046
+ return {
1047
+ ...annotation,
1048
+ body: [resource],
1049
+ motivation: data.motivation || "painting",
1050
+ target: ctx.getTarget()
1051
+ };
1052
+ }
1053
+ if (targetType === "Canvas") {
1054
+ const canvasId = ctx.generateId("canvas");
1055
+ const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
1056
+ const annotationResource = ctx.embed({
1057
+ ...annotation,
1058
+ motivation: "painting",
1059
+ body: [resource],
1060
+ target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
1061
+ });
1062
+ const page = ctx.embed({
1063
+ id: pageId,
1064
+ type: "AnnotationPage",
1065
+ items: [annotationResource]
1066
+ });
1067
+ return ctx.embed({
1068
+ id: canvasId,
1069
+ type: "Canvas",
1070
+ label: data.label || { en: ["Untitled canvas"] },
1071
+ height: resource.resource.height || 1e3,
1072
+ width: resource.resource.width || 1e3,
1073
+ items: [page]
1074
+ });
1075
+ }
1076
+ }
1077
+ function CreateImageServiceAnnotationForm(props) {
1078
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CreateImageServerForm, { ...props });
1079
+ }
1080
+
1081
+ // src/Annotation/ImageServiceAnnotation/index.tsx
1082
+ var import_components5 = require("@manifest-editor/components");
1083
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1084
+ var imageServiceAnnotation = {
1085
+ id: "@manifest-editor/image-service-annotation",
1086
+ create: createImageServiceAnnotation,
1087
+ label: "IIIF Image",
1088
+ dependencies: ["@manifest-editor/image-service-creator"],
1089
+ summary: "IIIF Image service",
1090
+ icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_components5.IIIFLogo, { style: { padding: 10 } }),
1091
+ render(ctx) {
1092
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CreateImageServiceAnnotationForm, { ...ctx });
1093
+ },
1094
+ resourceType: "Annotation",
1095
+ resourceFields: ["id", "type", "motivation", "body", "target"],
1096
+ additionalTypes: ["Canvas"],
1097
+ supports: {
1098
+ parentTypes: ["AnnotationPage", "Manifest"],
1099
+ parentFields: ["items"]
1100
+ },
1101
+ sideEffects: [resizeToFitService, resizeResourceToEmptyCanvas, repositionMultipleImages],
1102
+ staticFields: {
1103
+ type: "Annotation"
1104
+ }
1105
+ };
1106
+
1107
+ // src/Annotation/NoBodyAnnotation/index.tsx
1108
+ var import_components6 = require("@manifest-editor/components");
1109
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1110
+ var noBodyAnnotation = {
1111
+ id: "@manifest-editor/no-body-annotation",
1112
+ create: createNoBodyAnnotation,
1113
+ label: "Annotation without body",
1114
+ summary: "Add an annotation that only has motivation and target",
1115
+ icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components6.EmptyCanvasIcon, {}),
1116
+ resourceType: "Annotation",
1117
+ resourceFields: ["id", "type", "motivation", "target"],
1118
+ supports: {
1119
+ initialData: true,
1120
+ parentTypes: ["AnnotationPage"],
1121
+ parentFields: ["items"],
1122
+ disallowPainting: true
1123
+ },
1124
+ sideEffects: [],
1125
+ staticFields: {
1126
+ type: "Annotation"
1127
+ }
1128
+ };
1129
+ function createNoBodyAnnotation(data, ctx) {
1130
+ return ctx.embed({
1131
+ id: ctx.generateId("annotation"),
1132
+ type: "Annotation",
1133
+ label: data?.label,
1134
+ motivation: data.motivation || ctx.options.initialData?.motivation || "highlighting",
1135
+ target: ctx.getTarget()
1136
+ });
1137
+ }
1138
+
1139
+ // src/ContentResource/IIIFBrowserCreator/iiif-browser-creator.tsx
1140
+ var import_helpers = require("@iiif/helpers");
1141
+ var import_react5 = require("react");
1142
+
1143
+ // ../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js
1144
+ var isProduction = false;
1145
+ var prefix = "Invariant failed";
1146
+ function invariant(condition, message) {
1147
+ if (condition) {
1148
+ return;
1149
+ }
1150
+ if (isProduction) {
1151
+ throw new Error(prefix);
1152
+ }
1153
+ var provided = typeof message === "function" ? message() : message;
1154
+ var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
1155
+ throw new Error(value);
1156
+ }
1157
+
1158
+ // src/ContentResource/IIIFBrowserCreator/iiif-browser-creator.tsx
1159
+ async function createFromIIIFBrowserOutput(data, ctx) {
1160
+ const targetType = ctx.options.targetType;
1161
+ if (Array.isArray(data.output)) {
1162
+ throw new Error("Multiple items not yet supported");
1163
+ }
1164
+ const contentState = (0, import_helpers.normaliseContentState)(
1165
+ typeof data.output === "string" ? (0, import_helpers.parseContentState)(data.output) : data.output
1166
+ );
1167
+ if (!contentState.target || contentState.target.length === 0) {
1168
+ throw new Error("No target found in content state");
1169
+ }
1170
+ const target = contentState.target[0];
1171
+ const type = target.source.type;
1172
+ const previewVault = ctx.getPreviewVault();
1173
+ if (targetType === "Canvas" || targetType === "Annotation") {
1174
+ if (type === "Canvas") {
1175
+ const canvasId = target.source.id;
1176
+ const manifestId = target.source.partOf?.find((t) => t.type === "Manifest");
1177
+ invariant(manifestId, "Could not load external resource without partOf");
1178
+ const manifest = await previewVault.loadManifest(manifestId);
1179
+ invariant(manifest, "Manifest not found");
1180
+ const canvasRef = manifest.items.find((item) => item.id === canvasId);
1181
+ invariant(canvasRef, "Canvas not found");
1182
+ const canvas = previewVault.get(canvasRef);
1183
+ if (targetType === "Canvas") {
1184
+ return ctx.embed(previewVault.toPresentation3(canvas));
1185
+ }
1186
+ const annotationPage = previewVault.get(canvas.items[0]);
1187
+ const annotation = previewVault.get(annotationPage.items[0]);
1188
+ if (targetType === "Annotation") {
1189
+ const fullAnnotation = previewVault.toPresentation3(annotation);
1190
+ if (fullAnnotation && fullAnnotation?.body?.service) {
1191
+ const width = fullAnnotation?.body.width;
1192
+ const height = fullAnnotation?.body.height;
1193
+ const service = Array.isArray(fullAnnotation?.body?.service) ? fullAnnotation?.body?.service[0] : fullAnnotation?.body?.service;
1194
+ if (!service.width || !service.height) {
1195
+ service.width = width;
1196
+ service.height = height;
1197
+ }
1198
+ }
1199
+ if (target.selector && target.selector.type === "BoxSelector") {
1200
+ const selector = {
1201
+ "@context": "http://iiif.io/api/annex/openannotation/context.json",
1202
+ type: "iiif:ImageApiSelector",
1203
+ region: [
1204
+ ~~target.selector.spatial.x,
1205
+ ~~target.selector.spatial.y,
1206
+ ~~target.selector.spatial.width,
1207
+ ~~target.selector.spatial.height
1208
+ ].join(",")
1209
+ };
1210
+ fullAnnotation.body = {
1211
+ id: ctx.generateId("SpecificResource", annotation),
1212
+ type: "SpecificResource",
1213
+ source: fullAnnotation.body,
1214
+ selector
1215
+ };
1216
+ return ctx.embed({
1217
+ ...fullAnnotation,
1218
+ target: ctx.getTarget()
1219
+ });
1220
+ }
1221
+ return ctx.embed({
1222
+ ...previewVault.toPresentation3(annotation),
1223
+ target: ctx.getTarget()
1224
+ });
1225
+ }
1226
+ }
1227
+ }
1228
+ throw new Error("Not yet supported.");
1229
+ }
1230
+ var IIIFBrowserCreatorForm2 = (0, import_react5.lazy)(() => Promise.resolve().then(() => (init_iiif_browser_form_lazy(), iiif_browser_form_lazy_exports)));
1231
+
1232
+ // src/ContentResource/IIIFBrowserCreator/index.tsx
1233
+ var import_components7 = require("@manifest-editor/components");
1234
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1235
+ var iiifBrowserCreator = {
1236
+ id: "@manifest-editor/iiif-browser-creator",
1237
+ create: createFromIIIFBrowserOutput,
1238
+ label: "IIIF Browser",
1239
+ summary: "Browse IIIF Resources",
1240
+ icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_components7.IIIFBrowserIcon, {}),
1241
+ render(ctx) {
1242
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(IIIFBrowserCreatorForm2, { ...ctx });
1243
+ },
1244
+ resourceType: "ContentResource",
1245
+ resourceFields: ["id", "language", "type", "format", "value"],
1246
+ additionalTypes: ["Annotation", "Canvas"],
1247
+ supports: {
1248
+ parentTypes: ["Annotation", "Manifest", "AnnotationPage"],
1249
+ parentFieldMap: {
1250
+ Annotation: ["body"],
1251
+ Manifest: ["items"],
1252
+ AnnotationPage: ["items"]
1253
+ }
1254
+ },
1255
+ sideEffects: [resizeToFitService, resizeResourceToEmptyCanvas, repositionMultipleImages],
1256
+ staticFields: {}
1257
+ };
1258
+
1259
+ // src/Canvas/InternalCanvas/index.tsx
1260
+ var import_react_iiif_vault = require("react-iiif-vault");
1261
+ var import_iiif_browser2 = require("@manifest-editor/iiif-browser");
1262
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1263
+ var internalCanvas = {
1264
+ id: "@manifest-editor/internal-canvas",
1265
+ create: createInternalCanvas,
1266
+ label: "Internal canvas link",
1267
+ summary: "Canvas from the same manifest",
1268
+ icon: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ThumbnailStripIcon, {}),
1269
+ resourceType: "Canvas",
1270
+ resourceFields: ["id", "type", "label"],
1271
+ supports: {
1272
+ parentTypes: ["Manifest"],
1273
+ parentFields: ["start"]
1274
+ },
1275
+ render: (ctx) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(InternalCanvas, { ...ctx })
1276
+ };
1277
+ function InternalCanvas(props) {
1278
+ const manifest = (0, import_react_iiif_vault.useManifest)();
1279
+ const vault = (0, import_react_iiif_vault.useVault)();
1280
+ invariant(manifest, "Manifest is not loaded");
1281
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1282
+ import_iiif_browser2.IIIFExplorer,
1283
+ {
1284
+ vault,
1285
+ entry: manifest,
1286
+ window: false,
1287
+ hideHeader: true,
1288
+ hideBack: true,
1289
+ output: { type: "url" },
1290
+ outputTargets: [
1291
+ {
1292
+ type: "callback",
1293
+ label: "Select canvas",
1294
+ cb: (url) => {
1295
+ props.runCreate({ id: url });
1296
+ }
1297
+ }
1298
+ ],
1299
+ outputTypes: ["Canvas"]
1300
+ }
1301
+ );
1302
+ }
1303
+ async function createInternalCanvas(data, ctx) {
1304
+ return ctx.embed({ id: data.id, type: "Canvas" });
1305
+ }
1306
+
1307
+ // src/Annotation/ImageUrlAnnotation/create-image-url-annotation.tsx
1308
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1309
+ async function createImageUrlAnnotation(data, ctx) {
1310
+ const annotation = {
1311
+ id: ctx.generateId("annotation"),
1312
+ type: "Annotation"
1313
+ };
1314
+ const targetType = ctx.options.targetType;
1315
+ const resource = await ctx.create("@manifest-editor/image-url-creator", data, {
1316
+ parent: { resource: annotation, property: "body" }
1317
+ });
1318
+ if (targetType === "Annotation") {
1319
+ return {
1320
+ ...annotation,
1321
+ body: [resource],
1322
+ motivation: data.motivation || "painting",
1323
+ target: ctx.getTarget()
1324
+ };
1325
+ }
1326
+ if (targetType === "Canvas") {
1327
+ const canvasId = ctx.generateId("canvas");
1328
+ const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
1329
+ const annotationResource = ctx.embed({
1330
+ ...annotation,
1331
+ motivation: "painting",
1332
+ body: [resource],
1333
+ target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
1334
+ });
1335
+ const page = ctx.embed({
1336
+ id: pageId,
1337
+ type: "AnnotationPage",
1338
+ items: [annotationResource]
1339
+ });
1340
+ return ctx.embed({
1341
+ id: canvasId,
1342
+ type: "Canvas",
1343
+ label: data.label || { en: ["Untitled canvas"] },
1344
+ height: resource.resource.height || 1e3,
1345
+ width: resource.resource.width || 1e3,
1346
+ items: [page]
1347
+ });
1348
+ }
1349
+ }
1350
+ function CreateImageUrlAnnotationForm(props) {
1351
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CreateImageUrlForm, { ...props });
1352
+ }
1353
+
1354
+ // src/Annotation/ImageUrlAnnotation/index.tsx
1355
+ var import_components8 = require("@manifest-editor/components");
1356
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1357
+ var imageUrlAnnotation = {
1358
+ id: "@manifest-editor/image-url-annotation",
1359
+ create: createImageUrlAnnotation,
1360
+ label: "Image",
1361
+ dependencies: ["@manifest-editor/image-url-creator"],
1362
+ summary: "Image from URL",
1363
+ icon: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_components8.AddImageIcon, {}),
1364
+ render(ctx) {
1365
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(CreateImageUrlAnnotationForm, { ...ctx });
1366
+ },
1367
+ resourceType: "Annotation",
1368
+ resourceFields: ["id", "type", "motivation", "body", "target"],
1369
+ additionalTypes: ["Canvas"],
1370
+ supports: {
1371
+ parentTypes: ["AnnotationPage", "Manifest"],
1372
+ parentFields: ["items"]
1373
+ },
1374
+ sideEffects: [resizeToFitService, resizeResourceToEmptyCanvas, repositionMultipleImages],
1375
+ staticFields: {
1376
+ type: "Annotation"
1377
+ }
1378
+ };
1379
+
1380
+ // src/Annotation/AudioAnnotation/create-audio-annotation.tsx
1381
+ var import_react7 = require("react");
1382
+
1383
+ // ../ui/atoms/callouts/ErrorMessage.tsx
1384
+ var import_styled_components3 = __toESM(require("styled-components"), 1);
1385
+ var ErrorMessage = import_styled_components3.default.div`
1386
+ border: 2px solid ${(props) => props.theme.color.danger || "red"};
1387
+ width: 100%;
1388
+ border-radius: 5px;
1389
+ padding: ${(props) => props.theme.padding.small || "0.5rem"}
1390
+ ${(props) => props.theme.padding.medium || "1rem"};
1391
+ line-height: 1.9em;
1392
+ display: flex;
1393
+ align-items: center;
1394
+ a {
1395
+ color: ${(props) => props.theme.color.white || "white"};
1396
+ }
1397
+ ${(props) => props.$small && import_styled_components3.css`
1398
+ font-size: 0.75em;
1399
+ white-space: nowrap;
1400
+ padding: ${props.theme.padding.xs || "0.25rem"} ${props.theme.padding.small || "0.5rem"};
1401
+ line-height: 1.6em;
1402
+ width: fit-content;
1403
+ `}
1404
+ `;
1405
+
1406
+ // ../ui/ui/MediaControls/MediaControls.tsx
1407
+ var import_react_iiif_vault2 = require("react-iiif-vault");
1408
+ var import_react6 = require("react");
1409
+
1410
+ // ../ui/ui/MediaControls/MediaControls.icons.tsx
1411
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1412
+ var PlayIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("svg", { ...props, viewBox: "4 4 16 16", xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", children: [
1413
+ props.title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("title", { children: props.title }) : null,
1414
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
1415
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { d: "M8 5v14l11-7z", fill: "currentColor" })
1416
+ ] });
1417
+ var PauseIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("svg", { ...props, viewBox: "4 4 16 16", xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", children: [
1418
+ props.title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("title", { children: props.title }) : null,
1419
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
1420
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { fill: "currentColor", d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" })
1421
+ ] });
1422
+ var VolumeUpIcon = ({ title, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "2 2 20 20", children: [
1423
+ title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("title", { children: title }) : null,
1424
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
1425
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1426
+ "path",
1427
+ {
1428
+ fill: "currentColor",
1429
+ d: "M3 9v6h4l5 5V4L7 9H3zm13.5 3A4.5 4.5 0 0 0 14 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"
1430
+ }
1431
+ )
1432
+ ] });
1433
+ var VolumeDownIcon = ({ title, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "2 2 20 20", children: [
1434
+ title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("title", { children: title }) : null,
1435
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
1436
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1437
+ "path",
1438
+ {
1439
+ fill: "currentColor",
1440
+ d: "M18.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM5 9v6h4l5 5V4L9 9H5z"
1441
+ }
1442
+ )
1443
+ ] });
1444
+ var VolumeOffIcon = ({ title, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "2 2 20 20", children: [
1445
+ title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("title", { children: title }) : null,
1446
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
1447
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1448
+ "path",
1449
+ {
1450
+ fill: "currentColor",
1451
+ d: "M16.5 12A4.5 4.5 0 0 0 14 7.97v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51A8.796 8.796 0 0 0 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3 3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06a8.99 8.99 0 0 0 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4 9.91 6.09 12 8.18V4z"
1452
+ }
1453
+ )
1454
+ ] });
1455
+
1456
+ // ../ui/ui/MediaControls/MediaControls.styles.ts
1457
+ var import_styled_components4 = __toESM(require("styled-components"), 1);
1458
+ var AudioPlayerContainer = import_styled_components4.default.div`
1459
+ background: #ededed; // Not in variable.
1460
+ display: flex;
1461
+ padding: 0.5em;
1462
+ align-items: center;
1463
+ `;
1464
+ var BaseButton = import_styled_components4.default.button`
1465
+ cursor: pointer;
1466
+ padding: 0.75em 1.5em;
1467
+ font-size: 0.938em;
1468
+ background: none;
1469
+ color: inherit;
1470
+ border: none;
1471
+ text-decoration: none;
1472
+ display: inline-block;
1473
+ vertical-align: top;
1474
+ white-space: nowrap;
1475
+ `;
1476
+ var PlayButton = (0, import_styled_components4.default)(BaseButton)`
1477
+ width: 2em;
1478
+ height: 2em;
1479
+ overflow: hidden;
1480
+ font-size: 1.1em;
1481
+ background: #fff;
1482
+ border-radius: 3px;
1483
+ padding: 0;
1484
+ margin: 0;
1485
+ color: #000; // Not in colours
1486
+
1487
+ &:disabled {
1488
+ color: #999;
1489
+ }
1490
+ `;
1491
+ var TimeDisplay = import_styled_components4.default.div`
1492
+ margin: 0 1em;
1493
+ font-size: 0.85em;
1494
+ color: #000;
1495
+ `;
1496
+ var ProgressContainer = import_styled_components4.default.div`
1497
+ flex: 1 1 0px;
1498
+ height: 6px;
1499
+ display: flex;
1500
+ position: relative;
1501
+ padding: 15px 0;
1502
+ `;
1503
+ var ProgressCurrent = import_styled_components4.default.div`
1504
+ background: #d85680;
1505
+ height: 6px;
1506
+ pointer-events: none;
1507
+ position: absolute;
1508
+ top: 13px;
1509
+ left: 0;
1510
+ border-radius: 3px;
1511
+ transition: width 200ms;
1512
+ `;
1513
+ var ProgressBackground = import_styled_components4.default.div`
1514
+ position: absolute;
1515
+ top: 13px;
1516
+ left: 0;
1517
+ height: 6px;
1518
+ border-radius: 3px;
1519
+ width: 100%;
1520
+ pointer-events: none;
1521
+ background: #fff;
1522
+ `;
1523
+ var SoundButton = (0, import_styled_components4.default)(BaseButton)`
1524
+ width: 2em;
1525
+ height: 2em;
1526
+ overflow: hidden;
1527
+ font-size: 1.1em;
1528
+ background: transparent;
1529
+ border-radius: 3px;
1530
+ padding: 0;
1531
+ margin: 0;
1532
+ `;
1533
+ var SoundContainer = import_styled_components4.default.div`
1534
+ display: flex;
1535
+ align-items: center;
1536
+ `;
1537
+ var VolumeContainer = import_styled_components4.default.div`
1538
+ width: 0;
1539
+ overflow: hidden;
1540
+ transition: width 500ms;
1541
+ color: #4a473f; // Not in colours
1542
+
1543
+ ${(props) => props.$isOpen && import_styled_components4.css`
1544
+ width: 150px;
1545
+ `}
1546
+ `;
1547
+ var VolumeSlider = import_styled_components4.default.input.attrs({ type: "range" })`
1548
+ width: 120px;
1549
+ margin: 0 15px;
1550
+ `;
1551
+
1552
+ // ../ui/madoc/components/icons/Spinner.tsx
1553
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1554
+ function Spinner(props) {
1555
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("svg", { width: "1em", height: "1em", viewBox: "0 0 42 42", xmlns: "http://www.w3.org/2000/svg", stroke: "#fff", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("g", { transform: "translate(2 2)", strokeWidth: 5, fill: "none", fillRule: "evenodd", children: [
1556
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("circle", { strokeOpacity: 0.5, cx: 18, cy: 18, r: 18 }),
1557
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { d: "M36 18c0-9.94-8.06-18-18-18", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1558
+ "animateTransform",
1559
+ {
1560
+ attributeName: "transform",
1561
+ type: "rotate",
1562
+ from: "0 18 18",
1563
+ to: "360 18 18",
1564
+ dur: "1s",
1565
+ repeatCount: "indefinite"
1566
+ }
1567
+ ) })
1568
+ ] }) });
1569
+ }
1570
+
1571
+ // ../ui/atoms/VisuallHidden/VisuallHidden.tsx
1572
+ var import_styled_components5 = __toESM(require("styled-components"), 1);
1573
+ var visuallyHidden = import_styled_components5.css`
1574
+ clip: rect(1px, 1px, 1px, 1px);
1575
+ clip-path: inset(50%);
1576
+ height: 1px;
1577
+ width: 1px;
1578
+ margin: -1px;
1579
+ overflow: hidden;
1580
+ padding: 0;
1581
+ position: absolute;
1582
+ `;
1583
+ var VisuallyHiddenLabel = import_styled_components5.default.label`
1584
+ ${visuallyHidden}
1585
+ `;
1586
+
1587
+ // ../ui/ui/MediaControls/MediaControls.tsx
1588
+ var import_jsx_runtime30 = require("react/jsx-runtime");
1589
+ function MediaControls(props) {
1590
+ const [isVolumeOpen, setIsVolumeOpen] = (0, import_react6.useState)(false);
1591
+ const { progress, currentTime, element } = (0, import_react_iiif_vault2.useMediaElements)();
1592
+ const { duration, isMuted, volume, isPlaying, playRequested } = (0, import_react_iiif_vault2.useMediaState)();
1593
+ const { setVolume, toggleMute, play, pause, setDurationPercent } = (0, import_react_iiif_vault2.useMediaActions)();
1594
+ const Volume = isMuted || volume === 0 ? VolumeOffIcon : volume > 50 ? VolumeUpIcon : VolumeDownIcon;
1595
+ (0, import_react6.useLayoutEffect)(() => {
1596
+ if (element.current) {
1597
+ const $el = element.current;
1598
+ if ($el.error && props.onError) {
1599
+ props.onError($el.error?.message || "Unknown error");
1600
+ return;
1601
+ }
1602
+ const onError = () => {
1603
+ if (props.onError) {
1604
+ props.onError($el.error?.message || "Unknown error");
1605
+ }
1606
+ };
1607
+ const loadedMetadata = () => {
1608
+ if ($el.duration && props.onDuration) {
1609
+ props.onDuration($el.duration);
1610
+ }
1611
+ if (props.onDimensions && $el instanceof HTMLVideoElement) {
1612
+ props.onDimensions($el.videoWidth, $el.videoHeight);
1613
+ }
1614
+ };
1615
+ $el.addEventListener("loadedmetadata", loadedMetadata);
1616
+ $el.addEventListener("error", onError);
1617
+ return () => {
1618
+ $el.removeEventListener("loadedmetadata", loadedMetadata);
1619
+ $el.removeEventListener("error", onError);
1620
+ };
1621
+ }
1622
+ }, []);
1623
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(AudioPlayerContainer, { children: [
1624
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1625
+ PlayButton,
1626
+ {
1627
+ disabled: playRequested,
1628
+ onClick: () => {
1629
+ if (isPlaying) {
1630
+ pause();
1631
+ } else {
1632
+ play();
1633
+ }
1634
+ },
1635
+ children: playRequested ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Spinner, { stroke: "#999" }) : isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PauseIcon, { title: "Pause" }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PlayIcon, { title: "Play" })
1636
+ }
1637
+ ),
1638
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TimeDisplay, { ref: currentTime, children: "0:00" }),
1639
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
1640
+ ProgressContainer,
1641
+ {
1642
+ onClick: (e) => {
1643
+ const { left, width } = e.currentTarget.getBoundingClientRect();
1644
+ const percent = (e.pageX - left) / width;
1645
+ setDurationPercent(percent);
1646
+ },
1647
+ children: [
1648
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ProgressBackground, {}),
1649
+ duration ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ProgressCurrent, { ref: progress }) : null
1650
+ ]
1651
+ }
1652
+ ),
1653
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TimeDisplay, { children: (0, import_react_iiif_vault2.formatTime)(duration) }),
1654
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(SoundContainer, { onMouseEnter: () => setIsVolumeOpen(true), onMouseLeave: () => setIsVolumeOpen(false), children: [
1655
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(VolumeContainer, { $isOpen: isVolumeOpen, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { children: [
1656
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(VisuallyHiddenLabel, { htmlFor: "audio-slider", children: "Change volume" }),
1657
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1658
+ VolumeSlider,
1659
+ {
1660
+ id: "audio-slider",
1661
+ role: "slider",
1662
+ disabled: isMuted,
1663
+ min: "0",
1664
+ max: "100",
1665
+ value: volume,
1666
+ onChange: (e) => setVolume(Number(e.currentTarget.value))
1667
+ }
1668
+ )
1669
+ ] }) }),
1670
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SoundButton, { onClick: () => toggleMute(), children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Volume, { title: isMuted ? "Mute" : "Unmute" }) })
1671
+ ] })
1672
+ ] });
1673
+ }
1674
+
1675
+ // src/Annotation/AudioAnnotation/create-audio-annotation.tsx
1676
+ var import_react_iiif_vault3 = require("react-iiif-vault");
1677
+ var import_helpers2 = require("@iiif/helpers");
1678
+ var import_editors9 = require("@manifest-editor/editors");
1679
+ var import_jsx_runtime31 = require("react/jsx-runtime");
1680
+ async function createAudioAnnotation(data, ctx) {
1681
+ const annotation = {
1682
+ id: ctx.generateId("annotation"),
1683
+ type: "Annotation"
1684
+ };
1685
+ const targetType = ctx.options.targetType;
1686
+ const body = await ctx.embed({
1687
+ id: data.url,
1688
+ type: "Sound",
1689
+ format: "audio/mp4",
1690
+ duration: data.duration || 0
1691
+ });
1692
+ if (targetType === "Annotation") {
1693
+ return ctx.embed({
1694
+ ...annotation,
1695
+ label: (0, import_helpers2.getValue)(data.label) && data.label,
1696
+ motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
1697
+ body,
1698
+ target: ctx.getTarget()
1699
+ });
1700
+ }
1701
+ if (targetType === "Canvas") {
1702
+ const canvasId = ctx.generateId("canvas");
1703
+ const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
1704
+ const annotationResource = ctx.embed({
1705
+ ...annotation,
1706
+ motivation: "painting",
1707
+ body,
1708
+ target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
1709
+ });
1710
+ const page = ctx.embed({
1711
+ id: pageId,
1712
+ type: "AnnotationPage",
1713
+ items: [annotationResource]
1714
+ });
1715
+ return ctx.embed({
1716
+ id: canvasId,
1717
+ type: "Canvas",
1718
+ label: data.label || { en: ["Untitled HTML canvas"] },
1719
+ duration: data.duration || 0,
1720
+ items: [page]
1721
+ });
1722
+ }
1723
+ }
1724
+ function CreateAudioAnnotationForm(props) {
1725
+ const [url, setUrl] = (0, import_react7.useState)("");
1726
+ const [duration, setDuration] = (0, import_react7.useState)(0);
1727
+ const [error, setError] = (0, import_react7.useState)("");
1728
+ const [label, setLabel] = (0, import_react7.useState)({ en: [""] });
1729
+ const onSubmit = () => {
1730
+ props.runCreate({
1731
+ url,
1732
+ duration,
1733
+ label
1734
+ });
1735
+ };
1736
+ (0, import_react7.useEffect)(() => {
1737
+ setError("");
1738
+ setDuration(0);
1739
+ if (url) {
1740
+ const labelFromUrl = url.split("/").pop()?.split(".").shift();
1741
+ setLabel({ en: [labelFromUrl || ""] });
1742
+ }
1743
+ }, [url]);
1744
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(PaddedSidebarContainer, { children: [
1745
+ error ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ErrorMessage, { children: error }) : null,
1746
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_editors9.InputContainer, { children: [
1747
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_editors9.InputLabel, { htmlFor: "audio-url", children: "URL" }),
1748
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_editors9.Input, { type: "text", id: "audio-url", value: url, onChange: (e) => setUrl(e.target.value) })
1749
+ ] }),
1750
+ url && !error ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1751
+ import_editors9.LanguageFieldEditor,
1752
+ {
1753
+ containerId: "label",
1754
+ focusId: "label_",
1755
+ label: "Label",
1756
+ fields: label,
1757
+ onSave: (e) => setLabel(e.toInternationalString())
1758
+ },
1759
+ url + "__" + duration
1760
+ ) }) : null,
1761
+ url && !error ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_iiif_vault3.CanvasPanel.AudioHTML, { media: { url, duration, type: "Sound" }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1762
+ MediaControls,
1763
+ {
1764
+ onError: (error2) => setError(error2),
1765
+ onDuration: (duration2) => setDuration(duration2)
1766
+ },
1767
+ url + "__" + duration
1768
+ ) }, url + "__" + duration) : null,
1769
+ duration && !error ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_editors9.FormFieldWrapper, { children: [
1770
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_editors9.InputLabel, { htmlFor: "duration", children: "Duration" }),
1771
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_editors9.Input, { type: "number", id: "duration", value: duration, onChange: (e) => setDuration(e.target.valueAsNumber) })
1772
+ ] }) : null,
1773
+ url && !error && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Button, { onClick: onSubmit, children: "Add audio" })
1774
+ ] });
1775
+ }
1776
+
1777
+ // src/Annotation/AudioAnnotation/index.tsx
1778
+ var import_components9 = require("@manifest-editor/components");
1779
+ var import_jsx_runtime32 = require("react/jsx-runtime");
1780
+ var audioAnnotation = {
1781
+ id: "@manifest-editor/audio-annotation",
1782
+ create: createAudioAnnotation,
1783
+ label: "Audio",
1784
+ summary: "Audio annotation",
1785
+ icon: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_components9.AudioIcon, {}),
1786
+ render(ctx) {
1787
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(CreateAudioAnnotationForm, { ...ctx });
1788
+ },
1789
+ resourceType: "Annotation",
1790
+ resourceFields: ["id", "type", "motivation", "body", "target"],
1791
+ additionalTypes: ["Canvas"],
1792
+ supports: {
1793
+ initialData: true,
1794
+ parentTypes: ["AnnotationPage", "Manifest"],
1795
+ parentFields: ["items"]
1796
+ },
1797
+ staticFields: {
1798
+ type: "Annotation"
1799
+ }
1800
+ };
1801
+
1802
+ // src/Annotation/VideoAnnotation/create-video-annotation.tsx
1803
+ var import_helpers3 = require("@iiif/helpers");
1804
+ var import_editors10 = require("@manifest-editor/editors");
1805
+ var import_react8 = require("react");
1806
+
1807
+ // ../ui/ui/VideoPlayer/VideoPlayer.tsx
1808
+ var import_react_iiif_vault4 = require("react-iiif-vault");
1809
+ var import_jsx_runtime33 = require("react/jsx-runtime");
1810
+ function VideoPlayer({
1811
+ media,
1812
+ onError,
1813
+ duration,
1814
+ onDuration,
1815
+ onDimensions
1816
+ }) {
1817
+ const [{ element, currentTime, progress }, state, actions] = (0, import_react_iiif_vault4.useSimpleMediaPlayer)({ duration });
1818
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
1819
+ import_react_iiif_vault4.MediaPlayerProvider,
1820
+ {
1821
+ element,
1822
+ state,
1823
+ actions,
1824
+ currentTime,
1825
+ progress,
1826
+ children: [
1827
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
1828
+ "div",
1829
+ {
1830
+ style: {
1831
+ maxHeight: 400,
1832
+ aspectRatio: `${media.width}/${media.height}`,
1833
+ position: "relative"
1834
+ },
1835
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_iiif_vault4.CanvasPanel.VideoHTML, { element, media, playPause: actions.playPause })
1836
+ }
1837
+ ),
1838
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MediaControls, { onError, onDuration, onDimensions })
1839
+ ]
1840
+ }
1841
+ );
1842
+ }
1843
+
1844
+ // src/Annotation/VideoAnnotation/create-video-annotation.tsx
1845
+ var import_jsx_runtime34 = require("react/jsx-runtime");
1846
+ async function createVideoAnnotation(data, ctx) {
1847
+ const annotation = {
1848
+ id: ctx.generateId("annotation"),
1849
+ type: "Annotation"
1850
+ };
1851
+ const targetType = ctx.options.targetType;
1852
+ const body = await ctx.embed({
1853
+ id: data.url,
1854
+ type: "Video",
1855
+ format: "video/mp4",
1856
+ width: data.width,
1857
+ height: data.height,
1858
+ duration: data.duration || 0
1859
+ });
1860
+ if (targetType === "Annotation") {
1861
+ return ctx.embed({
1862
+ ...annotation,
1863
+ label: (0, import_helpers3.getValue)(data.label) && data.label,
1864
+ motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
1865
+ body,
1866
+ target: ctx.getTarget()
1867
+ });
1868
+ }
1869
+ if (targetType === "Canvas") {
1870
+ const canvasId = ctx.generateId("canvas");
1871
+ const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
1872
+ const annotationResource = ctx.embed({
1873
+ ...annotation,
1874
+ motivation: "painting",
1875
+ body,
1876
+ target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
1877
+ });
1878
+ const page = ctx.embed({
1879
+ id: pageId,
1880
+ type: "AnnotationPage",
1881
+ items: [annotationResource]
1882
+ });
1883
+ return ctx.embed({
1884
+ id: canvasId,
1885
+ type: "Canvas",
1886
+ label: data.label || { en: ["Untitled HTML canvas"] },
1887
+ duration: data.duration || 0,
1888
+ width: data.width,
1889
+ height: data.height,
1890
+ items: [page]
1891
+ });
1892
+ }
1893
+ }
1894
+ function CreateVideoAnnotationForm(props) {
1895
+ const [url, setUrl] = (0, import_react8.useState)("");
1896
+ const [duration, setDuration] = (0, import_react8.useState)(0);
1897
+ const [width, setWidth] = (0, import_react8.useState)(0);
1898
+ const [height, setHeight] = (0, import_react8.useState)(0);
1899
+ const [error, setError] = (0, import_react8.useState)("");
1900
+ const [label, setLabel] = (0, import_react8.useState)({ en: [""] });
1901
+ const onSubmit = () => {
1902
+ props.runCreate({
1903
+ url,
1904
+ duration,
1905
+ label,
1906
+ width,
1907
+ height
1908
+ });
1909
+ };
1910
+ (0, import_react8.useEffect)(() => {
1911
+ setError("");
1912
+ setDuration(0);
1913
+ if (url) {
1914
+ const labelFromUrl = url.split("/").pop()?.split(".").shift();
1915
+ setLabel({ en: [labelFromUrl || ""] });
1916
+ }
1917
+ }, [url]);
1918
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(PaddedSidebarContainer, { children: [
1919
+ error ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ErrorMessage, { children: error }) : null,
1920
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_editors10.InputContainer, { children: [
1921
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_editors10.InputLabel, { htmlFor: "video-url", children: "URL" }),
1922
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_editors10.Input, { type: "text", id: "video-url", value: url, onChange: (e) => setUrl(e.target.value) })
1923
+ ] }),
1924
+ url && !error ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1925
+ import_editors10.LanguageFieldEditor,
1926
+ {
1927
+ containerId: "label",
1928
+ focusId: "label_",
1929
+ label: "Label",
1930
+ fields: label,
1931
+ onSave: (e) => setLabel(e.toInternationalString())
1932
+ },
1933
+ url + "__" + duration
1934
+ ) }) : null,
1935
+ url && !error ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1936
+ VideoPlayer,
1937
+ {
1938
+ duration,
1939
+ onDuration: (d) => setDuration(d),
1940
+ onError: (err) => setError(err),
1941
+ media: {
1942
+ url,
1943
+ duration,
1944
+ height,
1945
+ width,
1946
+ type: "Video"
1947
+ },
1948
+ onDimensions: (w, h) => {
1949
+ setWidth(w || 0);
1950
+ setHeight(h || 0);
1951
+ }
1952
+ }
1953
+ ) : null,
1954
+ !error && (duration || width || height) ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_editors10.InputContainer, { $wide: true, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1955
+ import_editors10.DimensionsTriplet,
1956
+ {
1957
+ widthId: "width",
1958
+ width: width || 0,
1959
+ changeWidth: (v) => setWidth(v),
1960
+ heightId: "height",
1961
+ height: height || 0,
1962
+ changeHeight: (v) => setHeight(v),
1963
+ durationId: "duration",
1964
+ duration: duration || 0,
1965
+ changeDuration: (v) => setDuration(v)
1966
+ }
1967
+ ) }) : null,
1968
+ url && !error && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Button, { onClick: onSubmit, children: "Add video" })
1969
+ ] });
1970
+ }
1971
+
1972
+ // src/Annotation/VideoAnnotation/index.tsx
1973
+ var import_components10 = require("@manifest-editor/components");
1974
+ var import_jsx_runtime35 = require("react/jsx-runtime");
1975
+ var videoAnnotation = {
1976
+ id: "@manifest-editor/video-annotation",
1977
+ create: createVideoAnnotation,
1978
+ label: "Video",
1979
+ summary: "Video annotation",
1980
+ icon: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_components10.VideoIcon, {}),
1981
+ render(ctx) {
1982
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(CreateVideoAnnotationForm, { ...ctx });
1983
+ },
1984
+ resourceType: "Annotation",
1985
+ resourceFields: ["id", "type", "motivation", "body", "target"],
1986
+ additionalTypes: ["Canvas"],
1987
+ supports: {
1988
+ initialData: true,
1989
+ parentTypes: ["AnnotationPage", "Manifest"],
1990
+ parentFields: ["items"]
1991
+ },
1992
+ staticFields: {
1993
+ type: "Annotation"
1994
+ }
1995
+ };
1996
+
1997
+ // src/Manifest/ManifestBrowserCreator/manifest-browser-creator.tsx
1998
+ var import_helpers4 = require("@iiif/helpers");
1999
+ var import_react9 = require("react");
2000
+ async function createFromManifestBrowserOutput(data, ctx) {
2001
+ const targetType = ctx.options.targetType;
2002
+ if (Array.isArray(data.output)) {
2003
+ throw new Error("Multiple items not yet supported");
2004
+ }
2005
+ const contentState = (0, import_helpers4.normaliseContentState)(
2006
+ typeof data.output === "string" ? (0, import_helpers4.parseContentState)(data.output) : data.output
2007
+ );
2008
+ const target = contentState.target[0];
2009
+ const previewVault = ctx.getPreviewVault();
2010
+ if (!target) {
2011
+ throw new Error("No target found in content state");
2012
+ }
2013
+ if (targetType === "Manifest") {
2014
+ const manifestId = target.source.id;
2015
+ invariant(manifestId, "Could not find Manifest ID");
2016
+ const manifest = await previewVault.get(manifestId);
2017
+ return ctx.embed({
2018
+ id: target.source.id,
2019
+ type: "Manifest",
2020
+ label: manifest.label
2021
+ });
2022
+ }
2023
+ if (targetType === "Collection") {
2024
+ const collectionId = target.source.id;
2025
+ invariant(collectionId, "Could not find Manifest ID");
2026
+ const collection = await previewVault.get(collectionId);
2027
+ return ctx.embed({
2028
+ id: target.source.id,
2029
+ type: "Collection",
2030
+ label: collection.label
2031
+ });
2032
+ }
2033
+ throw new Error("Not yet supported.");
2034
+ }
2035
+ var ManifestBrowserCreatorForm2 = (0, import_react9.lazy)(() => Promise.resolve().then(() => (init_manifest_browser_form_lazy(), manifest_browser_form_lazy_exports)));
2036
+
2037
+ // src/Manifest/ManifestBrowserCreator/index.tsx
2038
+ init_manifest_browser_form_lazy();
2039
+ var import_components11 = require("@manifest-editor/components");
2040
+ var import_jsx_runtime37 = require("react/jsx-runtime");
2041
+ var manifestBrowserCreator = {
2042
+ id: "@manifest-editor/manifest-browser-creator",
2043
+ create: createFromManifestBrowserOutput,
2044
+ label: "IIIF Browser",
2045
+ summary: "Browse IIIF Resources",
2046
+ icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_components11.IIIFBrowserIcon, {}),
2047
+ render(ctx) {
2048
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ManifestBrowserCreatorForm, { ...ctx });
2049
+ },
2050
+ resourceType: "Manifest",
2051
+ resourceFields: ["id", "label"],
2052
+ additionalTypes: ["Collection"],
2053
+ supports: {
2054
+ parentTypes: ["Collection"],
2055
+ parentFieldMap: {
2056
+ Collection: ["items"]
2057
+ }
2058
+ },
2059
+ sideEffects: [],
2060
+ staticFields: {}
2061
+ };
2062
+
2063
+ // src/index.ts
2064
+ var allCreators = [
2065
+ // Images first.
2066
+ imageServiceCreator,
2067
+ imageServiceAnnotation,
2068
+ imageUrlCreator,
2069
+ imageUrlAnnotation,
2070
+ videoAnnotation,
2071
+ audioAnnotation,
2072
+ htmlBodyCreator,
2073
+ htmlAnnotation,
2074
+ youTubeBodyCreator,
2075
+ iiifBrowserCreator,
2076
+ emptyCanvas,
2077
+ plaintextCreator,
2078
+ webPageCreator,
2079
+ emptyAnnotationPage,
2080
+ noBodyAnnotation,
2081
+ internalCanvas
2082
+ ];