@manifest-editor/creators 1.3.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -36,43 +36,46 @@ __export(iiif_browser_form_lazy_exports, {
36
36
  default: () => IIIFBrowserCreatorForm
37
37
  });
38
38
  function IIIFBrowserCreatorForm(props) {
39
- const vault = (0, import_react7.useMemo)(() => new import_helpers3.Vault(), []);
40
- const output = (0, import_react7.useMemo)(() => {
39
+ const vault = (0, import_react8.useMemo)(() => new import_helpers4.Vault(), []);
40
+ const output = (0, import_react8.useMemo)(() => {
41
41
  return [
42
42
  {
43
43
  type: "callback",
44
44
  label: "Select",
45
- supportedTypes: [
46
- "Canvas",
47
- "CanvasList",
48
- "CanvasRegion",
49
- "ImageService",
50
- "ImageServiceRegion"
51
- ],
45
+ supportedTypes: ["Canvas", "CanvasList", "CanvasRegion", "ImageService", "ImageServiceRegion"],
52
46
  cb: (resource) => props.runCreate({ output: resource }),
53
- format: { type: "content-state" }
47
+ format: {
48
+ type: "custom",
49
+ format: (resource, parent, vault2) => {
50
+ const resourcesAsArray = Array.isArray(resource) ? resource : [{ ...resource, parent }];
51
+ const resources = [];
52
+ for (const resource2 of resourcesAsArray) {
53
+ resources.push({ resource: vault2.get(resource2), parent: resource2.parent, selector: resource2.selector });
54
+ }
55
+ return resources;
56
+ }
57
+ }
54
58
  }
55
59
  ];
56
60
  }, [props.runCreate]);
57
- const navigationOptions = (0, import_react7.useMemo)(() => {
61
+ const navigationOptions = (0, import_react8.useMemo)(() => {
58
62
  return {
59
63
  canCropImage: true,
60
64
  canSelectCanvas: true,
61
65
  canSelectManifest: false,
62
66
  canSelectCollection: false,
63
67
  // @todo fix the output so this one works.
64
- multiSelect: false
68
+ multiSelect: true
65
69
  };
66
70
  }, []);
67
- const uiOptions = (0, import_react7.useMemo)(() => {
71
+ const uiOptions = (0, import_react8.useMemo)(() => {
68
72
  return {
69
73
  buttonClassName: "bg-me-primary-500 text-white hover:bg-me-primary-600"
70
74
  };
71
75
  }, []);
72
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_shell3.PreviewVaultBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
76
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_shell3.PreviewVaultBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
73
77
  import_iiif_browser2.IIIFBrowser,
74
78
  {
75
- debug: true,
76
79
  ui: uiOptions,
77
80
  vault,
78
81
  className: "iiif-browser border-none border-t rounded-none h-[70vh] min-h-[60vh] max-h-full max-w-full",
@@ -81,15 +84,15 @@ function IIIFBrowserCreatorForm(props) {
81
84
  }
82
85
  ) });
83
86
  }
84
- var import_helpers3, import_shell3, import_iiif_browser2, import_react7, import_jsx_runtime27;
87
+ var import_helpers4, import_shell3, import_iiif_browser2, import_react8, import_jsx_runtime29;
85
88
  var init_iiif_browser_form_lazy = __esm({
86
89
  "src/ContentResource/IIIFBrowserCreator/iiif-browser-form.lazy.tsx"() {
87
90
  "use strict";
88
- import_helpers3 = require("@iiif/helpers");
91
+ import_helpers4 = require("@iiif/helpers");
89
92
  import_shell3 = require("@manifest-editor/shell");
90
93
  import_iiif_browser2 = require("iiif-browser");
91
- import_react7 = require("react");
92
- import_jsx_runtime27 = require("react/jsx-runtime");
94
+ import_react8 = require("react");
95
+ import_jsx_runtime29 = require("react/jsx-runtime");
93
96
  }
94
97
  });
95
98
 
@@ -99,37 +102,54 @@ __export(manifest_browser_form_lazy_exports, {
99
102
  default: () => ManifestBrowserCreatorForm
100
103
  });
101
104
  function ManifestBrowserCreatorForm(props) {
102
- const vault = (0, import_shell4.usePreviewVault)();
103
- const { addHistory, clearHistory } = (0, import_shell4.usePreviewHistory)();
104
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_jsx_runtime38.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_shell4.PreviewVaultBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
105
- import_iiif_browser3.IIIFExplorer,
105
+ const vault = (0, import_react13.useMemo)(() => new import_helpers6.Vault(), []);
106
+ const output = (0, import_react13.useMemo)(() => {
107
+ return [
108
+ {
109
+ type: "callback",
110
+ label: "Select",
111
+ supportedTypes: ["Manifest", "Collection"],
112
+ cb: (resource) => props.runCreate({ output: resource }),
113
+ format: { type: "content-state" }
114
+ }
115
+ ];
116
+ }, [props.runCreate]);
117
+ const navigationOptions = (0, import_react13.useMemo)(() => {
118
+ return {
119
+ canCropImage: false,
120
+ canSelectCanvas: false,
121
+ canSelectManifest: true,
122
+ canSelectCollection: true,
123
+ // @todo fix the output so this one works.
124
+ multiSelect: false
125
+ };
126
+ }, []);
127
+ const uiOptions = (0, import_react13.useMemo)(() => {
128
+ return {
129
+ buttonClassName: "bg-me-primary-500 text-white hover:bg-me-primary-600"
130
+ };
131
+ }, []);
132
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_shell4.PreviewVaultBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
133
+ import_iiif_browser3.IIIFBrowser,
106
134
  {
107
- window: false,
108
- hideHeader: true,
109
- outputTypes: ["Manifest", "Collection"],
135
+ debug: true,
136
+ ui: uiOptions,
110
137
  vault,
111
- output: { type: "content-state" },
112
- homepageCollection: import_shell4.HOMEPAGE_COLLECTION,
113
- clearHomepageCollection: clearHistory,
114
- onHistory: addHistory,
115
- outputTargets: [
116
- {
117
- type: "callback",
118
- label: "Select",
119
- cb: (resource) => props.runCreate({ output: resource })
120
- }
121
- ],
122
- allowRemoveEntry: true
138
+ className: "iiif-browser border-none border-t rounded-none h-[70vh] min-h-[60vh] max-h-full max-w-full",
139
+ output,
140
+ navigation: navigationOptions
123
141
  }
124
- ) }) });
142
+ ) });
125
143
  }
126
- var import_iiif_browser3, import_shell4, import_jsx_runtime38;
144
+ var import_helpers6, import_shell4, import_iiif_browser3, import_react13, import_jsx_runtime43;
127
145
  var init_manifest_browser_form_lazy = __esm({
128
146
  "src/Manifest/ManifestBrowserCreator/manifest-browser-form.lazy.tsx"() {
129
147
  "use strict";
130
- import_iiif_browser3 = require("@manifest-editor/iiif-browser");
148
+ import_helpers6 = require("@iiif/helpers");
131
149
  import_shell4 = require("@manifest-editor/shell");
132
- import_jsx_runtime38 = require("react/jsx-runtime");
150
+ import_iiif_browser3 = require("iiif-browser");
151
+ import_react13 = require("react");
152
+ import_jsx_runtime43 = require("react/jsx-runtime");
133
153
  }
134
154
  });
135
155
 
@@ -144,10 +164,13 @@ __export(src_exports, {
144
164
  CreateImageServiceAnnotationForm: () => CreateImageServiceAnnotationForm,
145
165
  CreateImageUrlAnnotationForm: () => CreateImageUrlAnnotationForm,
146
166
  CreateImageUrlForm: () => CreateImageUrlForm,
167
+ CreateImageUrlListForm: () => CreateImageUrlListForm,
147
168
  CreatePlaintextForm: () => CreatePlaintextForm,
169
+ CreateThumbnailForm: () => CreateThumbnailForm,
148
170
  CreateVideoAnnotationForm: () => CreateVideoAnnotationForm,
149
171
  CreateWebPageForm: () => CreateWebPageForm,
150
172
  IIIFBrowserCreatorForm: () => IIIFBrowserCreatorForm2,
173
+ ManifestBrowserCreatorForm: () => ManifestBrowserCreatorForm2,
151
174
  YouTubeForm: () => YouTubeForm,
152
175
  allCreators: () => allCreators,
153
176
  audioAnnotation: () => audioAnnotation,
@@ -155,14 +178,18 @@ __export(src_exports, {
155
178
  createAudioAnnotation: () => createAudioAnnotation,
156
179
  createCaptionedImageAnnotation: () => createCaptionedImageAnnotation,
157
180
  createFromIIIFBrowserOutput: () => createFromIIIFBrowserOutput,
181
+ createFromManifestBrowserOutput: () => createFromManifestBrowserOutput,
158
182
  createHtmlAnnotation: () => createHtmlAnnotation,
159
183
  createHtmlBody: () => createHtmlBody,
160
184
  createImageServer: () => createImageServer,
161
185
  createImageServiceAnnotation: () => createImageServiceAnnotation,
162
186
  createImageUrl: () => createImageUrl,
163
187
  createImageUrlAnnotation: () => createImageUrlAnnotation,
188
+ createImageUrlList: () => createImageUrlList,
189
+ createImageUrlListAnnotation: () => createImageUrlListAnnotation,
164
190
  createNoBodyAnnotation: () => createNoBodyAnnotation,
165
191
  createPlaintext: () => createPlaintext,
192
+ createThumbnail: () => createThumbnail,
166
193
  createVideoAnnotation: () => createVideoAnnotation,
167
194
  createWebPage: () => createWebPage,
168
195
  createYoutubeBody: () => createYoutubeBody,
@@ -176,6 +203,8 @@ __export(src_exports, {
176
203
  imageServiceCreator: () => imageServiceCreator,
177
204
  imageUrlAnnotation: () => imageUrlAnnotation,
178
205
  imageUrlCreator: () => imageUrlCreator,
206
+ imageUrlListAnnotation: () => imageUrlListAnnotation,
207
+ imageUrlListCreator: () => imageUrlListCreator,
179
208
  internalCanvas: () => internalCanvas,
180
209
  manifestBrowserCreator: () => manifestBrowserCreator,
181
210
  noBodyAnnotation: () => noBodyAnnotation,
@@ -189,21 +218,12 @@ module.exports = __toCommonJS(src_exports);
189
218
 
190
219
  // src/Annotation/AudioAnnotation/index.tsx
191
220
  var import_components2 = require("@manifest-editor/components");
221
+ var import_creator_api = require("@manifest-editor/creator-api");
192
222
 
193
223
  // src/Annotation/AudioAnnotation/create-audio-annotation.tsx
194
- var import_react2 = require("react");
195
-
196
- // ../ui/atoms/PaddedSidebarContainer.tsx
197
- var import_styled_components = __toESM(require("styled-components"), 1);
198
- var PaddedSidebarContainer = import_styled_components.default.div`
199
- padding: 0 0.7em;
200
- margin: 0.7em 0;
201
- flex: 1;
202
- overflow: visible;
203
- `;
204
-
205
- // src/Annotation/AudioAnnotation/create-audio-annotation.tsx
224
+ var import_helpers = require("@iiif/helpers");
206
225
  var import_components = require("@manifest-editor/components");
226
+ var import_editors = require("@manifest-editor/editors");
207
227
 
208
228
  // ../ui/ui/MediaControls/MediaControls.tsx
209
229
  var import_react_iiif_vault = require("react-iiif-vault");
@@ -256,14 +276,14 @@ var VolumeOffIcon = ({ title, ...props }) => /* @__PURE__ */ (0, import_jsx_runt
256
276
  ] });
257
277
 
258
278
  // ../ui/ui/MediaControls/MediaControls.styles.ts
259
- var import_styled_components2 = __toESM(require("styled-components"), 1);
260
- var AudioPlayerContainer = import_styled_components2.default.div`
279
+ var import_styled_components = __toESM(require("styled-components"), 1);
280
+ var AudioPlayerContainer = import_styled_components.default.div`
261
281
  background: #ededed; // Not in variable.
262
282
  display: flex;
263
283
  padding: 0.5em;
264
284
  align-items: center;
265
285
  `;
266
- var BaseButton = import_styled_components2.default.button`
286
+ var BaseButton = import_styled_components.default.button`
267
287
  cursor: pointer;
268
288
  padding: 0.75em 1.5em;
269
289
  font-size: 0.938em;
@@ -275,7 +295,7 @@ var BaseButton = import_styled_components2.default.button`
275
295
  vertical-align: top;
276
296
  white-space: nowrap;
277
297
  `;
278
- var PlayButton = (0, import_styled_components2.default)(BaseButton)`
298
+ var PlayButton = (0, import_styled_components.default)(BaseButton)`
279
299
  width: 2em;
280
300
  height: 2em;
281
301
  overflow: hidden;
@@ -290,19 +310,19 @@ var PlayButton = (0, import_styled_components2.default)(BaseButton)`
290
310
  color: #999;
291
311
  }
292
312
  `;
293
- var TimeDisplay = import_styled_components2.default.div`
313
+ var TimeDisplay = import_styled_components.default.div`
294
314
  margin: 0 1em;
295
315
  font-size: 0.85em;
296
316
  color: #000;
297
317
  `;
298
- var ProgressContainer = import_styled_components2.default.div`
318
+ var ProgressContainer = import_styled_components.default.div`
299
319
  flex: 1 1 0px;
300
320
  height: 6px;
301
321
  display: flex;
302
322
  position: relative;
303
323
  padding: 15px 0;
304
324
  `;
305
- var ProgressCurrent = import_styled_components2.default.div`
325
+ var ProgressCurrent = import_styled_components.default.div`
306
326
  background: #d85680;
307
327
  height: 6px;
308
328
  pointer-events: none;
@@ -312,7 +332,7 @@ var ProgressCurrent = import_styled_components2.default.div`
312
332
  border-radius: 3px;
313
333
  transition: width 200ms;
314
334
  `;
315
- var ProgressBackground = import_styled_components2.default.div`
335
+ var ProgressBackground = import_styled_components.default.div`
316
336
  position: absolute;
317
337
  top: 13px;
318
338
  left: 0;
@@ -322,7 +342,7 @@ var ProgressBackground = import_styled_components2.default.div`
322
342
  pointer-events: none;
323
343
  background: #fff;
324
344
  `;
325
- var SoundButton = (0, import_styled_components2.default)(BaseButton)`
345
+ var SoundButton = (0, import_styled_components.default)(BaseButton)`
326
346
  width: 2em;
327
347
  height: 2em;
328
348
  overflow: hidden;
@@ -332,21 +352,21 @@ var SoundButton = (0, import_styled_components2.default)(BaseButton)`
332
352
  padding: 0;
333
353
  margin: 0;
334
354
  `;
335
- var SoundContainer = import_styled_components2.default.div`
355
+ var SoundContainer = import_styled_components.default.div`
336
356
  display: flex;
337
357
  align-items: center;
338
358
  `;
339
- var VolumeContainer = import_styled_components2.default.div`
359
+ var VolumeContainer = import_styled_components.default.div`
340
360
  width: 0;
341
361
  overflow: hidden;
342
362
  transition: width 500ms;
343
363
  color: #4a473f; // Not in colours
344
364
 
345
- ${(props) => props.$isOpen && import_styled_components2.css`
365
+ ${(props) => props.$isOpen && import_styled_components.css`
346
366
  width: 150px;
347
367
  `}
348
368
  `;
349
- var VolumeSlider = import_styled_components2.default.input.attrs({ type: "range" })`
369
+ var VolumeSlider = import_styled_components.default.input.attrs({ type: "range" })`
350
370
  width: 120px;
351
371
  margin: 0 15px;
352
372
  `;
@@ -354,25 +374,36 @@ var VolumeSlider = import_styled_components2.default.input.attrs({ type: "range"
354
374
  // ../ui/madoc/components/icons/Spinner.tsx
355
375
  var import_jsx_runtime2 = require("react/jsx-runtime");
356
376
  function Spinner(props) {
357
- return /* @__PURE__ */ (0, import_jsx_runtime2.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_runtime2.jsxs)("g", { transform: "translate(2 2)", strokeWidth: 5, fill: "none", fillRule: "evenodd", children: [
358
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { strokeOpacity: 0.5, cx: 18, cy: 18, r: 18 }),
359
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M36 18c0-9.94-8.06-18-18-18", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
360
- "animateTransform",
361
- {
362
- attributeName: "transform",
363
- type: "rotate",
364
- from: "0 18 18",
365
- to: "360 18 18",
366
- dur: "1s",
367
- repeatCount: "indefinite"
368
- }
369
- ) })
370
- ] }) });
377
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
378
+ "svg",
379
+ {
380
+ width: "1em",
381
+ height: "1em",
382
+ viewBox: "0 0 42 42",
383
+ xmlns: "http://www.w3.org/2000/svg",
384
+ stroke: "currentColor",
385
+ ...props,
386
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { transform: "translate(2 2)", strokeWidth: 5, fill: "none", fillRule: "evenodd", children: [
387
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { strokeOpacity: 0.5, cx: 18, cy: 18, r: 18 }),
388
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M36 18c0-9.94-8.06-18-18-18", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
389
+ "animateTransform",
390
+ {
391
+ attributeName: "transform",
392
+ type: "rotate",
393
+ from: "0 18 18",
394
+ to: "360 18 18",
395
+ dur: "1s",
396
+ repeatCount: "indefinite"
397
+ }
398
+ ) })
399
+ ] })
400
+ }
401
+ );
371
402
  }
372
403
 
373
404
  // ../ui/atoms/VisuallHidden/VisuallHidden.tsx
374
- var import_styled_components3 = __toESM(require("styled-components"), 1);
375
- var visuallyHidden = import_styled_components3.css`
405
+ var import_styled_components2 = __toESM(require("styled-components"), 1);
406
+ var visuallyHidden = import_styled_components2.css`
376
407
  clip: rect(1px, 1px, 1px, 1px);
377
408
  clip-path: inset(50%);
378
409
  height: 1px;
@@ -382,7 +413,7 @@ var visuallyHidden = import_styled_components3.css`
382
413
  padding: 0;
383
414
  position: absolute;
384
415
  `;
385
- var VisuallyHiddenLabel = import_styled_components3.default.label`
416
+ var VisuallyHiddenLabel = import_styled_components2.default.label`
386
417
  ${visuallyHidden}
387
418
  `;
388
419
 
@@ -474,93 +505,18 @@ function MediaControls(props) {
474
505
  ] });
475
506
  }
476
507
 
477
- // src/Annotation/AudioAnnotation/create-audio-annotation.tsx
478
- var import_react_iiif_vault2 = require("react-iiif-vault");
479
- var import_helpers = require("@iiif/helpers");
480
- var import_editors = require("@manifest-editor/editors");
481
-
482
- // ../ui/atoms/Button.tsx
483
- var import_styled_components4 = __toESM(require("styled-components"), 1);
484
- var ButtonReset = import_styled_components4.default.button`
485
- border: none;
486
- outline: none;
487
- background-color: transparent;
488
- margin: 0;
489
- padding: 0;
490
- font-size: inherit;
491
- color: inherit;
492
- cursor: pointer;
493
- &:hover {
494
- color: inherit;
495
- }
496
- `;
497
- var Button = import_styled_components4.default.button`
498
- padding: 0.5rem 1rem;
499
- color: ${(props) => props.theme.color.main || "none"};
500
- background-color: ${(props) => props.theme.color.white || "white"};
501
- border-radius: inherit;
502
- border: none;
503
- cursor: pointer;
504
- display: flex;
505
- align-items: center;
506
- font-size: 0.85em;
507
- :disabled {
508
- opacity: 0.65;
509
- cursor: not-allowed;
510
- }
511
-
512
- &:hover {
513
- background: #eee;
514
- }
515
- `;
516
- var SmallButton = (0, import_styled_components4.default)(Button)`
517
- padding: 0.25em ${(props) => props.theme.padding.xs || "0.4em"};
518
- height: unset;
519
- background: none;
520
- `;
521
- var SecondaryButton = (0, import_styled_components4.default)(Button)`
522
- {
523
- padding: 0 ${(props) => props.theme.padding.medium || "1rem"};
524
- color: ${(props) => props.theme.color.main || "#B84C74;"};
525
- background-color: ${(props) => props.theme.color.white || "white"};
526
- border: 1px solid ${(props) => props.theme.color.main || "#B84C74;"};
527
- border-radius: 0.25rem;
528
- cursor: pointer;
529
- height: 2rem;
530
- display: flex;
531
- align-items: center;
532
- white-space: nowrap;
533
- font-size: 0.75rem;
534
-
535
- :disabled {
536
- opacity: 0.65;
537
- cursor: not-allowed;
538
- }
539
- }
540
- `;
541
- var CalltoButton = (0, import_styled_components4.default)(Button)`
542
- padding: 0 ${(props) => props.theme.padding.medium || "1rem"};
543
- color: ${(props) => props.theme.color.white || "white"};
544
- background-color: ${(props) => props.theme.color.main || "#B84C74;"};
545
- border: 1px solid #eee;
546
- border-radius: 0.25rem;
547
- cursor: pointer;
548
- justify-content: center;
549
- display: flex;
550
- align-items: center;
551
- &:hover {
552
- background-color: ${(props) => props.theme.color.mainHover || "#B84C74;"};
553
- }
554
- `;
555
- var ButtonGroup = import_styled_components4.default.div`
556
- display: flex;
557
- flex-direction: row;
558
- flex-wrap: wrap;
559
- align-items: flex-start;
560
- justify-content: ${(props) => props.$right ? "flex-end" : "flex-start"};
508
+ // ../ui/atoms/PaddedSidebarContainer.tsx
509
+ var import_styled_components3 = __toESM(require("styled-components"), 1);
510
+ var PaddedSidebarContainer = import_styled_components3.default.div`
511
+ padding: 0 0.7em;
512
+ margin: 0.7em 0;
513
+ flex: 1;
514
+ overflow: visible;
561
515
  `;
562
516
 
563
517
  // src/Annotation/AudioAnnotation/create-audio-annotation.tsx
518
+ var import_react2 = require("react");
519
+ var import_react_iiif_vault2 = require("react-iiif-vault");
564
520
  var import_jsx_runtime4 = require("react/jsx-runtime");
565
521
  async function createAudioAnnotation(data, ctx) {
566
522
  const annotation = {
@@ -568,7 +524,7 @@ async function createAudioAnnotation(data, ctx) {
568
524
  type: "Annotation"
569
525
  };
570
526
  const targetType = ctx.options.targetType;
571
- const body = await ctx.embed({
527
+ const body = ctx.embed({
572
528
  id: data.url,
573
529
  type: "Sound",
574
530
  format: "audio/mp4",
@@ -634,17 +590,9 @@ function CreateAudioAnnotationForm(props) {
634
590
  }, [url]);
635
591
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(PaddedSidebarContainer, { children: [
636
592
  error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_components.ErrorMessage, { children: error }) : null,
637
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_editors.InputContainer, { children: [
593
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_editors.InputContainer, { $wide: true, children: [
638
594
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_editors.InputLabel, { htmlFor: "audio-url", children: "URL" }),
639
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
640
- import_editors.Input,
641
- {
642
- type: "text",
643
- id: "audio-url",
644
- value: url,
645
- onChange: (e) => setUrl(e.target.value)
646
- }
647
- )
595
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_editors.Input, { type: "text", id: "audio-url", value: url, onChange: (e) => setUrl(e.target.value) })
648
596
  ] }),
649
597
  url && !error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
650
598
  import_editors.LanguageFieldEditor,
@@ -655,42 +603,27 @@ function CreateAudioAnnotationForm(props) {
655
603
  fields: label,
656
604
  onSave: (e) => setLabel(e.toInternationalString())
657
605
  },
658
- url + "__" + duration
606
+ `${url}__${duration}`
659
607
  ) }) : null,
660
- url && !error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
661
- import_react_iiif_vault2.CanvasPanel.AudioHTML,
608
+ url && !error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_iiif_vault2.CanvasPanel.AudioHTML, { media: { url, duration, type: "Sound" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
609
+ MediaControls,
662
610
  {
663
- media: { url, duration, type: "Sound" },
664
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
665
- MediaControls,
666
- {
667
- onError: (error2) => setError(error2),
668
- onDuration: (duration2) => setDuration(duration2)
669
- },
670
- url + "__" + duration
671
- )
611
+ onError: (error2) => setError(error2),
612
+ onDuration: (duration2) => setDuration(~~duration2)
672
613
  },
673
- url + "__" + duration
674
- ) : null,
614
+ `${url}__${duration}`
615
+ ) }, `${url}__${duration}`) : null,
675
616
  duration && !error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_editors.FormFieldWrapper, { children: [
676
617
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_editors.InputLabel, { htmlFor: "duration", children: "Duration" }),
677
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
678
- import_editors.Input,
679
- {
680
- type: "number",
681
- id: "duration",
682
- value: duration,
683
- onChange: (e) => setDuration(e.target.valueAsNumber)
684
- }
685
- )
618
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_editors.Input, { type: "number", id: "duration", value: duration, onChange: (e) => setDuration(e.target.valueAsNumber) })
686
619
  ] }) : null,
687
- url && !error && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { onClick: onSubmit, children: "Add audio" })
620
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_components.ActionButton, { primary: true, large: true, type: "button", onPress: onSubmit, isDisabled: !url || !!error, children: "Add audio" })
688
621
  ] });
689
622
  }
690
623
 
691
624
  // src/Annotation/AudioAnnotation/index.tsx
692
625
  var import_jsx_runtime5 = require("react/jsx-runtime");
693
- var audioAnnotation = {
626
+ var audioAnnotation = (0, import_creator_api.defineCreator)({
694
627
  id: "@manifest-editor/audio-annotation",
695
628
  create: createAudioAnnotation,
696
629
  label: "Audio",
@@ -710,12 +643,14 @@ var audioAnnotation = {
710
643
  staticFields: {
711
644
  type: "Annotation"
712
645
  }
713
- };
646
+ });
714
647
 
715
648
  // src/Annotation/CaptionedImageAnnotation/index.tsx
716
- var import_components3 = require("@manifest-editor/components");
649
+ var import_components4 = require("@manifest-editor/components");
650
+ var import_creator_api2 = require("@manifest-editor/creator-api");
717
651
 
718
652
  // src/Annotation/CaptionedImageAnnotation/create-captioned-image-annotation.tsx
653
+ var import_components3 = require("@manifest-editor/components");
719
654
  var import_editors2 = require("@manifest-editor/editors");
720
655
  var import_react3 = require("react");
721
656
  var import_jsx_runtime6 = require("react/jsx-runtime");
@@ -818,18 +753,18 @@ function CreateCaptionedImageAnnotation(props) {
818
753
  }
819
754
  )
820
755
  ] }),
821
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Button, { type: "submit", children: "Create" })
756
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_components3.ActionButton, { primary: true, large: true, type: "submit", children: "Create" })
822
757
  ] }) });
823
758
  }
824
759
 
825
760
  // src/Annotation/CaptionedImageAnnotation/index.tsx
826
761
  var import_jsx_runtime7 = require("react/jsx-runtime");
827
- var captionedImageAnnotation = {
762
+ var captionedImageAnnotation = (0, import_creator_api2.defineCreator)({
828
763
  id: "@manifest-editor/captioned-image-annotation",
829
764
  create: createCaptionedImageAnnotation,
830
765
  label: "Captioned image",
831
766
  summary: "Add an image from a URL with caption",
832
- icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_components3.AddImageIcon, {}),
767
+ icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_components4.AddImageIcon, {}),
833
768
  render(ctx) {
834
769
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CreateCaptionedImageAnnotation, { ...ctx });
835
770
  },
@@ -844,14 +779,17 @@ var captionedImageAnnotation = {
844
779
  staticFields: {
845
780
  type: "Annotation"
846
781
  }
847
- };
782
+ });
848
783
 
849
784
  // src/Annotation/HTMLAnnotation/index.tsx
850
- var import_components4 = require("@manifest-editor/components");
785
+ var import_components6 = require("@manifest-editor/components");
786
+ var import_creator_api3 = require("@manifest-editor/creator-api");
851
787
 
852
788
  // src/Annotation/HTMLAnnotation/create-html-annotation.tsx
853
- var import_react4 = require("react");
789
+ var import_helpers2 = require("@iiif/helpers");
790
+ var import_components5 = require("@manifest-editor/components");
854
791
  var import_editors3 = require("@manifest-editor/editors");
792
+ var import_react4 = require("react");
855
793
  var import_jsx_runtime8 = require("react/jsx-runtime");
856
794
  async function createHtmlAnnotation(data, ctx) {
857
795
  const annotation = {
@@ -916,36 +854,34 @@ async function createHtmlAnnotation(data, ctx) {
916
854
  }
917
855
  function CreateHTMLAnnotation(props) {
918
856
  const [body, setBody] = (0, import_react4.useState)({ en: [""] });
857
+ const isEmpty = (0, import_helpers2.getValue)(body).trim() === "";
919
858
  const onSubmit = () => {
920
859
  props.runCreate({
921
860
  body
922
861
  });
923
862
  };
924
863
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(PaddedSidebarContainer, { children: [
925
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_editors3.InputContainer, { children: [
926
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_editors3.InputLabel, { children: "HTML Body" }),
927
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
928
- import_editors3.LanguageFieldEditor,
929
- {
930
- focusId: "html-content",
931
- label: "HTML Content",
932
- fields: body,
933
- onSave: (e) => setBody(e.toInternationalString())
934
- }
935
- )
936
- ] }),
937
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { onClick: () => onSubmit(), children: "Create" })
864
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
865
+ import_editors3.LanguageFieldEditor,
866
+ {
867
+ focusId: "html-content",
868
+ label: "HTML Content",
869
+ fields: body,
870
+ onSave: (e) => setBody(e.toInternationalString())
871
+ }
872
+ ),
873
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_components5.ActionButton, { primary: true, large: true, type: "button", onPress: onSubmit, isDisabled: isEmpty, children: "Create" })
938
874
  ] });
939
875
  }
940
876
 
941
877
  // src/Annotation/HTMLAnnotation/index.tsx
942
878
  var import_jsx_runtime9 = require("react/jsx-runtime");
943
- var htmlAnnotation = {
879
+ var htmlAnnotation = (0, import_creator_api3.defineCreator)({
944
880
  id: "@manifest-editor/html-annotation",
945
881
  create: createHtmlAnnotation,
946
882
  label: "HTML",
947
883
  summary: "HTML annotation",
948
- icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components4.HTMLIcon, {}),
884
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components6.HTMLIcon, {}),
949
885
  render(ctx) {
950
886
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CreateHTMLAnnotation, { ...ctx });
951
887
  },
@@ -960,10 +896,11 @@ var htmlAnnotation = {
960
896
  staticFields: {
961
897
  type: "Annotation"
962
898
  }
963
- };
899
+ });
964
900
 
965
901
  // src/Annotation/ImageServiceAnnotation/index.tsx
966
- var import_components5 = require("@manifest-editor/components");
902
+ var import_components8 = require("@manifest-editor/components");
903
+ var import_creator_api5 = require("@manifest-editor/creator-api");
967
904
 
968
905
  // src/side-effects/reposition-multiple-images.ts
969
906
  var import_image_3 = require("@iiif/parser/image-3");
@@ -1151,12 +1088,26 @@ var resizeToFitService = {
1151
1088
  }
1152
1089
  };
1153
1090
 
1091
+ // src/Annotation/ImageServiceAnnotation/create-service-annotation.tsx
1092
+ var import_creator_api4 = require("@manifest-editor/creator-api");
1093
+
1154
1094
  // src/ContentResource/ImageServiceCreator/create-image-service.tsx
1155
1095
  var import_image_32 = require("@iiif/parser/image-3");
1096
+ var import_components7 = require("@manifest-editor/components");
1156
1097
  var import_editors5 = require("@manifest-editor/editors");
1098
+ var import_react5 = require("react");
1099
+ var import_react_error_boundary = require("react-error-boundary");
1100
+ var import_react_iiif_vault3 = require("react-iiif-vault");
1157
1101
  var import_jsx_runtime10 = require("react/jsx-runtime");
1158
1102
  async function createImageServer(data, ctx) {
1159
- const request = (0, import_image_32.createImageServiceRequest)(data.service);
1103
+ const service = { ...data.service };
1104
+ if (service["@id"]) {
1105
+ service.id = service["@id"];
1106
+ }
1107
+ if (service["@type"]) {
1108
+ service.type = service["@type"];
1109
+ }
1110
+ const request = (0, import_image_32.createImageServiceRequest)(service);
1160
1111
  const imageId = (0, import_image_32.imageServiceRequestToString)({
1161
1112
  identifier: request.identifier,
1162
1113
  server: request.server,
@@ -1181,37 +1132,64 @@ async function createImageServer(data, ctx) {
1181
1132
  id: imageId,
1182
1133
  type: "Image",
1183
1134
  format: data.format || "image/jpeg",
1184
- height: data.height || data.service.height,
1185
- width: data.width || data.service.width,
1135
+ height: data.height || service.height,
1136
+ width: data.width || service.width,
1186
1137
  service: data.embedService === false ? void 0 : [data.service]
1187
1138
  });
1188
1139
  return resource;
1189
1140
  }
1141
+ function getCanonicalUrl(url) {
1142
+ return url.endsWith("default.jpg") ? (0, import_image_32.imageServiceRequestToString)({
1143
+ ...(0, import_image_32.parseImageServiceRequest)(url),
1144
+ type: "info"
1145
+ }) : (0, import_image_32.canonicalServiceUrl)(url);
1146
+ }
1190
1147
  function CreateImageServerForm(props) {
1148
+ const [url, setUrl] = (0, import_react5.useState)("");
1191
1149
  const onSubmit = (e) => {
1192
1150
  e.preventDefault();
1193
1151
  const data = new FormData(e.target);
1194
1152
  const formData = Object.fromEntries(data.entries());
1195
- const url = formData.url;
1196
- if (url) {
1197
- const canon = (0, import_image_32.canonicalServiceUrl)(url);
1198
- fetch(canon).then((r) => r.json()).then((service) => {
1199
- if (service["@id"]) {
1200
- service.id = service["@id"];
1201
- }
1202
- if (service["@type"]) {
1203
- service.type = service["@type"];
1204
- }
1153
+ const url2 = formData.url;
1154
+ if (url2) {
1155
+ const info = getCanonicalUrl(url2);
1156
+ if (!info) {
1157
+ throw new Error("Invalid image service request");
1158
+ }
1159
+ fetch(info).then((r) => r.json()).then((service) => {
1205
1160
  props.runCreate({ url: formData.url, service });
1206
1161
  });
1207
1162
  }
1208
1163
  };
1209
1164
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("form", { onSubmit, children: [
1210
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_editors5.InputContainer, { $wide: true, children: [
1165
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex gap-2 items-center", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_editors5.InputContainer, { $wide: true, children: [
1211
1166
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_editors5.InputLabel, { htmlFor: "id", children: "Link to image service" }),
1212
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_editors5.Input, { id: "url", name: "url", defaultValue: "" })
1213
- ] }),
1214
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "submit", children: "Create" })
1167
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1168
+ import_editors5.Input,
1169
+ {
1170
+ id: "url",
1171
+ name: "url",
1172
+ defaultValue: "",
1173
+ onPaste: (e) => {
1174
+ const text = e.clipboardData.getData("text/plain");
1175
+ setUrl(text ? getCanonicalUrl(text) : "");
1176
+ },
1177
+ onBlur: (e) => setUrl(e.currentTarget.value ? getCanonicalUrl(e.currentTarget.value) : "")
1178
+ }
1179
+ )
1180
+ ] }) }),
1181
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "relative flex z-0 my-5 h-96 min-h-0 min-w-0 overflow-hidden bg-gray-200 rounded items-center justify-center", children: url.trim() ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_error_boundary.ErrorBoundary, { fallbackRender: () => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { children: "Invalid service" }), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1182
+ import_react_iiif_vault3.ImageService,
1183
+ {
1184
+ src: url,
1185
+ fluid: true,
1186
+ errorFallback: () => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { children: "Invalid service" }),
1187
+ background: "rgb(229,231,235)",
1188
+ className: "h-full w-full",
1189
+ containerProps: { className: "w-full h-full z-10" }
1190
+ }
1191
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "text-grey-600", children: "Preview" }) }),
1192
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_components7.ActionButton, { primary: true, large: true, type: "submit", isDisabled: !url, children: "Create" }) })
1215
1193
  ] }) });
1216
1194
  }
1217
1195
 
@@ -1223,13 +1201,10 @@ async function createImageServiceAnnotation(data, ctx) {
1223
1201
  type: "Annotation"
1224
1202
  };
1225
1203
  const targetType = ctx.options.targetType;
1226
- const resource = await ctx.create(
1227
- "@manifest-editor/image-service-creator",
1228
- data,
1229
- {
1230
- parent: { resource: annotation, property: "body" }
1231
- }
1232
- );
1204
+ const createImage = (0, import_creator_api4.creatorHelper)(ctx, "Annotation", "body", "@manifest-editor/image-service-creator");
1205
+ const resource = await createImage(data, {
1206
+ parent: { resource: annotation, property: "body" }
1207
+ });
1233
1208
  if (targetType === "Annotation") {
1234
1209
  return {
1235
1210
  ...annotation,
@@ -1258,12 +1233,21 @@ async function createImageServiceAnnotation(data, ctx) {
1258
1233
  type: "AnnotationPage",
1259
1234
  items: [annotationResource]
1260
1235
  });
1236
+ let thumbnail = void 0;
1237
+ if (data.service?.sizes) {
1238
+ const createThumbnail2 = (0, import_creator_api4.creatorHelper)(ctx, "Canvas", "thumbnail", "@manifest-editor/thumbnail-image");
1239
+ thumbnail = await createThumbnail2({
1240
+ service: data.service,
1241
+ width: data.thumbnailSize || 400
1242
+ });
1243
+ }
1261
1244
  return ctx.embed({
1262
1245
  id: canvasId,
1263
1246
  type: "Canvas",
1264
1247
  label: data.label || { en: ["Untitled canvas"] },
1265
1248
  height: resource.resource.height || 1e3,
1266
1249
  width: resource.resource.width || 1e3,
1250
+ thumbnail: thumbnail ? [thumbnail] : void 0,
1267
1251
  items: [page]
1268
1252
  });
1269
1253
  }
@@ -1274,14 +1258,14 @@ function CreateImageServiceAnnotationForm(props) {
1274
1258
 
1275
1259
  // src/Annotation/ImageServiceAnnotation/index.tsx
1276
1260
  var import_jsx_runtime12 = require("react/jsx-runtime");
1277
- var imageServiceAnnotation = {
1261
+ var imageServiceAnnotation = (0, import_creator_api5.defineCreator)({
1278
1262
  id: "@manifest-editor/image-service-annotation",
1279
1263
  create: createImageServiceAnnotation,
1280
1264
  label: "IIIF Image",
1281
1265
  dependencies: ["@manifest-editor/image-service-creator"],
1282
1266
  summary: "IIIF Image service",
1283
1267
  tags: ["image", "image-service"],
1284
- icon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_components5.IIIFLogo, { style: { padding: 10 } }),
1268
+ icon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_components8.IIIFLogo, { style: { padding: 10 } }),
1285
1269
  render(ctx) {
1286
1270
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CreateImageServiceAnnotationForm, { ...ctx });
1287
1271
  },
@@ -1292,20 +1276,21 @@ var imageServiceAnnotation = {
1292
1276
  parentTypes: ["AnnotationPage", "Manifest"],
1293
1277
  parentFields: ["items"]
1294
1278
  },
1295
- sideEffects: [
1296
- resizeToFitService,
1297
- resizeResourceToEmptyCanvas,
1298
- repositionMultipleImages
1299
- ],
1279
+ sideEffects: [resizeToFitService, resizeResourceToEmptyCanvas, repositionMultipleImages],
1300
1280
  staticFields: {
1301
1281
  type: "Annotation"
1302
1282
  }
1303
- };
1283
+ });
1304
1284
 
1305
1285
  // src/Annotation/ImageUrlAnnotation/index.tsx
1306
- var import_components6 = require("@manifest-editor/components");
1286
+ var import_components10 = require("@manifest-editor/components");
1287
+ var import_creator_api7 = require("@manifest-editor/creator-api");
1288
+
1289
+ // src/Annotation/ImageUrlAnnotation/create-image-url-annotation.tsx
1290
+ var import_creator_api6 = require("@manifest-editor/creator-api");
1307
1291
 
1308
1292
  // src/ContentResource/ImageUrlCreator/create-image-url.tsx
1293
+ var import_components9 = require("@manifest-editor/components");
1309
1294
  var import_editors6 = require("@manifest-editor/editors");
1310
1295
  var import_shell = require("@manifest-editor/shell");
1311
1296
  var import_jsx_runtime13 = require("react/jsx-runtime");
@@ -1340,7 +1325,7 @@ function CreateImageUrlForm(props) {
1340
1325
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_editors6.InputLabel, { htmlFor: "id", children: "Link to Image" }),
1341
1326
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_editors6.Input, { id: "url", name: "url", defaultValue: "" })
1342
1327
  ] }),
1343
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { type: "submit", children: "Create" })
1328
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_components9.ActionButton, { primary: true, large: true, type: "submit", children: "Create" })
1344
1329
  ] }) });
1345
1330
  }
1346
1331
 
@@ -1352,20 +1337,17 @@ async function createImageUrlAnnotation(data, ctx) {
1352
1337
  type: "Annotation"
1353
1338
  };
1354
1339
  const targetType = ctx.options.targetType;
1355
- const resource = await ctx.create(
1356
- "@manifest-editor/image-url-creator",
1357
- data,
1358
- {
1359
- parent: { resource: annotation, property: "body" }
1360
- }
1361
- );
1340
+ const createImage = (0, import_creator_api6.creatorHelper)(ctx, "Annotation", "body", "@manifest-editor/image-url-creator");
1341
+ const resource = await createImage(data, {
1342
+ parent: { resource: annotation, property: "body" }
1343
+ });
1362
1344
  if (targetType === "Annotation") {
1363
- return {
1345
+ return ctx.embed({
1364
1346
  ...annotation,
1365
1347
  body: [resource],
1366
1348
  motivation: data.motivation || "painting",
1367
1349
  target: ctx.getTarget()
1368
- };
1350
+ });
1369
1351
  }
1370
1352
  if (targetType === "Canvas") {
1371
1353
  const canvasId = ctx.generateId("canvas");
@@ -1396,6 +1378,7 @@ async function createImageUrlAnnotation(data, ctx) {
1396
1378
  items: [page]
1397
1379
  });
1398
1380
  }
1381
+ throw new Error("Unsupported target type");
1399
1382
  }
1400
1383
  function CreateImageUrlAnnotationForm(props) {
1401
1384
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CreateImageUrlForm, { ...props });
@@ -1403,14 +1386,14 @@ function CreateImageUrlAnnotationForm(props) {
1403
1386
 
1404
1387
  // src/Annotation/ImageUrlAnnotation/index.tsx
1405
1388
  var import_jsx_runtime15 = require("react/jsx-runtime");
1406
- var imageUrlAnnotation = {
1389
+ var imageUrlAnnotation = (0, import_creator_api7.defineCreator)({
1407
1390
  id: "@manifest-editor/image-url-annotation",
1408
1391
  create: createImageUrlAnnotation,
1409
1392
  label: "Image",
1410
1393
  dependencies: ["@manifest-editor/image-url-creator"],
1411
1394
  summary: "Image from URL",
1412
1395
  tags: ["image"],
1413
- icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_components6.AddImageIcon, {}),
1396
+ icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_components10.AddImageIcon, {}),
1414
1397
  render(ctx) {
1415
1398
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CreateImageUrlAnnotationForm, { ...ctx });
1416
1399
  },
@@ -1421,25 +1404,93 @@ var imageUrlAnnotation = {
1421
1404
  parentTypes: ["AnnotationPage", "Manifest"],
1422
1405
  parentFields: ["items"]
1423
1406
  },
1424
- sideEffects: [
1425
- resizeToFitService,
1426
- resizeResourceToEmptyCanvas,
1427
- repositionMultipleImages
1428
- ],
1407
+ sideEffects: [resizeToFitService, resizeResourceToEmptyCanvas, repositionMultipleImages],
1429
1408
  staticFields: {
1430
1409
  type: "Annotation"
1431
1410
  }
1432
- };
1411
+ });
1433
1412
 
1434
- // src/Annotation/NoBodyAnnotation/index.tsx
1435
- var import_components7 = require("@manifest-editor/components");
1413
+ // src/Annotation/ImageUrlListAnnotation/index.tsx
1414
+ var import_components12 = require("@manifest-editor/components");
1415
+ var import_creator_api10 = require("@manifest-editor/creator-api");
1416
+
1417
+ // src/ContentResource/ImageUrlListCreator/create-image-url-list.tsx
1418
+ var import_components11 = require("@manifest-editor/components");
1419
+ var import_creator_api8 = require("@manifest-editor/creator-api");
1436
1420
  var import_jsx_runtime16 = require("react/jsx-runtime");
1437
- var noBodyAnnotation = {
1421
+ async function createImageUrlList(payload, ctx) {
1422
+ const items = [];
1423
+ const createImage = (0, import_creator_api8.creatorHelper)(ctx, "Annotation", "body", "@manifest-editor/image-url-creator");
1424
+ for (const image of payload.images) {
1425
+ items.push(await createImage(image, ctx.options));
1426
+ }
1427
+ return items;
1428
+ }
1429
+ function CreateImageUrlListForm(props) {
1430
+ const onSubmit = (e) => {
1431
+ e.preventDefault();
1432
+ const data = new FormData(e.target);
1433
+ const formData = Object.fromEntries(data.entries());
1434
+ if (formData.urls) {
1435
+ props.runCreate({ images: formData.urls.split("\n").map((url) => ({ url })) });
1436
+ }
1437
+ };
1438
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_components11.Form.Form, { onSubmit, children: [
1439
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_components11.Form.InputContainer, { className: "mb-4", children: [
1440
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_components11.Form.Label, { children: "Enter a list of URLs (one per line)" }),
1441
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_components11.Form.TextArea, { name: "urls", rows: "10" })
1442
+ ] }),
1443
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_components11.ActionButton, { primary: true, large: true, type: "submit", children: "Create" })
1444
+ ] }) });
1445
+ }
1446
+
1447
+ // src/Annotation/ImageUrlListAnnotation/create-image-url-list-annotation.tsx
1448
+ var import_creator_api9 = require("@manifest-editor/creator-api");
1449
+ async function createImageUrlListAnnotation(payload, ctx) {
1450
+ const items = [];
1451
+ const createAnnotation = (0, import_creator_api9.creatorHelper)(ctx, "AnnotationPage", "items", "@manifest-editor/image-url-annotation");
1452
+ for (const image of payload.images) {
1453
+ items.push(await createAnnotation(image, ctx.options));
1454
+ }
1455
+ return items;
1456
+ }
1457
+
1458
+ // src/Annotation/ImageUrlListAnnotation/index.tsx
1459
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1460
+ var imageUrlListAnnotation = (0, import_creator_api10.defineCreator)({
1461
+ id: "@manifest-editor/image-url-list-annotation",
1462
+ create: createImageUrlListAnnotation,
1463
+ label: "List of Images",
1464
+ dependencies: ["@manifest-editor/image-url-annotation"],
1465
+ summary: "List of Images from URLs",
1466
+ tags: ["image"],
1467
+ icon: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_components12.ImageListIcon, {}),
1468
+ render(ctx) {
1469
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CreateImageUrlListForm, { ...ctx });
1470
+ },
1471
+ resourceType: "Annotation",
1472
+ resourceFields: ["id", "type", "motivation", "body", "target"],
1473
+ additionalTypes: ["Canvas"],
1474
+ supports: {
1475
+ parentTypes: ["AnnotationPage", "Manifest"],
1476
+ parentFields: ["items"]
1477
+ },
1478
+ sideEffects: [resizeToFitService, resizeResourceToEmptyCanvas, repositionMultipleImages],
1479
+ staticFields: {
1480
+ type: "Annotation"
1481
+ }
1482
+ });
1483
+
1484
+ // src/Annotation/NoBodyAnnotation/index.tsx
1485
+ var import_components13 = require("@manifest-editor/components");
1486
+ var import_creator_api11 = require("@manifest-editor/creator-api");
1487
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1488
+ var noBodyAnnotation = (0, import_creator_api11.defineCreator)({
1438
1489
  id: "@manifest-editor/no-body-annotation",
1439
1490
  create: createNoBodyAnnotation,
1440
1491
  label: "Annotation without body",
1441
1492
  summary: "Add an annotation that only has motivation and target",
1442
- icon: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_components7.EmptyCanvasIcon, {}),
1493
+ icon: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_components13.EmptyCanvasIcon, {}),
1443
1494
  resourceType: "Annotation",
1444
1495
  resourceFields: ["id", "type", "motivation", "target"],
1445
1496
  supports: {
@@ -1452,7 +1503,7 @@ var noBodyAnnotation = {
1452
1503
  staticFields: {
1453
1504
  type: "Annotation"
1454
1505
  }
1455
- };
1506
+ });
1456
1507
  function createNoBodyAnnotation(data, ctx) {
1457
1508
  return ctx.embed({
1458
1509
  id: ctx.generateId("annotation"),
@@ -1464,16 +1515,17 @@ function createNoBodyAnnotation(data, ctx) {
1464
1515
  }
1465
1516
 
1466
1517
  // src/Annotation/VideoAnnotation/index.tsx
1467
- var import_components9 = require("@manifest-editor/components");
1518
+ var import_components15 = require("@manifest-editor/components");
1519
+ var import_creator_api12 = require("@manifest-editor/creator-api");
1468
1520
 
1469
1521
  // src/Annotation/VideoAnnotation/create-video-annotation.tsx
1470
- var import_helpers2 = require("@iiif/helpers");
1471
- var import_components8 = require("@manifest-editor/components");
1522
+ var import_helpers3 = require("@iiif/helpers");
1523
+ var import_components14 = require("@manifest-editor/components");
1472
1524
  var import_editors7 = require("@manifest-editor/editors");
1473
1525
 
1474
1526
  // ../ui/ui/VideoPlayer/VideoPlayer.tsx
1475
- var import_react_iiif_vault3 = require("react-iiif-vault");
1476
- var import_jsx_runtime17 = require("react/jsx-runtime");
1527
+ var import_react_iiif_vault4 = require("react-iiif-vault");
1528
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1477
1529
  function VideoPlayer({
1478
1530
  media,
1479
1531
  onError,
@@ -1481,9 +1533,9 @@ function VideoPlayer({
1481
1533
  onDuration,
1482
1534
  onDimensions
1483
1535
  }) {
1484
- const [{ element, currentTime, progress }, state, actions] = (0, import_react_iiif_vault3.useSimpleMediaPlayer)({ duration });
1485
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1486
- import_react_iiif_vault3.MediaPlayerProvider,
1536
+ const [{ element, currentTime, progress }, state, actions] = (0, import_react_iiif_vault4.useSimpleMediaPlayer)({ duration });
1537
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1538
+ import_react_iiif_vault4.MediaPlayerProvider,
1487
1539
  {
1488
1540
  element,
1489
1541
  state,
@@ -1491,7 +1543,7 @@ function VideoPlayer({
1491
1543
  currentTime,
1492
1544
  progress,
1493
1545
  children: [
1494
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1546
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1495
1547
  "div",
1496
1548
  {
1497
1549
  style: {
@@ -1499,18 +1551,18 @@ function VideoPlayer({
1499
1551
  aspectRatio: `${media.width}/${media.height}`,
1500
1552
  position: "relative"
1501
1553
  },
1502
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_iiif_vault3.CanvasPanel.VideoHTML, { element, media, playPause: actions.playPause })
1554
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_iiif_vault4.CanvasPanel.VideoHTML, { element, media, playPause: actions.playPause })
1503
1555
  }
1504
1556
  ),
1505
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(MediaControls, { onError, onDuration, onDimensions })
1557
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(MediaControls, { onError, onDuration, onDimensions })
1506
1558
  ]
1507
1559
  }
1508
1560
  );
1509
1561
  }
1510
1562
 
1511
1563
  // src/Annotation/VideoAnnotation/create-video-annotation.tsx
1512
- var import_react5 = require("react");
1513
- var import_jsx_runtime18 = require("react/jsx-runtime");
1564
+ var import_react6 = require("react");
1565
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1514
1566
  async function createVideoAnnotation(data, ctx) {
1515
1567
  const annotation = {
1516
1568
  id: ctx.generateId("annotation"),
@@ -1528,7 +1580,7 @@ async function createVideoAnnotation(data, ctx) {
1528
1580
  if (targetType === "Annotation") {
1529
1581
  return ctx.embed({
1530
1582
  ...annotation,
1531
- label: (0, import_helpers2.getValue)(data.label) && data.label,
1583
+ label: (0, import_helpers3.getValue)(data.label) && data.label,
1532
1584
  motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
1533
1585
  body,
1534
1586
  target: ctx.getTarget()
@@ -1566,12 +1618,12 @@ async function createVideoAnnotation(data, ctx) {
1566
1618
  }
1567
1619
  }
1568
1620
  function CreateVideoAnnotationForm(props) {
1569
- const [url, setUrl] = (0, import_react5.useState)("");
1570
- const [duration, setDuration] = (0, import_react5.useState)(0);
1571
- const [width, setWidth] = (0, import_react5.useState)(0);
1572
- const [height, setHeight] = (0, import_react5.useState)(0);
1573
- const [error, setError] = (0, import_react5.useState)("");
1574
- const [label, setLabel] = (0, import_react5.useState)({ en: [""] });
1621
+ const [url, setUrl] = (0, import_react6.useState)("");
1622
+ const [duration, setDuration] = (0, import_react6.useState)(0);
1623
+ const [width, setWidth] = (0, import_react6.useState)(0);
1624
+ const [height, setHeight] = (0, import_react6.useState)(0);
1625
+ const [error, setError] = (0, import_react6.useState)("");
1626
+ const [label, setLabel] = (0, import_react6.useState)({ en: [""] });
1575
1627
  const onSubmit = () => {
1576
1628
  props.runCreate({
1577
1629
  url,
@@ -1581,7 +1633,7 @@ function CreateVideoAnnotationForm(props) {
1581
1633
  height
1582
1634
  });
1583
1635
  };
1584
- (0, import_react5.useEffect)(() => {
1636
+ (0, import_react6.useEffect)(() => {
1585
1637
  setError("");
1586
1638
  setDuration(0);
1587
1639
  if (url) {
@@ -1589,21 +1641,13 @@ function CreateVideoAnnotationForm(props) {
1589
1641
  setLabel({ en: [labelFromUrl || ""] });
1590
1642
  }
1591
1643
  }, [url]);
1592
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(PaddedSidebarContainer, { children: [
1593
- error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_components8.ErrorMessage, { children: error }) : null,
1594
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_editors7.InputContainer, { children: [
1595
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_editors7.InputLabel, { htmlFor: "video-url", children: "URL" }),
1596
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1597
- import_editors7.Input,
1598
- {
1599
- type: "text",
1600
- id: "video-url",
1601
- value: url,
1602
- onChange: (e) => setUrl(e.target.value)
1603
- }
1604
- )
1644
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(PaddedSidebarContainer, { children: [
1645
+ error ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_components14.ErrorMessage, { children: error }) : null,
1646
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_editors7.InputContainer, { $wide: true, children: [
1647
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_editors7.InputLabel, { htmlFor: "video-url", children: "URL" }),
1648
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_editors7.Input, { type: "text", id: "video-url", value: url, onChange: (e) => setUrl(e.target.value) })
1605
1649
  ] }),
1606
- url && !error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1650
+ url && !error ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1607
1651
  import_editors7.LanguageFieldEditor,
1608
1652
  {
1609
1653
  containerId: "label",
@@ -1612,9 +1656,9 @@ function CreateVideoAnnotationForm(props) {
1612
1656
  fields: label,
1613
1657
  onSave: (e) => setLabel(e.toInternationalString())
1614
1658
  },
1615
- url + "__" + duration
1659
+ `${url}__${duration}`
1616
1660
  ) }) : null,
1617
- url && !error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1661
+ url && !error ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "mb-4 bg-black", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1618
1662
  VideoPlayer,
1619
1663
  {
1620
1664
  duration,
@@ -1632,8 +1676,8 @@ function CreateVideoAnnotationForm(props) {
1632
1676
  setHeight(h || 0);
1633
1677
  }
1634
1678
  }
1635
- ) : null,
1636
- !error && (duration || width || height) ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_editors7.InputContainer, { $wide: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1679
+ ) }) : null,
1680
+ !error && (duration || width || height) ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_editors7.InputContainer, { $wide: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1637
1681
  import_editors7.DimensionsTriplet,
1638
1682
  {
1639
1683
  widthId: "width",
@@ -1647,20 +1691,20 @@ function CreateVideoAnnotationForm(props) {
1647
1691
  changeDuration: (v) => setDuration(v)
1648
1692
  }
1649
1693
  ) }) : null,
1650
- url && !error && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Button, { onClick: onSubmit, children: "Add video" })
1694
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_components14.ActionButton, { primary: true, large: true, type: "button", onPress: onSubmit, isDisabled: !url || !!error, children: "Add video" })
1651
1695
  ] });
1652
1696
  }
1653
1697
 
1654
1698
  // src/Annotation/VideoAnnotation/index.tsx
1655
- var import_jsx_runtime19 = require("react/jsx-runtime");
1656
- var videoAnnotation = {
1699
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1700
+ var videoAnnotation = (0, import_creator_api12.defineCreator)({
1657
1701
  id: "@manifest-editor/video-annotation",
1658
1702
  create: createVideoAnnotation,
1659
1703
  label: "Video",
1660
1704
  summary: "Video annotation",
1661
- icon: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_components9.VideoIcon, {}),
1705
+ icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_components15.VideoIcon, {}),
1662
1706
  render(ctx) {
1663
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CreateVideoAnnotationForm, { ...ctx });
1707
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CreateVideoAnnotationForm, { ...ctx });
1664
1708
  },
1665
1709
  resourceType: "Annotation",
1666
1710
  resourceFields: ["id", "type", "motivation", "body", "target"],
@@ -1673,11 +1717,14 @@ var videoAnnotation = {
1673
1717
  staticFields: {
1674
1718
  type: "Annotation"
1675
1719
  }
1676
- };
1720
+ });
1721
+
1722
+ // src/AnnotationPage/EmptyAnnotationPage/index.tsx
1723
+ var import_creator_api13 = require("@manifest-editor/creator-api");
1677
1724
 
1678
1725
  // ../ui/icons/ThumbnailStripIcon.tsx
1679
- var import_jsx_runtime20 = require("react/jsx-runtime");
1680
- var ThumbnailStripIcon = () => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1726
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1727
+ var ThumbnailStripIcon = () => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1681
1728
  "svg",
1682
1729
  {
1683
1730
  xmlns: "http://www.w3.org/2000/svg",
@@ -1686,16 +1733,16 @@ var ThumbnailStripIcon = () => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1686
1733
  width: "24px",
1687
1734
  fill: "#000000",
1688
1735
  transform: "scale(-1, 1)",
1689
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("g", { children: [
1690
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("rect", { fill: "none", height: "24", width: "24" }),
1691
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M16,20H2V4h14V20z M18,8h4V4h-4V8z M18,20h4v-4h-4V20z M18,14h4v-4h-4V14z" })
1736
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("g", { children: [
1737
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("rect", { fill: "none", height: "24", width: "24" }),
1738
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("path", { d: "M16,20H2V4h14V20z M18,8h4V4h-4V8z M18,20h4v-4h-4V20z M18,14h4v-4h-4V14z" })
1692
1739
  ] })
1693
1740
  }
1694
1741
  );
1695
1742
 
1696
1743
  // src/AnnotationPage/EmptyAnnotationPage/index.tsx
1697
- var import_jsx_runtime21 = require("react/jsx-runtime");
1698
- var emptyAnnotationPage = {
1744
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1745
+ var emptyAnnotationPage = (0, import_creator_api13.defineCreator)({
1699
1746
  id: "@manifest-editor/empty-annotation-page",
1700
1747
  create: (data, ctx) => {
1701
1748
  return ctx.embed({
@@ -1707,7 +1754,7 @@ var emptyAnnotationPage = {
1707
1754
  },
1708
1755
  label: "Empty annotation page",
1709
1756
  summary: "AnnotationPage with nothing",
1710
- icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ThumbnailStripIcon, {}),
1757
+ icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ThumbnailStripIcon, {}),
1711
1758
  resourceType: "AnnotationPage",
1712
1759
  resourceFields: ["id", "type", "items"],
1713
1760
  supports: {
@@ -1718,12 +1765,13 @@ var emptyAnnotationPage = {
1718
1765
  Range: ["annotations"]
1719
1766
  }
1720
1767
  }
1721
- };
1768
+ });
1722
1769
 
1723
1770
  // src/Canvas/EmptyCanvas/index.tsx
1724
- var import_components10 = require("@manifest-editor/components");
1725
- var import_jsx_runtime22 = require("react/jsx-runtime");
1726
- var emptyCanvas = {
1771
+ var import_components16 = require("@manifest-editor/components");
1772
+ var import_creator_api14 = require("@manifest-editor/creator-api");
1773
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1774
+ var emptyCanvas = (0, import_creator_api14.defineCreator)({
1727
1775
  id: "@manifest-editor/empty-canvas",
1728
1776
  create: (data, ctx) => {
1729
1777
  const canvasId = ctx.generateId("canvas");
@@ -1743,18 +1791,19 @@ var emptyCanvas = {
1743
1791
  },
1744
1792
  label: "Empty canvas",
1745
1793
  summary: "No content",
1746
- icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components10.EmptyCanvasIcon, {}),
1794
+ icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_components16.EmptyCanvasIcon, {}),
1747
1795
  resourceType: "Canvas",
1748
1796
  resourceFields: ["id", "type", "label", "height", "width", "items"],
1749
1797
  supports: {
1750
1798
  parentTypes: ["Manifest"],
1751
1799
  parentFields: ["items"]
1752
1800
  }
1753
- };
1801
+ });
1754
1802
 
1755
1803
  // src/Canvas/InternalCanvas/index.tsx
1804
+ var import_creator_api15 = require("@manifest-editor/creator-api");
1756
1805
  var import_iiif_browser = require("@manifest-editor/iiif-browser");
1757
- var import_react_iiif_vault4 = require("react-iiif-vault");
1806
+ var import_react_iiif_vault5 = require("react-iiif-vault");
1758
1807
 
1759
1808
  // ../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js
1760
1809
  var isProduction = false;
@@ -1772,26 +1821,26 @@ function invariant(condition, message) {
1772
1821
  }
1773
1822
 
1774
1823
  // src/Canvas/InternalCanvas/index.tsx
1775
- var import_jsx_runtime23 = require("react/jsx-runtime");
1776
- var internalCanvas = {
1824
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1825
+ var internalCanvas = (0, import_creator_api15.defineCreator)({
1777
1826
  id: "@manifest-editor/internal-canvas",
1778
1827
  create: createInternalCanvas,
1779
1828
  label: "Internal canvas link",
1780
1829
  summary: "Canvas from the same manifest",
1781
- icon: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ThumbnailStripIcon, {}),
1830
+ icon: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ThumbnailStripIcon, {}),
1782
1831
  resourceType: "Canvas",
1783
1832
  resourceFields: ["id", "type", "label"],
1784
1833
  supports: {
1785
1834
  parentTypes: ["Manifest"],
1786
1835
  parentFields: ["start"]
1787
1836
  },
1788
- render: (ctx) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(InternalCanvas, { ...ctx })
1789
- };
1837
+ render: (ctx) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(InternalCanvas, { ...ctx })
1838
+ });
1790
1839
  function InternalCanvas(props) {
1791
- const manifest = (0, import_react_iiif_vault4.useManifest)();
1792
- const vault = (0, import_react_iiif_vault4.useVault)();
1840
+ const manifest = (0, import_react_iiif_vault5.useManifest)();
1841
+ const vault = (0, import_react_iiif_vault5.useVault)();
1793
1842
  invariant(manifest, "Manifest is not loaded");
1794
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1843
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1795
1844
  import_iiif_browser.IIIFExplorer,
1796
1845
  {
1797
1846
  vault,
@@ -1817,18 +1866,22 @@ async function createInternalCanvas(data, ctx) {
1817
1866
  return ctx.embed({ id: data.id, type: "Canvas" });
1818
1867
  }
1819
1868
 
1869
+ // src/ContentResource/HTMLBodyCreator/index.tsx
1870
+ var import_creator_api16 = require("@manifest-editor/creator-api");
1871
+
1820
1872
  // ../ui/icons/TextFormatIcon.tsx
1821
- var import_jsx_runtime24 = require("react/jsx-runtime");
1822
- var TextFormatIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", height: "1em", width: "1em", ...props, children: [
1823
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
1824
- /* @__PURE__ */ (0, import_jsx_runtime24.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" })
1873
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1874
+ var TextFormatIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", height: "1em", width: "1em", ...props, children: [
1875
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
1876
+ /* @__PURE__ */ (0, import_jsx_runtime26.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" })
1825
1877
  ] });
1826
1878
 
1827
1879
  // src/ContentResource/HTMLBodyCreator/create-html-body.tsx
1880
+ var import_components17 = require("@manifest-editor/components");
1828
1881
  var import_editors8 = require("@manifest-editor/editors");
1829
1882
  var import_shell2 = require("@manifest-editor/shell");
1830
- var import_react6 = require("react");
1831
- var import_jsx_runtime25 = require("react/jsx-runtime");
1883
+ var import_react7 = require("react");
1884
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1832
1885
  async function createHtmlBody(data, ctx) {
1833
1886
  return ctx.embed({
1834
1887
  id: ctx.generateId(`html/${data.language}`),
@@ -1840,18 +1893,18 @@ async function createHtmlBody(data, ctx) {
1840
1893
  }
1841
1894
  function CreateHTMLBodyForm(props) {
1842
1895
  const { i18n } = (0, import_shell2.useConfig)();
1843
- const [body, setBodyValue] = (0, import_react6.useState)("<p></p>");
1844
- const [language, setLang] = (0, import_react6.useState)(i18n.defaultLanguage);
1896
+ const [body, setBodyValue] = (0, import_react7.useState)("<p></p>");
1897
+ const [language, setLang] = (0, import_react7.useState)(i18n.defaultLanguage);
1845
1898
  const onSubmit = () => {
1846
1899
  props.runCreate({
1847
1900
  language,
1848
1901
  body
1849
1902
  });
1850
1903
  };
1851
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(PaddedSidebarContainer, { children: [
1852
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_editors8.InputContainer, { children: [
1853
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_editors8.InputLabel, { children: "HTML Body" }),
1854
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1904
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(PaddedSidebarContainer, { children: [
1905
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_editors8.InputContainer, { children: [
1906
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_editors8.InputLabel, { children: "HTML Body" }),
1907
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
1855
1908
  import_editors8.RichTextLanguageField,
1856
1909
  {
1857
1910
  value: body,
@@ -1862,20 +1915,20 @@ function CreateHTMLBodyForm(props) {
1862
1915
  }
1863
1916
  )
1864
1917
  ] }),
1865
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button, { onClick: () => onSubmit(), children: "Create" })
1918
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_components17.ActionButton, { primary: true, large: true, type: "button", onPress: onSubmit, children: "Create" })
1866
1919
  ] });
1867
1920
  }
1868
1921
 
1869
1922
  // src/ContentResource/HTMLBodyCreator/index.tsx
1870
- var import_jsx_runtime26 = require("react/jsx-runtime");
1871
- var htmlBodyCreator = {
1923
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1924
+ var htmlBodyCreator = (0, import_creator_api16.defineCreator)({
1872
1925
  id: "@manifest-editor/html-body-creator",
1873
1926
  create: createHtmlBody,
1874
1927
  label: "HTML Body",
1875
1928
  summary: "Add HTML annotation body",
1876
- icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TextFormatIcon, {}),
1929
+ icon: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(TextFormatIcon, {}),
1877
1930
  render(ctx) {
1878
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CreateHTMLBodyForm, { ...ctx });
1931
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(CreateHTMLBodyForm, { ...ctx });
1879
1932
  },
1880
1933
  resourceType: "ContentResource",
1881
1934
  resourceFields: ["id", "language", "type", "format", "value"],
@@ -1887,15 +1940,16 @@ var htmlBodyCreator = {
1887
1940
  type: "TextualBody",
1888
1941
  format: "text/html"
1889
1942
  }
1890
- };
1943
+ });
1891
1944
 
1892
1945
  // src/ContentResource/IIIFBrowserCreator/index.tsx
1893
- var import_components11 = require("@manifest-editor/components");
1946
+ var import_components18 = require("@manifest-editor/components");
1947
+ var import_creator_api17 = require("@manifest-editor/creator-api");
1894
1948
 
1895
1949
  // src/ContentResource/IIIFBrowserCreator/iiif-browser-creator.tsx
1896
- var import_helpers4 = require("@iiif/helpers");
1950
+ var import_helpers5 = require("@iiif/helpers");
1897
1951
  var import_image_33 = require("@iiif/parser/image-3");
1898
- var import_react8 = require("react");
1952
+ var import_react9 = require("react");
1899
1953
  function croppedRegion(imageServiceId, region, size) {
1900
1954
  return `${imageServiceId}/${Math.floor(region.x)},${Math.floor(region.y)},${Math.floor(region.width)},${Math.floor(
1901
1955
  region.height
@@ -1903,145 +1957,148 @@ function croppedRegion(imageServiceId, region, size) {
1903
1957
  }
1904
1958
  async function createFromIIIFBrowserOutput(data, ctx) {
1905
1959
  const targetType = ctx.options.targetType;
1906
- if (Array.isArray(data.output)) {
1907
- throw new Error("Multiple items not yet supported");
1908
- }
1909
- const contentState = (0, import_helpers4.normaliseContentState)(
1910
- typeof data.output === "string" ? (0, import_helpers4.parseContentState)(data.output) : data.output
1911
- );
1912
- if (!contentState.target || contentState.target.length === 0) {
1913
- throw new Error("No target found in content state");
1914
- }
1915
- const target = contentState.target[0];
1916
- const type = target.source.type;
1917
- const previewVault = new import_helpers4.Vault();
1918
- if (targetType === "Canvas" || targetType === "Annotation" || targetType === "ContentResource") {
1919
- if (type === "Canvas") {
1920
- const canvasId = target.source.id;
1921
- const manifestId = target.source.partOf?.find(
1922
- (t) => t.type === "Manifest"
1923
- );
1924
- invariant(manifestId, "Could not load external resource without partOf");
1925
- const manifest = await previewVault.loadManifest(manifestId);
1926
- invariant(manifest, "Manifest not found");
1927
- const canvasRef = manifest.items.find((item) => item.id === canvasId);
1928
- invariant(canvasRef, "Canvas not found");
1929
- const canvas = previewVault.get(canvasRef);
1930
- if (targetType === "Canvas" && target.selector?.type !== "BoxSelector") {
1931
- return ctx.embed(previewVault.toPresentation3(canvas));
1932
- }
1933
- const annotationPage = previewVault.get(canvas.items[0]);
1934
- const annotation = previewVault.get(annotationPage.items[0]);
1935
- if (targetType === "Annotation" || targetType === "Canvas" || targetType === "ContentResource") {
1936
- const fullAnnotation = previewVault.toPresentation3(annotation);
1937
- fullAnnotation.id = ctx.generateId("Annotation");
1938
- let service = null;
1939
- const dimensions = { width: 0, height: 0 };
1940
- if (fullAnnotation?.body?.service) {
1941
- const width = fullAnnotation?.body.width;
1942
- const height = fullAnnotation?.body.height;
1943
- service = (0, import_image_33.getImageServices)(fullAnnotation?.body)[0];
1944
- if (service && (!service.width || !service.height)) {
1945
- service.width = width;
1946
- service.height = height;
1947
- }
1948
- dimensions.width = width;
1949
- dimensions.height = height;
1950
- if (data.trackSize) {
1951
- data.trackSize(dimensions);
1960
+ const resources = data.output;
1961
+ const returnResources = [];
1962
+ for (const { resource, selector, parent } of resources) {
1963
+ const type = resource.type;
1964
+ const previewVault = new import_helpers5.Vault();
1965
+ if (targetType === "Canvas" || targetType === "Annotation" || targetType === "ContentResource") {
1966
+ if (type === "Canvas") {
1967
+ const canvasId = resource.id;
1968
+ const manifestId = parent?.type === "Manifest" ? parent.id : void 0;
1969
+ invariant(manifestId, "Could not find Manifest");
1970
+ const manifest = await previewVault.loadManifest(manifestId);
1971
+ invariant(manifest, "Manifest not found");
1972
+ const canvasRef = manifest.items.find((item) => item.id === canvasId);
1973
+ invariant(canvasRef, "Canvas not found");
1974
+ const canvas = previewVault.get(canvasRef);
1975
+ if (targetType === "Canvas" && selector?.type !== "BoxSelector") {
1976
+ const fullCanvas = previewVault.toPresentation3(canvas);
1977
+ if (!fullCanvas.label) {
1978
+ fullCanvas.label = { en: ["Untitled canvas"] };
1952
1979
  }
1980
+ returnResources.push(ctx.embed(fullCanvas));
1981
+ continue;
1953
1982
  }
1954
- if (target.selector && target.selector.type === "BoxSelector") {
1955
- const selector = {
1956
- "@context": "http://iiif.io/api/annex/openannotation/context.json",
1957
- type: "iiif:ImageApiSelector",
1958
- region: [
1959
- ~~target.selector.spatial.x,
1960
- ~~target.selector.spatial.y,
1961
- ~~target.selector.spatial.width,
1962
- ~~target.selector.spatial.height
1963
- ].join(",")
1964
- };
1965
- const newBody = { ...fullAnnotation.body };
1966
- let thumbnailId = "";
1967
- if (service) {
1968
- const id = service.id || service["@id"] || "";
1969
- if (id) {
1970
- newBody.id = croppedRegion(id, target.selector.spatial, "max");
1971
- thumbnailId = croppedRegion(id, target.selector.spatial, "512,");
1983
+ const annotationPage = previewVault.get(canvas.items[0]);
1984
+ const annotation = previewVault.get(annotationPage.items[0]);
1985
+ if (targetType === "Annotation" || targetType === "Canvas" || targetType === "ContentResource") {
1986
+ const fullAnnotation = previewVault.toPresentation3(annotation);
1987
+ fullAnnotation.id = ctx.generateId("Annotation");
1988
+ let service = null;
1989
+ const dimensions = { width: 0, height: 0 };
1990
+ if (fullAnnotation?.body?.service) {
1991
+ const width = fullAnnotation?.body.width;
1992
+ const height = fullAnnotation?.body.height;
1993
+ service = (0, import_image_33.getImageServices)(fullAnnotation?.body)[0];
1994
+ if (service && (!service.width || !service.height)) {
1995
+ service.width = width;
1996
+ service.height = height;
1997
+ }
1998
+ dimensions.width = width;
1999
+ dimensions.height = height;
2000
+ if (data.trackSize) {
2001
+ data.trackSize(dimensions);
1972
2002
  }
1973
2003
  }
1974
- fullAnnotation.body = {
1975
- id: ctx.generateId("SpecificResource", annotation),
1976
- type: "SpecificResource",
1977
- source: newBody,
1978
- selector
1979
- };
1980
- if (data.trackSize) {
1981
- data.trackSize({
1982
- width: ~~target.selector.spatial.width,
1983
- height: ~~target.selector.spatial.height
1984
- });
1985
- }
1986
- if (targetType === "ContentResource") {
1987
- return fullAnnotation.body;
1988
- }
1989
- if (targetType === "Canvas") {
1990
- const canvasId2 = ctx.generateId("Canvas", annotation);
1991
- fullAnnotation.target = canvasId2;
1992
- const pageId = ctx.generateId("Page", annotation);
1993
- const annotationPage2 = ctx.embed({
1994
- id: pageId,
1995
- type: "AnnotationPage",
1996
- items: [fullAnnotation]
1997
- });
1998
- return ctx.embed({
1999
- id: canvasId2,
2000
- type: "Canvas",
2001
- width: ~~target.selector.spatial.width,
2002
- height: ~~target.selector.spatial.height,
2003
- thumbnail: thumbnailId ? [
2004
+ if (selector?.type === "BoxSelector") {
2005
+ const imageApiSelector = {
2006
+ "@context": "http://iiif.io/api/annex/openannotation/context.json",
2007
+ type: "iiif:ImageApiSelector",
2008
+ region: [
2009
+ ~~selector.spatial.x,
2010
+ ~~selector.spatial.y,
2011
+ ~~selector.spatial.width,
2012
+ ~~selector.spatial.height
2013
+ ].join(",")
2014
+ };
2015
+ const newBody = { ...fullAnnotation.body };
2016
+ let thumbnailId = "";
2017
+ if (service) {
2018
+ const id = service.id || service["@id"] || "";
2019
+ if (id) {
2020
+ newBody.id = croppedRegion(id, selector.spatial, "max");
2021
+ thumbnailId = croppedRegion(id, selector.spatial, "512,");
2022
+ }
2023
+ }
2024
+ fullAnnotation.body = {
2025
+ id: ctx.generateId("SpecificResource", annotation),
2026
+ type: "SpecificResource",
2027
+ source: newBody,
2028
+ selector: imageApiSelector
2029
+ };
2030
+ if (data.trackSize) {
2031
+ data.trackSize({
2032
+ width: ~~selector.spatial.width,
2033
+ height: ~~selector.spatial.height
2034
+ });
2035
+ }
2036
+ if (targetType === "ContentResource") {
2037
+ returnResources.push(fullAnnotation.body);
2038
+ continue;
2039
+ }
2040
+ if (targetType === "Canvas") {
2041
+ const canvasId2 = ctx.generateId("Canvas", annotation);
2042
+ fullAnnotation.target = canvasId2;
2043
+ const pageId = ctx.generateId("Page", annotation);
2044
+ const annotationPage2 = ctx.embed({
2045
+ id: pageId,
2046
+ type: "AnnotationPage",
2047
+ items: [fullAnnotation]
2048
+ });
2049
+ returnResources.push(
2004
2050
  ctx.embed({
2005
- id: thumbnailId,
2006
- type: "Image",
2007
- format: "image/jpeg",
2008
- width: 512,
2009
- height: Math.round(
2010
- target.selector.spatial.height / target.selector.spatial.width * 512
2011
- )
2051
+ id: canvasId2,
2052
+ type: "Canvas",
2053
+ label: { en: ["Untitled canvas"] },
2054
+ width: ~~selector.spatial.width,
2055
+ height: ~~selector.spatial.height,
2056
+ thumbnail: thumbnailId ? [
2057
+ ctx.embed({
2058
+ id: thumbnailId,
2059
+ type: "Image",
2060
+ format: "image/jpeg",
2061
+ width: 512,
2062
+ height: Math.round(selector.spatial.height / selector.spatial.width * 512)
2063
+ })
2064
+ ] : void 0,
2065
+ items: [annotationPage2]
2012
2066
  })
2013
- ] : void 0,
2014
- items: [annotationPage2]
2015
- });
2067
+ );
2068
+ continue;
2069
+ }
2070
+ returnResources.push(
2071
+ ctx.embed({
2072
+ ...fullAnnotation,
2073
+ target: ctx.getTarget()
2074
+ })
2075
+ );
2076
+ continue;
2016
2077
  }
2017
- return ctx.embed({
2018
- ...fullAnnotation,
2019
- target: ctx.getTarget()
2020
- });
2078
+ returnResources.push(
2079
+ ctx.embed({
2080
+ ...previewVault.toPresentation3(annotation),
2081
+ target: ctx.getTarget()
2082
+ })
2083
+ );
2021
2084
  }
2022
- return ctx.embed({
2023
- ...previewVault.toPresentation3(annotation),
2024
- target: ctx.getTarget()
2025
- });
2026
2085
  }
2027
2086
  }
2028
2087
  }
2029
- throw new Error("Not yet supported.");
2088
+ return returnResources;
2030
2089
  }
2031
- var IIIFBrowserCreatorForm2 = (0, import_react8.lazy)(
2032
- () => Promise.resolve().then(() => (init_iiif_browser_form_lazy(), iiif_browser_form_lazy_exports))
2033
- );
2090
+ var IIIFBrowserCreatorForm2 = (0, import_react9.lazy)(() => Promise.resolve().then(() => (init_iiif_browser_form_lazy(), iiif_browser_form_lazy_exports)));
2034
2091
 
2035
2092
  // src/ContentResource/IIIFBrowserCreator/index.tsx
2036
- var import_jsx_runtime28 = require("react/jsx-runtime");
2037
- var iiifBrowserCreator = {
2093
+ var import_jsx_runtime30 = require("react/jsx-runtime");
2094
+ var iiifBrowserCreator = (0, import_creator_api17.defineCreator)({
2038
2095
  id: "@manifest-editor/iiif-browser-creator",
2039
2096
  create: createFromIIIFBrowserOutput,
2040
2097
  label: "IIIF Browser",
2041
2098
  summary: "Browse IIIF Resources",
2042
- icon: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_components11.IIIFBrowserIcon, {}),
2099
+ icon: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_components18.IIIFBrowserIcon, {}),
2043
2100
  render(ctx) {
2044
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(IIIFBrowserCreatorForm2, { ...ctx });
2101
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(IIIFBrowserCreatorForm2, { ...ctx });
2045
2102
  },
2046
2103
  hiddenModal: true,
2047
2104
  tags: ["image", "image-service"],
@@ -2050,49 +2107,49 @@ var iiifBrowserCreator = {
2050
2107
  additionalTypes: ["Annotation", "Canvas"],
2051
2108
  supports: {
2052
2109
  parentTypes: ["Annotation", "Manifest", "AnnotationPage"],
2110
+ parentFields: ["body", "items"],
2053
2111
  parentFieldMap: {
2054
2112
  Annotation: ["body"],
2055
2113
  Manifest: ["items"],
2056
2114
  AnnotationPage: ["items"]
2057
2115
  }
2058
2116
  },
2059
- sideEffects: [
2060
- resizeToFitService,
2061
- resizeResourceToEmptyCanvas,
2062
- repositionMultipleImages
2063
- ],
2117
+ sideEffects: [resizeToFitService, resizeResourceToEmptyCanvas, repositionMultipleImages],
2064
2118
  staticFields: {}
2065
- };
2119
+ });
2066
2120
 
2067
2121
  // src/ContentResource/ImageServiceCreator/index.tsx
2068
- var import_jsx_runtime29 = require("react/jsx-runtime");
2069
- var imageServiceCreator = {
2122
+ var import_components19 = require("@manifest-editor/components");
2123
+ var import_creator_api18 = require("@manifest-editor/creator-api");
2124
+ var import_jsx_runtime31 = require("react/jsx-runtime");
2125
+ var imageServiceCreator = (0, import_creator_api18.defineCreator)({
2070
2126
  id: "@manifest-editor/image-service-creator",
2071
2127
  create: createImageServer,
2072
2128
  label: "Image Service",
2073
2129
  summary: "Add an image from Image Service",
2074
- icon: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TextFormatIcon, {}),
2130
+ icon: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_components19.IIIFLogo, { style: { padding: 10 } }),
2075
2131
  render(ctx) {
2076
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(CreateImageServerForm, { ...ctx });
2132
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(CreateImageServerForm, { ...ctx });
2077
2133
  },
2078
2134
  resourceType: "ContentResource",
2079
2135
  resourceFields: ["id", "type", "height", "width", "format", "service"],
2080
2136
  supports: {
2081
2137
  parentFields: ["logo", "body", "thumbnail"]
2082
2138
  }
2083
- };
2139
+ });
2084
2140
 
2085
2141
  // src/ContentResource/ImageUrlCreator/index.tsx
2086
- var import_components12 = require("@manifest-editor/components");
2087
- var import_jsx_runtime30 = require("react/jsx-runtime");
2088
- var imageUrlCreator = {
2142
+ var import_components20 = require("@manifest-editor/components");
2143
+ var import_creator_api19 = require("@manifest-editor/creator-api");
2144
+ var import_jsx_runtime32 = require("react/jsx-runtime");
2145
+ var imageUrlCreator = (0, import_creator_api19.defineCreator)({
2089
2146
  id: "@manifest-editor/image-url-creator",
2090
2147
  create: createImageUrl,
2091
2148
  label: "Image",
2092
2149
  summary: "Image from a URL",
2093
- icon: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_components12.AddImageIcon, {}),
2150
+ icon: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_components20.AddImageIcon, {}),
2094
2151
  render(ctx) {
2095
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(CreateImageUrlForm, { ...ctx });
2152
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(CreateImageUrlForm, { ...ctx });
2096
2153
  },
2097
2154
  resourceType: "ContentResource",
2098
2155
  resourceFields: ["format"],
@@ -2102,12 +2159,39 @@ var imageUrlCreator = {
2102
2159
  staticFields: {
2103
2160
  type: "Image"
2104
2161
  }
2105
- };
2162
+ });
2163
+
2164
+ // src/ContentResource/ImageUrlListCreator/index.tsx
2165
+ var import_components21 = require("@manifest-editor/components");
2166
+ var import_creator_api20 = require("@manifest-editor/creator-api");
2167
+ var import_jsx_runtime33 = require("react/jsx-runtime");
2168
+ var imageUrlListCreator = (0, import_creator_api20.defineCreator)({
2169
+ id: "@manifest-editor/image-url-list",
2170
+ label: "Image URL List",
2171
+ summary: "Image from a list of URLs",
2172
+ create: createImageUrlList,
2173
+ icon: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_components21.ImageListIcon, {}),
2174
+ render(ctx) {
2175
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CreateImageUrlListForm, { ...ctx });
2176
+ },
2177
+ resourceType: "ContentResource",
2178
+ resourceFields: ["format"],
2179
+ supports: {
2180
+ parentFields: ["logo", "body", "thumbnail"]
2181
+ },
2182
+ staticFields: {
2183
+ type: "Image"
2184
+ }
2185
+ });
2186
+
2187
+ // src/ContentResource/PlaintextCreator/index.tsx
2188
+ var import_creator_api21 = require("@manifest-editor/creator-api");
2106
2189
 
2107
2190
  // src/ContentResource/PlaintextCreator/create-plaintext.tsx
2191
+ var import_components22 = require("@manifest-editor/components");
2108
2192
  var import_editors9 = require("@manifest-editor/editors");
2109
- var import_react9 = require("react");
2110
- var import_jsx_runtime31 = require("react/jsx-runtime");
2193
+ var import_react10 = require("react");
2194
+ var import_jsx_runtime34 = require("react/jsx-runtime");
2111
2195
  async function createPlaintext(data, ctx) {
2112
2196
  return ctx.embed({
2113
2197
  id: data.url,
@@ -2117,7 +2201,7 @@ async function createPlaintext(data, ctx) {
2117
2201
  });
2118
2202
  }
2119
2203
  function CreatePlaintextForm(props) {
2120
- const [label, setLabel] = (0, import_react9.useState)({
2204
+ const [label, setLabel] = (0, import_react10.useState)({
2121
2205
  en: ["View as text"]
2122
2206
  });
2123
2207
  const onSubmit = (e) => {
@@ -2128,8 +2212,8 @@ function CreatePlaintextForm(props) {
2128
2212
  props.runCreate({ url: formData.url, label });
2129
2213
  }
2130
2214
  };
2131
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("form", { onSubmit, children: [
2132
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2215
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("form", { onSubmit, children: [
2216
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2133
2217
  import_editors9.LanguageFieldEditor,
2134
2218
  {
2135
2219
  focusId: "label",
@@ -2138,24 +2222,24 @@ function CreatePlaintextForm(props) {
2138
2222
  onSave: (e) => setLabel(e.toInternationalString())
2139
2223
  }
2140
2224
  ),
2141
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_editors9.InputContainer, { $wide: true, children: [
2142
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_editors9.InputLabel, { htmlFor: "id", children: "Link to plaintext" }),
2143
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_editors9.Input, { id: "url", name: "url", defaultValue: "" })
2225
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_editors9.InputContainer, { $wide: true, children: [
2226
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_editors9.InputLabel, { htmlFor: "id", children: "Link to plaintext" }),
2227
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_editors9.Input, { id: "url", name: "url", defaultValue: "" })
2144
2228
  ] }),
2145
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Button, { type: "submit", children: "Create" })
2229
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_components22.ActionButton, { primary: true, large: true, type: "submit", children: "Create" })
2146
2230
  ] }) });
2147
2231
  }
2148
2232
 
2149
2233
  // src/ContentResource/PlaintextCreator/index.tsx
2150
- var import_jsx_runtime32 = require("react/jsx-runtime");
2151
- var plaintextCreator = {
2234
+ var import_jsx_runtime35 = require("react/jsx-runtime");
2235
+ var plaintextCreator = (0, import_creator_api21.defineCreator)({
2152
2236
  id: "@manifest-editor/plaintext-creator",
2153
2237
  create: createPlaintext,
2154
2238
  label: "Plaintext",
2155
2239
  summary: "Add link to an plaintext",
2156
- icon: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TextFormatIcon, {}),
2240
+ icon: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(TextFormatIcon, {}),
2157
2241
  render(ctx) {
2158
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(CreatePlaintextForm, { ...ctx });
2242
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(CreatePlaintextForm, { ...ctx });
2159
2243
  },
2160
2244
  resourceType: "ContentResource",
2161
2245
  resourceFields: ["label", "format"],
@@ -2165,21 +2249,223 @@ var plaintextCreator = {
2165
2249
  staticFields: {
2166
2250
  format: "text/plain"
2167
2251
  }
2168
- };
2252
+ });
2253
+
2254
+ // src/ContentResource/ThumbnailCreator/index.tsx
2255
+ var import_components24 = require("@manifest-editor/components");
2256
+ var import_creator_api22 = require("@manifest-editor/creator-api");
2257
+
2258
+ // src/ContentResource/ThumbnailCreator/create-thumbnail.tsx
2259
+ var import_components23 = require("@manifest-editor/components");
2260
+ var import_editors10 = require("@manifest-editor/editors");
2261
+ var import_react11 = require("react");
2262
+
2263
+ // src/ContentResource/ThumbnailCreator/thumbnail-helpers.ts
2264
+ var import_image_34 = require("@iiif/parser/image-3");
2265
+ function serviceImageAtSize(service, size) {
2266
+ if (service["@id"]) {
2267
+ service.id = service["@id"];
2268
+ }
2269
+ if (service["@type"]) {
2270
+ service.type = service["@type"];
2271
+ }
2272
+ const request = (0, import_image_34.createImageServiceRequest)(service);
2273
+ return (0, import_image_34.imageServiceRequestToString)({
2274
+ identifier: request.identifier,
2275
+ server: request.server,
2276
+ scheme: request.scheme,
2277
+ type: "image",
2278
+ size: {
2279
+ max: false,
2280
+ confined: false,
2281
+ upscaled: false,
2282
+ width: size.width,
2283
+ height: size.height
2284
+ },
2285
+ format: "jpg",
2286
+ // This isn't how it should be modelled, always full,
2287
+ // region: data.selector ? data.selector : { full: true },
2288
+ region: { full: true },
2289
+ rotation: { angle: 0 },
2290
+ quality: "default",
2291
+ prefix: request.prefix,
2292
+ originalPath: request.originalPath
2293
+ });
2294
+ }
2295
+ function getCanonicalUrl2(url) {
2296
+ return url.endsWith("default.jpg") ? (0, import_image_34.imageServiceRequestToString)({
2297
+ ...(0, import_image_34.parseImageServiceRequest)(url),
2298
+ type: "info"
2299
+ }) : (0, import_image_34.canonicalServiceUrl)(url);
2300
+ }
2301
+
2302
+ // src/ContentResource/ThumbnailCreator/create-thumbnail.tsx
2303
+ var import_jsx_runtime36 = require("react/jsx-runtime");
2304
+ async function createThumbnail(data, ctx) {
2305
+ const service = { ...data.service };
2306
+ const sizes = service.sizes;
2307
+ if (service["@id"]) {
2308
+ service.id = service["@id"];
2309
+ }
2310
+ if (service["@type"]) {
2311
+ service.type = service["@type"];
2312
+ }
2313
+ if (data.thumbnailUrl) {
2314
+ return ctx.embed({
2315
+ id: data.thumbnailUrl,
2316
+ type: "Image",
2317
+ format: "image/jpeg",
2318
+ width: data.width,
2319
+ height: data.height
2320
+ });
2321
+ }
2322
+ if (sizes) {
2323
+ const thumbnailSize = data.width || 400;
2324
+ let bestMatch = null;
2325
+ for (const size of sizes) {
2326
+ if (!bestMatch || Math.abs(size.width - thumbnailSize) < Math.abs(bestMatch.width - thumbnailSize)) {
2327
+ bestMatch = { width: size.width, height: size.height };
2328
+ }
2329
+ }
2330
+ if (bestMatch) {
2331
+ const imageId = serviceImageAtSize(service, bestMatch);
2332
+ return ctx.embed({
2333
+ id: imageId,
2334
+ type: "Image",
2335
+ format: "image/jpeg",
2336
+ width: bestMatch.width,
2337
+ height: bestMatch.height
2338
+ });
2339
+ }
2340
+ }
2341
+ return null;
2342
+ }
2343
+ function CreateThumbnailForm(props) {
2344
+ const [url, setUrl] = (0, import_react11.useState)("");
2345
+ const [service, setService] = (0, import_react11.useState)(null);
2346
+ const [selectedSize, setSelectedSize] = (0, import_react11.useState)({ width: 0, height: 0 });
2347
+ const previewUrl = (0, import_react11.useMemo)(() => {
2348
+ if (!service)
2349
+ return null;
2350
+ if (!selectedSize.width || !selectedSize.height)
2351
+ return null;
2352
+ return serviceImageAtSize(service, selectedSize);
2353
+ }, [selectedSize, service]);
2354
+ const onSubmit = (e) => {
2355
+ e.preventDefault();
2356
+ const data = new FormData(e.target);
2357
+ const formData = Object.fromEntries(data.entries());
2358
+ const url2 = formData.url;
2359
+ if (url2) {
2360
+ const info = getCanonicalUrl2(url2);
2361
+ if (!info) {
2362
+ throw new Error("Invalid image service request");
2363
+ }
2364
+ fetch(info).then((r) => r.json()).then((service2) => {
2365
+ setService(service2);
2366
+ const size0 = service2.sizes?.[0];
2367
+ if (size0) {
2368
+ setSelectedSize(size0);
2369
+ }
2370
+ });
2371
+ }
2372
+ };
2373
+ if (service) {
2374
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(PaddedSidebarContainer, { children: [
2375
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "mb-4", children: [
2376
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mb-2", children: service["@id"] || service.id }),
2377
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex gap-2 mb-4", children: service.sizes?.map((size) => {
2378
+ const isSelected = size.width === selectedSize.width;
2379
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
2380
+ import_components23.ActionButton,
2381
+ {
2382
+ primary: isSelected,
2383
+ isDisabled: isSelected,
2384
+ large: true,
2385
+ onPress: () => setSelectedSize(size),
2386
+ children: [
2387
+ size.width,
2388
+ "x",
2389
+ size.height
2390
+ ]
2391
+ },
2392
+ size.width
2393
+ );
2394
+ }) }),
2395
+ previewUrl ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("img", { src: previewUrl, alt: "preview of selected resource" }) : null
2396
+ ] }),
2397
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2398
+ import_components23.ActionButton,
2399
+ {
2400
+ primary: true,
2401
+ large: true,
2402
+ isDisabled: !previewUrl,
2403
+ onPress: () => {
2404
+ if (!service)
2405
+ return;
2406
+ props.runCreate({ service, width: selectedSize.width, height: selectedSize.height });
2407
+ },
2408
+ children: "Add thumbnail"
2409
+ }
2410
+ )
2411
+ ] });
2412
+ }
2413
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("form", { onSubmit, children: [
2414
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex gap-2 items-center", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_editors10.InputContainer, { $wide: true, children: [
2415
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_editors10.InputLabel, { htmlFor: "id", children: "Link to image service" }),
2416
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2417
+ import_editors10.Input,
2418
+ {
2419
+ id: "url",
2420
+ name: "url",
2421
+ defaultValue: "",
2422
+ onPaste: (e) => {
2423
+ const text = e.clipboardData.getData("text/plain");
2424
+ setUrl(text ? getCanonicalUrl2(text) : "");
2425
+ },
2426
+ onBlur: (e) => setUrl(e.currentTarget.value ? getCanonicalUrl2(e.currentTarget.value) : "")
2427
+ }
2428
+ )
2429
+ ] }) }),
2430
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_components23.ActionButton, { primary: true, large: true, type: "submit", isDisabled: !url, children: "Select size" }) })
2431
+ ] }) });
2432
+ }
2433
+
2434
+ // src/ContentResource/ThumbnailCreator/index.tsx
2435
+ var import_jsx_runtime37 = require("react/jsx-runtime");
2436
+ var thumbnailCreator = (0, import_creator_api22.defineCreator)({
2437
+ id: "@manifest-editor/thumbnail-image",
2438
+ create: createThumbnail,
2439
+ label: "Thumbnail from service",
2440
+ summary: "Add thumbnail from an image service",
2441
+ icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_components24.ScaledImageIcon, {}),
2442
+ render(ctx) {
2443
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(CreateThumbnailForm, { ...ctx });
2444
+ },
2445
+ resourceType: "ContentResource",
2446
+ resourceFields: ["id", "type", "format"],
2447
+ supports: {
2448
+ parentFields: ["thumbnail"]
2449
+ }
2450
+ });
2451
+
2452
+ // src/ContentResource/WebPageCreator/index.tsx
2453
+ var import_creator_api23 = require("@manifest-editor/creator-api");
2169
2454
 
2170
2455
  // ../ui/icons/LinkIcon.tsx
2171
- var import_jsx_runtime33 = require("react/jsx-runtime");
2456
+ var import_jsx_runtime38 = require("react/jsx-runtime");
2172
2457
  function LinkIcon() {
2173
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", height: "24px", viewBox: "0 0 24 24", width: "24px", fill: "#000000", children: [
2174
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
2175
- /* @__PURE__ */ (0, import_jsx_runtime33.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" })
2458
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", height: "24px", viewBox: "0 0 24 24", width: "24px", fill: "#000000", children: [
2459
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
2460
+ /* @__PURE__ */ (0, import_jsx_runtime38.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" })
2176
2461
  ] });
2177
2462
  }
2178
2463
 
2179
2464
  // src/ContentResource/WebPageCreator/create-web-page.tsx
2180
- var import_editors10 = require("@manifest-editor/editors");
2181
- var import_react10 = require("react");
2182
- var import_jsx_runtime34 = require("react/jsx-runtime");
2465
+ var import_components25 = require("@manifest-editor/components");
2466
+ var import_editors11 = require("@manifest-editor/editors");
2467
+ var import_react12 = require("react");
2468
+ var import_jsx_runtime39 = require("react/jsx-runtime");
2183
2469
  async function createWebPage(data, ctx) {
2184
2470
  return ctx.embed({
2185
2471
  id: data.url,
@@ -2189,7 +2475,7 @@ async function createWebPage(data, ctx) {
2189
2475
  });
2190
2476
  }
2191
2477
  function CreateWebPageForm(props) {
2192
- const [label, setLabel] = (0, import_react10.useState)({ en: [""] });
2478
+ const [label, setLabel] = (0, import_react12.useState)({ en: [""] });
2193
2479
  const onSubmit = (e) => {
2194
2480
  e.preventDefault();
2195
2481
  const data = new FormData(e.target);
@@ -2198,9 +2484,9 @@ function CreateWebPageForm(props) {
2198
2484
  props.runCreate({ url: formData.url, label });
2199
2485
  }
2200
2486
  };
2201
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("form", { onSubmit, children: [
2202
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2203
- import_editors10.LanguageFieldEditor,
2487
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("form", { onSubmit, children: [
2488
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2489
+ import_editors11.LanguageFieldEditor,
2204
2490
  {
2205
2491
  focusId: "label",
2206
2492
  label: "Label",
@@ -2208,38 +2494,40 @@ function CreateWebPageForm(props) {
2208
2494
  onSave: (e) => setLabel(e.toInternationalString())
2209
2495
  }
2210
2496
  ),
2211
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_editors10.InputContainer, { $wide: true, children: [
2212
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_editors10.InputLabel, { htmlFor: "id", children: "Link" }),
2213
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_editors10.Input, { id: "url", name: "url", defaultValue: "" })
2497
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_editors11.InputContainer, { $wide: true, children: [
2498
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_editors11.InputLabel, { htmlFor: "id", children: "Link" }),
2499
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_editors11.Input, { id: "url", name: "url", defaultValue: "" })
2214
2500
  ] }),
2215
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Button, { type: "submit", children: "Create link" })
2501
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_components25.ActionButton, { primary: true, large: true, type: "submit", children: "Create link" })
2216
2502
  ] }) });
2217
2503
  }
2218
2504
 
2219
2505
  // src/ContentResource/WebPageCreator/index.tsx
2220
- var import_jsx_runtime35 = require("react/jsx-runtime");
2221
- var webPageCreator = {
2506
+ var import_jsx_runtime40 = require("react/jsx-runtime");
2507
+ var webPageCreator = (0, import_creator_api23.defineCreator)({
2222
2508
  id: "@manifest-editor/web-page-creator",
2223
2509
  create: createWebPage,
2224
2510
  label: "Web page",
2225
2511
  summary: "Add link to an external web page",
2226
- icon: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(LinkIcon, {}),
2512
+ icon: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(LinkIcon, {}),
2227
2513
  render(ctx) {
2228
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(CreateWebPageForm, { ...ctx });
2514
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(CreateWebPageForm, { ...ctx });
2229
2515
  },
2230
2516
  resourceType: "ContentResource",
2231
2517
  resourceFields: ["label", "format"],
2232
2518
  supports: {
2233
2519
  parentFields: ["seeAlso", "rendering", "homepage"]
2234
2520
  }
2235
- };
2521
+ });
2236
2522
 
2237
2523
  // src/ContentResource/YouTubeCreator/index.tsx
2238
- var import_components13 = require("@manifest-editor/components");
2524
+ var import_components27 = require("@manifest-editor/components");
2525
+ var import_creator_api24 = require("@manifest-editor/creator-api");
2239
2526
 
2240
2527
  // src/ContentResource/YouTubeCreator/create-youtube-body.tsx
2241
- var import_editors11 = require("@manifest-editor/editors");
2242
- var import_jsx_runtime36 = require("react/jsx-runtime");
2528
+ var import_components26 = require("@manifest-editor/components");
2529
+ var import_editors12 = require("@manifest-editor/editors");
2530
+ var import_jsx_runtime41 = require("react/jsx-runtime");
2243
2531
  var ytRegex = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/|shorts\/)|(?:(?:watch)?\?vi?=|&vi?=))([^#&?]*).*/;
2244
2532
  function getYouTubeId(url) {
2245
2533
  const id = (url || "").match(ytRegex);
@@ -2317,27 +2605,27 @@ function YouTubeForm(props) {
2317
2605
  props.runCreate({ youtubeUrl: formData.youtubeUrl });
2318
2606
  }
2319
2607
  };
2320
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("form", { onSubmit, children: [
2321
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_editors11.InputContainer, { $wide: true, children: [
2322
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_editors11.InputLabel, { htmlFor: "id", children: "Link to YouTube" }),
2323
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_editors11.Input, { id: "youtubeUrl", name: "youtubeUrl", defaultValue: "" })
2608
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("form", { onSubmit, children: [
2609
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_editors12.InputContainer, { $wide: true, children: [
2610
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_editors12.InputLabel, { htmlFor: "id", children: "Link to YouTube" }),
2611
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_editors12.Input, { id: "youtubeUrl", name: "youtubeUrl", defaultValue: "" })
2324
2612
  ] }),
2325
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Button, { type: "submit", children: "Create" })
2613
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_components26.ActionButton, { primary: true, large: true, type: "submit", children: "Create" })
2326
2614
  ] }) });
2327
2615
  }
2328
2616
 
2329
2617
  // src/ContentResource/YouTubeCreator/index.tsx
2330
- var import_jsx_runtime37 = require("react/jsx-runtime");
2331
- var youTubeBodyCreator = {
2618
+ var import_jsx_runtime42 = require("react/jsx-runtime");
2619
+ var youTubeBodyCreator = (0, import_creator_api24.defineCreator)({
2332
2620
  id: "@manifest-editor/youtube",
2333
2621
  create: createYoutubeBody,
2334
2622
  label: "YouTube",
2335
2623
  summary: "Embed YouTube",
2336
- icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_components13.YouTubeIcon, {}),
2624
+ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_components27.YouTubeIcon, {}),
2337
2625
  resourceType: "ContentResource",
2338
2626
  additionalTypes: ["Canvas", "Annotation"],
2339
2627
  resourceFields: ["id", "type", "service"],
2340
- render: (ctx) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(YouTubeForm, { ...ctx }),
2628
+ render: (ctx) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(YouTubeForm, { ...ctx }),
2341
2629
  supports: {
2342
2630
  parentTypes: ["Annotation", "Manifest", "AnnotationPage"],
2343
2631
  parentFieldMap: {
@@ -2349,41 +2637,53 @@ var youTubeBodyCreator = {
2349
2637
  staticFields: {
2350
2638
  type: "Video"
2351
2639
  }
2352
- };
2640
+ });
2353
2641
 
2354
2642
  // src/Manifest/ManifestBrowserCreator/index.tsx
2355
- var import_components14 = require("@manifest-editor/components");
2643
+ var import_components28 = require("@manifest-editor/components");
2644
+ var import_creator_api25 = require("@manifest-editor/creator-api");
2356
2645
 
2357
2646
  // src/Manifest/ManifestBrowserCreator/manifest-browser-creator.tsx
2358
- var import_helpers5 = require("@iiif/helpers");
2359
- var import_react11 = require("react");
2647
+ var import_helpers7 = require("@iiif/helpers");
2648
+ var import_react14 = require("react");
2360
2649
  async function createFromManifestBrowserOutput(data, ctx) {
2361
2650
  const targetType = ctx.options.targetType;
2362
2651
  if (Array.isArray(data.output)) {
2363
2652
  throw new Error("Multiple items not yet supported");
2364
2653
  }
2365
- const contentState = (0, import_helpers5.normaliseContentState)(
2366
- typeof data.output === "string" ? (0, import_helpers5.parseContentState)(data.output) : data.output
2654
+ const contentState = (0, import_helpers7.normaliseContentState)(
2655
+ typeof data.output === "string" ? (0, import_helpers7.parseContentState)(data.output) : data.output
2367
2656
  );
2368
2657
  const target = contentState.target[0];
2369
2658
  const previewVault = ctx.getPreviewVault();
2659
+ const thumbnails = (0, import_helpers7.createThumbnailHelper)(previewVault);
2370
2660
  if (!target) {
2371
2661
  throw new Error("No target found in content state");
2372
2662
  }
2373
2663
  if (targetType === "Manifest") {
2374
2664
  const manifestId = target.source.id;
2375
2665
  invariant(manifestId, "Could not find Manifest ID");
2376
- const manifest = await previewVault.get(manifestId);
2666
+ const manifest = await previewVault.loadManifest(manifestId);
2667
+ const thumbnail = await thumbnails.getBestThumbnailAtSize(manifest, { width: 256, height: 256 }, false);
2668
+ invariant(manifest, "Manifest not found");
2377
2669
  return ctx.embed({
2378
2670
  id: target.source.id,
2379
2671
  type: "Manifest",
2380
- label: manifest.label
2672
+ label: manifest.label,
2673
+ summary: manifest.summary,
2674
+ thumbnail: thumbnail?.best ? [
2675
+ {
2676
+ id: thumbnail.best.id,
2677
+ type: "Image"
2678
+ }
2679
+ ] : void 0
2381
2680
  });
2382
2681
  }
2383
2682
  if (targetType === "Collection") {
2384
2683
  const collectionId = target.source.id;
2385
2684
  invariant(collectionId, "Could not find Manifest ID");
2386
- const collection = await previewVault.get(collectionId);
2685
+ const collection = await previewVault.loadManifest(collectionId);
2686
+ invariant(collection, "Collection not found");
2387
2687
  return ctx.embed({
2388
2688
  id: target.source.id,
2389
2689
  type: "Collection",
@@ -2392,21 +2692,19 @@ async function createFromManifestBrowserOutput(data, ctx) {
2392
2692
  }
2393
2693
  throw new Error("Not yet supported.");
2394
2694
  }
2395
- var ManifestBrowserCreatorForm2 = (0, import_react11.lazy)(
2396
- () => Promise.resolve().then(() => (init_manifest_browser_form_lazy(), manifest_browser_form_lazy_exports))
2397
- );
2695
+ var ManifestBrowserCreatorForm2 = (0, import_react14.lazy)(() => Promise.resolve().then(() => (init_manifest_browser_form_lazy(), manifest_browser_form_lazy_exports)));
2398
2696
 
2399
2697
  // src/Manifest/ManifestBrowserCreator/index.tsx
2400
2698
  init_manifest_browser_form_lazy();
2401
- var import_jsx_runtime39 = require("react/jsx-runtime");
2402
- var manifestBrowserCreator = {
2699
+ var import_jsx_runtime44 = require("react/jsx-runtime");
2700
+ var manifestBrowserCreator = (0, import_creator_api25.defineCreator)({
2403
2701
  id: "@manifest-editor/manifest-browser-creator",
2404
2702
  create: createFromManifestBrowserOutput,
2405
2703
  label: "IIIF Browser",
2406
2704
  summary: "Browse IIIF Resources",
2407
- icon: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_components14.IIIFBrowserIcon, {}),
2705
+ icon: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_components28.IIIFBrowserIcon, {}),
2408
2706
  render(ctx) {
2409
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ManifestBrowserCreatorForm, { ...ctx });
2707
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ManifestBrowserCreatorForm, { ...ctx });
2410
2708
  },
2411
2709
  resourceType: "Manifest",
2412
2710
  resourceFields: ["id", "label"],
@@ -2419,7 +2717,7 @@ var manifestBrowserCreator = {
2419
2717
  },
2420
2718
  sideEffects: [],
2421
2719
  staticFields: {}
2422
- };
2720
+ });
2423
2721
 
2424
2722
  // src/index.ts
2425
2723
  var allCreators = [
@@ -2440,5 +2738,8 @@ var allCreators = [
2440
2738
  emptyAnnotationPage,
2441
2739
  noBodyAnnotation,
2442
2740
  internalCanvas,
2443
- captionedImageAnnotation
2741
+ captionedImageAnnotation,
2742
+ imageUrlListCreator,
2743
+ imageUrlListAnnotation,
2744
+ thumbnailCreator
2444
2745
  ];