cozy-iiif 0.2.7 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -134,6 +134,13 @@ console.log(image.getRegionURL(bounds));
134
134
 
135
135
  // With custom minimum shorted dimension
136
136
  console.log(image.getRegionURL(bounds, 800));
137
+
138
+ // Full image with custom minimum shorted dimension
139
+ console.log(image.getImageURL(800));
140
+
141
+ // Resolves the actual image pixel size from the info.json
142
+ // or the image file (which may **differ**) from the canvas size!
143
+ console.log(image.getPixelSize());
137
144
  ```
138
145
 
139
146
  ## Cozy Helpers
@@ -1,6 +1,5 @@
1
1
  import { Canvas } from '@iiif/presentation-3';
2
2
  import { CozyImageResource } from '../types';
3
3
  export declare const getThumbnailURL: (canvas: Canvas, images?: CozyImageResource[]) => (minSize?: number) => string | undefined;
4
- export declare const getImageURL: (canvas: Canvas, images?: CozyImageResource[]) => (minSize?: number) => string | undefined;
5
4
  export declare const normalizeServiceUrl: (url: string) => string;
6
5
  export declare const getImages: (canvas: Canvas) => CozyImageResource[];
@@ -6,7 +6,7 @@ export declare const parseImageService: (service: Service) => {
6
6
  majorVersion: number;
7
7
  profileLevel: number;
8
8
  } | undefined;
9
- export declare const getImageURLFromService: (service: ImageService2 | ImageService3, width: number, height: number) => string;
10
- export declare const getRegionURLFromService: (service: ImageService2 | ImageService3, bounds: Bounds, minSize: number) => string | undefined;
9
+ export declare const getImageURLFromService: (service: Service, width: number, height: number) => string;
10
+ export declare const getRegionURLFromService: (service: Service, bounds: Bounds, minSize: number) => string | undefined;
11
11
  export declare const getRegionURL: (image: CozyImageResource) => (bounds: Bounds, minSize?: number) => string | undefined;
12
12
  export {};
package/dist/index.js CHANGED
@@ -1,15 +1,16 @@
1
- import { g as m, a as j, b as S } from "./resource-DS2brz47.js";
2
- import { c as Wt } from "./resource-DS2brz47.js";
3
- var ce = "http://library.stanford.edu/iiif/image-api/compliance.html#level0", le = "http://library.stanford.edu/iiif/image-api/compliance.html#level1", F = "http://library.stanford.edu/iiif/image-api/compliance.html#level2", pe = "http://library.stanford.edu/iiif/image-api/conformance.html#level0", ve = "http://library.stanford.edu/iiif/image-api/conformance.html#level1", W = "http://library.stanford.edu/iiif/image-api/conformance.html#level2", he = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0", ue = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level1", B = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2", fe = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level0", me = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level1", H = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level2", ge = "http://iiif.io/api/image/1/level0.json", de = "http://iiif.io/api/image/1/profiles/level0.json", ye = "http://iiif.io/api/image/1/level1.json", Ae = "http://iiif.io/api/image/1/profiles/level1.json", J = "http://iiif.io/api/image/1/level2.json", G = "http://iiif.io/api/image/1/profiles/level2.json", Ce = "http://iiif.io/api/image/2/level0.json", be = "http://iiif.io/api/image/2/profiles/level0.json", Re = "http://iiif.io/api/image/2/level1.json", Le = "http://iiif.io/api/image/2/profiles/level1.json", K = "http://iiif.io/api/image/2/level2.json", Q = "http://iiif.io/api/image/2/profiles/level2.json", we = "level0", Ie = "level1", X = "level2", Se = "http://iiif.io/api/image/2/level0", Te = "http://iiif.io/api/image/2/level1", Y = "http://iiif.io/api/image/2/level2", xe = [Y, F, W, B, H, J, G, K, Q, X], $e = [Se, Te, Y, ce, le, F, pe, ve, W, he, ue, B, fe, me, H, ge, de, ye, Ae, J, G, Ce, be, Re, Le, K, Q, we, Ie, X], Me = $e;
4
- function g(t) {
1
+ import { imageSize as ce } from "image-size";
2
+ import { g, a as j, b as S } from "./resource-DS2brz47.js";
3
+ import { c as zt } from "./resource-DS2brz47.js";
4
+ var le = "http://library.stanford.edu/iiif/image-api/compliance.html#level0", pe = "http://library.stanford.edu/iiif/image-api/compliance.html#level1", V = "http://library.stanford.edu/iiif/image-api/compliance.html#level2", ve = "http://library.stanford.edu/iiif/image-api/conformance.html#level0", he = "http://library.stanford.edu/iiif/image-api/conformance.html#level1", F = "http://library.stanford.edu/iiif/image-api/conformance.html#level2", ue = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0", fe = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level1", W = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2", ge = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level0", me = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level1", H = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level2", de = "http://iiif.io/api/image/1/level0.json", ye = "http://iiif.io/api/image/1/profiles/level0.json", Ae = "http://iiif.io/api/image/1/level1.json", Ce = "http://iiif.io/api/image/1/profiles/level1.json", J = "http://iiif.io/api/image/1/level2.json", z = "http://iiif.io/api/image/1/profiles/level2.json", be = "http://iiif.io/api/image/2/level0.json", Re = "http://iiif.io/api/image/2/profiles/level0.json", Le = "http://iiif.io/api/image/2/level1.json", we = "http://iiif.io/api/image/2/profiles/level1.json", G = "http://iiif.io/api/image/2/level2.json", K = "http://iiif.io/api/image/2/profiles/level2.json", Ie = "level0", Se = "level1", Q = "level2", xe = "http://iiif.io/api/image/2/level0", Te = "http://iiif.io/api/image/2/level1", X = "http://iiif.io/api/image/2/level2", $e = [X, V, F, W, H, J, z, G, K, Q], Me = [xe, Te, X, le, pe, V, ve, he, F, ue, fe, W, ge, me, H, de, ye, Ae, Ce, J, z, be, Re, Le, we, G, K, Ie, Se, Q], je = Me;
5
+ function m(t) {
5
6
  for (let e in t) (typeof t[e] > "u" || t[e] === null) && delete t[e];
6
7
  return t;
7
8
  }
8
9
  function w(t) {
9
10
  return Array.isArray(t) ? t : t ? [t] : [];
10
11
  }
11
- var je = Object.defineProperty, ke = (t, e, r) => e in t ? je(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r, b = (t, e, r) => (ke(t, typeof e != "symbol" ? e + "" : e, r), r), N = ["sc:Collection", "sc:Manifest", "sc:Canvas", "sc:AnnotationList", "oa:Annotation", "sc:Range", "sc:Layer", "sc:Sequence", "oa:Choice", "Service", "ContentResource"];
12
- function Pe(t) {
12
+ var ke = Object.defineProperty, Pe = (t, e, r) => e in t ? ke(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r, b = (t, e, r) => (Pe(t, typeof e != "symbol" ? e + "" : e, r), r), N = ["sc:Collection", "sc:Manifest", "sc:Canvas", "sc:AnnotationList", "oa:Annotation", "sc:Range", "sc:Layer", "sc:Sequence", "oa:Choice", "Service", "ContentResource"];
13
+ function Oe(t) {
13
14
  if (typeof t > "u" || t === null) throw new Error("Null or undefined is not a valid entity.");
14
15
  if (Array.isArray(t)) throw new Error("Array is not a valid entity");
15
16
  if (typeof t != "object") throw new Error(`${typeof t} is not a valid entity`);
@@ -21,12 +22,12 @@ function Pe(t) {
21
22
  if (t.format || t["@type"]) return "ContentResource";
22
23
  throw new Error("Resource type is not known");
23
24
  }
24
- var Oe = class Z {
25
+ var Ue = class Y {
25
26
  constructor(e, r = {}) {
26
27
  b(this, "traversals"), b(this, "options"), this.traversals = { collection: [], manifest: [], canvas: [], annotationList: [], sequence: [], annotation: [], contentResource: [], choice: [], range: [], service: [], layer: [], ...e }, this.options = { convertPropsToArray: !0, mergeMemberProperties: !0, allowUndefinedReturn: !1, ...r };
27
28
  }
28
29
  static all(e) {
29
- return new Z({ collection: [e], manifest: [e], canvas: [e], annotationList: [e], sequence: [e], annotation: [e], contentResource: [e], choice: [e], range: [e], service: [e], layer: [e] });
30
+ return new Y({ collection: [e], manifest: [e], canvas: [e], annotationList: [e], sequence: [e], annotation: [e], contentResource: [e], choice: [e], range: [e], service: [e], layer: [e] });
30
31
  }
31
32
  traverseCollection(e) {
32
33
  return this.traverseType(this.traverseDescriptive(this.traverseLinking(this.traverseCollectionItems(e))), this.traversals.collection);
@@ -99,7 +100,7 @@ var Oe = class Z {
99
100
  }
100
101
  traverseUnknown(e) {
101
102
  if (!e["@type"] || typeof e == "string") return e;
102
- switch (Pe(e)) {
103
+ switch (Oe(e)) {
103
104
  case "sc:Collection":
104
105
  return this.traverseCollection(e);
105
106
  case "sc:Manifest":
@@ -152,8 +153,8 @@ var Oe = class Z {
152
153
  return typeof n > "u" && !this.options.allowUndefinedReturn ? i : n;
153
154
  }, e);
154
155
  }
155
- }, Ue = "http://library.stanford.edu/iiif/image-api/compliance.html#level1", De = "http://library.stanford.edu/iiif/image-api/compliance.html#level2", Ne = "http://library.stanford.edu/iiif/image-api/conformance.html#level1", Ee = "http://library.stanford.edu/iiif/image-api/conformance.html#level2", qe = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level1", _e = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2", Ve = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level1", Fe = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level2", We = "http://iiif.io/api/image/1/level1.json", Be = "http://iiif.io/api/image/1/profiles/level1.json", He = "http://iiif.io/api/image/1/level2.json", Je = "http://iiif.io/api/image/1/profiles/level2.json", Ge = "http://iiif.io/api/image/2/level1.json", Ke = "http://iiif.io/api/image/2/profiles/level1.json", Qe = "http://iiif.io/api/image/2/level2.json", Xe = "http://iiif.io/api/image/2/profiles/level2.json", Ye = "level1", Ze = "level2", ze = "http://iiif.io/api/image/2/level1", et = "http://iiif.io/api/image/2/level2", tt = [ze, et, Ue, De, Ne, Ee, qe, _e, Ve, Fe, We, Be, He, Je, Ge, Ke, Qe, Xe, Ye, Ze], k = { attributionLabel: "Attribution", providerId: "http://example.org/provider", providerName: "Unknown" };
156
- function rt(t) {
156
+ }, De = "http://library.stanford.edu/iiif/image-api/compliance.html#level1", Ne = "http://library.stanford.edu/iiif/image-api/compliance.html#level2", Ee = "http://library.stanford.edu/iiif/image-api/conformance.html#level1", qe = "http://library.stanford.edu/iiif/image-api/conformance.html#level2", _e = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level1", Be = "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2", Ve = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level1", Fe = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level2", We = "http://iiif.io/api/image/1/level1.json", He = "http://iiif.io/api/image/1/profiles/level1.json", Je = "http://iiif.io/api/image/1/level2.json", ze = "http://iiif.io/api/image/1/profiles/level2.json", Ge = "http://iiif.io/api/image/2/level1.json", Ke = "http://iiif.io/api/image/2/profiles/level1.json", Qe = "http://iiif.io/api/image/2/level2.json", Xe = "http://iiif.io/api/image/2/profiles/level2.json", Ye = "level1", Ze = "level2", et = "http://iiif.io/api/image/2/level1", tt = "http://iiif.io/api/image/2/level2", rt = [et, tt, De, Ne, Ee, qe, _e, Be, Ve, Fe, We, He, Je, ze, Ge, Ke, Qe, Xe, Ye, Ze], k = { attributionLabel: "Attribution", providerId: "http://example.org/provider", providerName: "Unknown" };
157
+ function it(t) {
157
158
  if (typeof t == "string") return [t];
158
159
  if (!t) return [];
159
160
  let e = Array.isArray(t) ? t : [t], r = [];
@@ -168,7 +169,7 @@ function rt(t) {
168
169
  }
169
170
  function I(t, e = "none") {
170
171
  if (!t) return { none: [""] };
171
- let r = rt(t), i = {};
172
+ let r = it(t), i = {};
172
173
  for (let s of r) {
173
174
  if (typeof s == "string") {
174
175
  i[e] = i[e] ? i[e] : [], i[e].push(s || "");
@@ -183,14 +184,14 @@ function I(t, e = "none") {
183
184
  }
184
185
  return Object.keys(i).length === 0 ? { none: [""] } : i;
185
186
  }
186
- function z(t) {
187
- if (Array.isArray(t)) return z(t.find((e) => typeof e == "string"));
188
- if (xe.indexOf(t) !== -1) return "level2";
189
- if (tt.indexOf(t) !== -1) return "level1";
190
- if (Me.indexOf(t) !== -1) return "level0";
187
+ function Z(t) {
188
+ if (Array.isArray(t)) return Z(t.find((e) => typeof e == "string"));
189
+ if ($e.indexOf(t) !== -1) return "level2";
190
+ if (rt.indexOf(t) !== -1) return "level1";
191
+ if (je.indexOf(t) !== -1) return "level0";
191
192
  if (typeof t == "string") return t;
192
193
  }
193
- function it(t) {
194
+ function st(t) {
194
195
  let e = Array.isArray(t) ? t : [t];
195
196
  for (let r of e) switch (r) {
196
197
  case "http://iiif.io/api/image/2/context.json":
@@ -203,7 +204,7 @@ function it(t) {
203
204
  return "ImageApiSelector";
204
205
  }
205
206
  }
206
- function st(t) {
207
+ function nt(t) {
207
208
  switch (t) {
208
209
  case "http://iiif.io/api/image/2/level0.json":
209
210
  case "http://iiif.io/api/image/2/level1.json":
@@ -236,15 +237,15 @@ function E(t) {
236
237
  for (let e of ["sc", "oa", "dcterms", "dctypes", "iiif"]) if (t.startsWith(`${e}:`)) return t.slice(e.length + 1);
237
238
  return t;
238
239
  }
239
- var nt = ["Collection", "Manifest", "Annotation", "AnnotationPage", "Range", "Service"];
240
+ var at = ["Collection", "Manifest", "Annotation", "AnnotationPage", "Range", "Service"];
240
241
  function U(t) {
241
242
  let e = t["@id"] || t.id, r = t["@type"] || t.type, i = t.profile || void 0, s = t["@context"] || void 0;
242
243
  if (i) {
243
- let n = st(i);
244
+ let n = nt(i);
244
245
  if (n) return n;
245
246
  }
246
247
  if (s) {
247
- let n = it(s);
248
+ let n = st(s);
248
249
  if (n) return n;
249
250
  }
250
251
  if (r) {
@@ -266,7 +267,7 @@ function U(t) {
266
267
  return "TextualBody";
267
268
  }
268
269
  }
269
- if (r && nt.indexOf(r) !== -1) return r;
270
+ if (r && at.indexOf(r) !== -1) return r;
270
271
  if (t.format) {
271
272
  if (t.format.startsWith("image/")) return "Image";
272
273
  if (t.format.startsWith("text/") || t.format === "application/pdf") return "Text";
@@ -274,15 +275,15 @@ function U(t) {
274
275
  }
275
276
  return e && (e.endsWith(".jpg") || e.endsWith(".png") || e.endsWith(".jpeg")) ? "Image" : r || "unknown";
276
277
  }
277
- var at = /http(s)?:\/\/(creativecommons.org|rightsstatements.org)[^"'\\<\n]+/gm;
278
- function ot(t) {
279
- let e = t.match(at);
278
+ var ot = /http(s)?:\/\/(creativecommons.org|rightsstatements.org)[^"'\\<\n]+/gm;
279
+ function ct(t) {
280
+ let e = t.match(ot);
280
281
  return e ? e[0] : t;
281
282
  }
282
- function ct(t, e = "Rights/License", r = "none") {
283
+ function lt(t, e = "Rights/License", r = "none") {
283
284
  let i = null, s = [], n = Array.isArray(t) ? t : [t];
284
285
  for (let o of n) {
285
- let c = o ? ot(o) : void 0;
286
+ let c = o ? ct(o) : void 0;
286
287
  if (c && (c.indexOf("creativecommons.org") !== -1 || c.indexOf("rightsstatements.org") !== -1)) {
287
288
  c.startsWith("https://") ? i = `http://${c.slice(8)}` : i = c;
288
289
  continue;
@@ -291,15 +292,15 @@ function ct(t, e = "Rights/License", r = "none") {
291
292
  }
292
293
  return [i, s];
293
294
  }
294
- var lt = ["http://iiif.io/api/presentation/2/context.json", "http://iiif.io/api/image/2/context.json", "http://iiif.io/api/image/1/context.json", "http://library.stanford.edu/iiif/image-api/1.1/context.json", "http://iiif.io/api/search/1/context.json", "http://iiif.io/api/search/0/context.json", "http://iiif.io/api/auth/1/context.json", "http://iiif.io/api/auth/0/context.json", "http://iiif.io/api/annex/openannotation/context.json"];
295
- function pt(t) {
295
+ var pt = ["http://iiif.io/api/presentation/2/context.json", "http://iiif.io/api/image/2/context.json", "http://iiif.io/api/image/1/context.json", "http://library.stanford.edu/iiif/image-api/1.1/context.json", "http://iiif.io/api/search/1/context.json", "http://iiif.io/api/search/0/context.json", "http://iiif.io/api/auth/1/context.json", "http://iiif.io/api/auth/0/context.json", "http://iiif.io/api/annex/openannotation/context.json"];
296
+ function vt(t) {
296
297
  if (t) {
297
298
  let e = Array.isArray(t) ? t : [t], r = [];
298
- for (let i of e) i === "http://iiif.io/api/presentation/2/context.json" && r.push("http://iiif.io/api/presentation/3/context.json"), lt.indexOf(i) === -1 && r.push(i);
299
+ for (let i of e) i === "http://iiif.io/api/presentation/2/context.json" && r.push("http://iiif.io/api/presentation/3/context.json"), pt.indexOf(i) === -1 && r.push(i);
299
300
  if (e.length) return r.length === 1 ? r[0] : r;
300
301
  }
301
302
  }
302
- function vt(t) {
303
+ function ht(t) {
303
304
  return t ? t.map((e) => ({ label: I(e.label), value: I(e.value) })) : [];
304
305
  }
305
306
  var q = 0;
@@ -311,16 +312,16 @@ function A(t) {
311
312
  let e = [...t.behavior || []];
312
313
  t.viewingHint && e.push(t.viewingHint);
313
314
  let r;
314
- return Array.isArray(t.motivation) ? r = t.motivation.map(E) : t.motivation && (r = E(t.motivation)), { "@context": t["@context"] ? pt(t["@context"]) : void 0, id: (t["@id"] || ee(t)).trim(), type: U(t), behavior: e.length ? e : void 0, height: t.height ? t.height : void 0, width: t.width ? t.width : void 0, motivation: r, viewingDirection: t.viewingDirection, profile: t.profile, format: t.format ? t.format : void 0, duration: void 0, timeMode: void 0 };
315
+ return Array.isArray(t.motivation) ? r = t.motivation.map(E) : t.motivation && (r = E(t.motivation)), { "@context": t["@context"] ? vt(t["@context"]) : void 0, id: (t["@id"] || ee(t)).trim(), type: U(t), behavior: e.length ? e : void 0, height: t.height ? t.height : void 0, width: t.width ? t.width : void 0, motivation: r, viewingDirection: t.viewingDirection, profile: t.profile, format: t.format ? t.format : void 0, duration: void 0, timeMode: void 0 };
315
316
  }
316
317
  function C(t) {
317
- let [e, r] = ct(t.license), i = [...t.metadata ? vt(t.metadata) : [], ...r];
318
- return { rights: e, metadata: i.length ? i : void 0, label: t.label ? I(t.label) : void 0, requiredStatement: t.attribution ? { label: I(k.attributionLabel), value: I(t.attribution) } : void 0, navDate: t.navDate, summary: t.description ? I(t.description) : void 0, thumbnail: ht(t.thumbnail) };
318
+ let [e, r] = lt(t.license), i = [...t.metadata ? ht(t.metadata) : [], ...r];
319
+ return { rights: e, metadata: i.length ? i : void 0, label: t.label ? I(t.label) : void 0, requiredStatement: t.attribution ? { label: I(k.attributionLabel), value: I(t.attribution) } : void 0, navDate: t.navDate, summary: t.description ? I(t.description) : void 0, thumbnail: ut(t.thumbnail) };
319
320
  }
320
- function ht(t) {
321
+ function ut(t) {
321
322
  return t && (Array.isArray(t) ? t : [t]).map((e) => typeof e == "string" ? { id: e, type: "Image" } : (e.type === "unknown" && (e.type = "Image"), e));
322
323
  }
323
- function ut(t) {
324
+ function ft(t) {
324
325
  if (!t.within) return;
325
326
  let e = Array.isArray(t.within) ? t.within : [t.within], r = [];
326
327
  for (let i of e) if (typeof i == "string") {
@@ -334,21 +335,21 @@ function ut(t) {
334
335
  }
335
336
  function R(t) {
336
337
  let e = t.related ? Array.isArray(t.related) ? t.related : [t.related] : [], r = t.contentLayer;
337
- return { provider: t.logo || e.length ? [{ id: k.providerId, type: "Agent", homepage: e.length ? [e[0]] : void 0, logo: t.logo ? Array.isArray(t.logo) ? t.logo : [t.logo] : void 0, label: I(k.providerName) }] : void 0, partOf: ut(t), rendering: t.rendering, seeAlso: t.seeAlso, start: t.startCanvas, service: t.service ? w(t.service) : void 0, supplementary: r ? [r] : void 0 };
338
+ return { provider: t.logo || e.length ? [{ id: k.providerId, type: "Agent", homepage: e.length ? [e[0]] : void 0, logo: t.logo ? Array.isArray(t.logo) ? t.logo : [t.logo] : void 0, label: I(k.providerName) }] : void 0, partOf: ft(t), rendering: t.rendering, seeAlso: t.seeAlso, start: t.startCanvas, service: t.service ? w(t.service) : void 0, supplementary: r ? [r] : void 0 };
338
339
  }
339
- function ft(t) {
340
+ function gt(t) {
340
341
  return { chars: t.chars, format: t.format ? t.format : void 0, language: t.language };
341
342
  }
342
343
  function mt(t) {
343
- return g({ ...A(t), ...C(t), ...R(t), items: t.members });
344
+ return m({ ...A(t), ...C(t), ...R(t), items: t.members });
344
345
  }
345
- function gt(t) {
346
+ function dt(t) {
346
347
  let e = [], r = [], i;
347
348
  for (let n of t.sequences || []) n.canvases.length && e.push(...n.canvases), n.behavior && r.push(...n.behavior), n.startCanvas && (i = n.startCanvas);
348
349
  let s = A(t);
349
- return r.length && (s.behavior ? s.behavior.push(...r) : s.behavior = r), g({ ...s, ...C(t), ...R(t), start: i, items: e, structures: dt(t.structures) });
350
+ return r.length && (s.behavior ? s.behavior.push(...r) : s.behavior = r), m({ ...s, ...C(t), ...R(t), start: i, items: e, structures: yt(t.structures) });
350
351
  }
351
- function dt(t) {
352
+ function yt(t) {
352
353
  if (!t) return t;
353
354
  let e = /* @__PURE__ */ new Map();
354
355
  for (let i of t) e.set(i.id, i);
@@ -359,16 +360,16 @@ function dt(t) {
359
360
  }
360
361
  return t.filter((i) => r.indexOf(i.id) === -1);
361
362
  }
362
- function yt(t) {
363
- return g({ ...A(t), ...C(t), ...R(t), annotations: t.otherContent && t.otherContent.length ? t.otherContent : void 0, items: t.images && t.images.length ? [{ id: ee(t, "annotation-page"), type: "AnnotationPage", items: t.images }] : void 0 });
364
- }
365
363
  function At(t) {
366
- return g({ ...A(t), ...C(t), ...R(t), items: t.resources && t.resources.length ? t.resources : void 0 });
364
+ return m({ ...A(t), ...C(t), ...R(t), annotations: t.otherContent && t.otherContent.length ? t.otherContent : void 0, items: t.images && t.images.length ? [{ id: ee(t, "annotation-page"), type: "AnnotationPage", items: t.images }] : void 0 });
367
365
  }
368
366
  function Ct(t) {
369
- return !t.canvases || t.canvases.length === 0 ? { canvases: [], behavior: [] } : { canvases: t.canvases, behavior: t.viewingHint ? [t.viewingHint] : [], startCanvas: t.startCanvas };
367
+ return m({ ...A(t), ...C(t), ...R(t), items: t.resources && t.resources.length ? t.resources : void 0 });
370
368
  }
371
369
  function bt(t) {
370
+ return !t.canvases || t.canvases.length === 0 ? { canvases: [], behavior: [] } : { canvases: t.canvases, behavior: t.viewingHint ? [t.viewingHint] : [], startCanvas: t.startCanvas };
371
+ }
372
+ function Rt(t) {
372
373
  function e(r) {
373
374
  if (Array.isArray(r)) {
374
375
  if (r.length > 1) return { type: "List", items: r.map(e) };
@@ -384,32 +385,32 @@ function bt(t) {
384
385
  return { type: "SpecificResource", source: i, selector: P(r.selector) };
385
386
  } else return encodeURI(r["@id"]).trim();
386
387
  }
387
- return g({ ...A(t), ...C(t), ...R(t), target: e(t.on), body: Array.isArray(t.resource) ? t.resource.map(_) : _(t.resource) });
388
+ return m({ ...A(t), ...C(t), ...R(t), target: e(t.on), body: Array.isArray(t.resource) ? t.resource.map(_) : _(t.resource) });
388
389
  }
389
390
  function _(t) {
390
391
  return t.type === "Choice" ? t : te(t);
391
392
  }
392
393
  function te(t) {
393
394
  let e = t;
394
- return g({ ...A(e), ...C(e), ...R(e), ...ft(e) });
395
- }
396
- function Rt(t) {
397
- let e = [];
398
- return t.default && t.default !== "rdf:nil" && e.push(t.default), t.item && t.item !== "rdf:nil" && e.push(...t.item), g({ ...A(t), ...C(t), items: e });
395
+ return m({ ...A(e), ...C(e), ...R(e), ...gt(e) });
399
396
  }
400
397
  function Lt(t) {
401
- return g({ ...A(t), ...C(t), ...R(t), items: t.members });
398
+ let e = [];
399
+ return t.default && t.default !== "rdf:nil" && e.push(t.default), t.item && t.item !== "rdf:nil" && e.push(...t.item), m({ ...A(t), ...C(t), items: e });
402
400
  }
403
401
  function wt(t) {
404
- let { "@id": e, "@type": r, "@context": i, profile: s, ...n } = t, o = {};
405
- return e && (o["@id"] = e), o["@type"] = U(t), o["@type"] === "unknown" && (i && i.length && (o["@context"] = i), o["@type"] = "Service"), s && (o.profile = z(s)), g({ ...o, ...n });
402
+ return m({ ...A(t), ...C(t), ...R(t), items: t.members });
406
403
  }
407
404
  function It(t) {
408
- return g({ ...A(t), ...C(t), ...R(t) });
405
+ let { "@id": e, "@type": r, "@context": i, profile: s, ...n } = t, o = {};
406
+ return e && (o["@id"] = e), o["@type"] = U(t), o["@type"] === "unknown" && (i && i.length && (o["@context"] = i), o["@type"] = "Service"), s && (o.profile = Z(s)), m({ ...o, ...n });
407
+ }
408
+ function St(t) {
409
+ return m({ ...A(t), ...C(t), ...R(t) });
409
410
  }
410
- var St = new Oe({ collection: [mt], manifest: [gt], canvas: [yt], annotationList: [At], sequence: [Ct], annotation: [bt], contentResource: [te], choice: [Rt], range: [Lt], service: [wt], layer: [It] });
411
+ var xt = new Ue({ collection: [mt], manifest: [dt], canvas: [At], annotationList: [Ct], sequence: [bt], annotation: [Rt], contentResource: [te], choice: [Lt], range: [wt], service: [It], layer: [St] });
411
412
  function re(t) {
412
- return t && t["@context"] && (t["@context"] === "http://iiif.io/api/presentation/2/context.json" || t["@context"].indexOf("http://iiif.io/api/presentation/2/context.json") !== -1 || t["@context"] === "http://www.shared-canvas.org/ns/context.json") || t["@context"] === "http://iiif.io/api/image/2/context.json" ? St.traverseUnknown(t) : t;
413
+ return t && t["@context"] && (t["@context"] === "http://iiif.io/api/presentation/2/context.json" || t["@context"].indexOf("http://iiif.io/api/presentation/2/context.json") !== -1 || t["@context"] === "http://www.shared-canvas.org/ns/context.json") || t["@context"] === "http://iiif.io/api/image/2/context.json" ? xt.traverseUnknown(t) : t;
413
414
  }
414
415
  function P(t) {
415
416
  if ((Array.isArray(t["@type"]) && t["@type"].includes("oa:SvgSelector") || t["@type"] == "oa:SvgSelector") && ("chars" in t || "value" in t)) return { type: "SvgSelector", value: "chars" in t ? t.chars : t.value };
@@ -421,10 +422,10 @@ function P(t) {
421
422
  function M(t) {
422
423
  return typeof t == "string" ? !1 : t && !t.type && "source" in t ? (t.type = "SpecificResource", !0) : !!t && t.type === "SpecificResource";
423
424
  }
424
- function T(...t) {
425
+ function x(...t) {
425
426
  return (e) => t.reduce((r, i) => i(r), e);
426
427
  }
427
- var V = ["Collection", "Manifest", "Canvas", "AnnotationPage", "AnnotationCollection", "Annotation", "ContentResource", "Range", "Service", "Selector", "Agent"];
428
+ var B = ["Collection", "Manifest", "Canvas", "AnnotationPage", "AnnotationCollection", "Annotation", "ContentResource", "Range", "Service", "Selector", "Agent"];
428
429
  function Tt(t, e) {
429
430
  if (typeof t > "u" || t === null) throw new Error("Null or undefined is not a valid entity.");
430
431
  if (Array.isArray(t)) throw new Error("Array is not a valid entity");
@@ -433,15 +434,15 @@ function Tt(t, e) {
433
434
  throw new Error(`${typeof t} is not a valid entity`);
434
435
  }
435
436
  if (typeof t.type == "string") {
436
- let r = V.indexOf(t.type);
437
- if (r !== -1) return V[r];
437
+ let r = B.indexOf(t.type);
438
+ if (r !== -1) return B[r];
438
439
  }
439
440
  if (t.profile) return "Service";
440
441
  throw new Error("Resource type is not known");
441
442
  }
442
443
  var D = class ie {
443
444
  constructor(e, r = {}) {
444
- b(this, "traversals"), b(this, "options"), b(this, "_traverseManifest", T(this.traverseManifestItems.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this), this.traverseLinkedCanvases.bind(this), this.traverseManifestStructures.bind(this), this.traverseInlineAnnotationPages.bind(this))), b(this, "_traverseCanvas", T(this.traverseCanvasItems.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this), this.traverseLinkedCanvases.bind(this), this.traverseInlineAnnotationPages.bind(this))), b(this, "_traverseAnnotationPage", T(this.traverseAnnotationPageItems.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this))), b(this, "_traverseRange", T(this.traverseRangeRanges.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this), this.traverseLinkedCanvases.bind(this))), this.traversals = { collection: [], manifest: [], canvas: [], annotationCollection: [], annotationPage: [], annotation: [], contentResource: [], choice: [], range: [], service: [], agent: [], specificResource: [], geoJson: [], ...e }, this.options = { allowUndefinedReturn: !1, ...r };
445
+ b(this, "traversals"), b(this, "options"), b(this, "_traverseManifest", x(this.traverseManifestItems.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this), this.traverseLinkedCanvases.bind(this), this.traverseManifestStructures.bind(this), this.traverseInlineAnnotationPages.bind(this))), b(this, "_traverseCanvas", x(this.traverseCanvasItems.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this), this.traverseLinkedCanvases.bind(this), this.traverseInlineAnnotationPages.bind(this))), b(this, "_traverseAnnotationPage", x(this.traverseAnnotationPageItems.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this))), b(this, "_traverseRange", x(this.traverseRangeRanges.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this), this.traverseLinkedCanvases.bind(this))), this.traversals = { collection: [], manifest: [], canvas: [], annotationCollection: [], annotationPage: [], annotation: [], contentResource: [], choice: [], range: [], service: [], agent: [], specificResource: [], geoJson: [], ...e }, this.options = { allowUndefinedReturn: !1, ...r };
445
446
  }
446
447
  static all(e) {
447
448
  return new ie({ collection: [e], manifest: [e], canvas: [e], annotationCollection: [e], annotationPage: [e], annotation: [e], contentResource: [e], choice: [e], range: [e], service: [e], geoJson: [e], specificResource: [e], agent: [e] });
@@ -552,15 +553,15 @@ var D = class ie {
552
553
  }
553
554
  }
554
555
  };
555
- const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.profile.toString().includes("iiif.io/api/image/"), ne = (t) => {
556
- const e = m(t, "type"), r = m(t, "context");
556
+ const se = (t) => g(t, "type").startsWith("ImageService") || t.profile && t.profile.toString().includes("iiif.io/api/image/"), ne = (t) => {
557
+ const e = g(t, "type"), r = g(t, "context");
557
558
  if (e === "ImageService2" || r != null && r.includes("image/2")) {
558
559
  const i = t, s = ["level0", "level1", "level2"];
559
560
  return { majorVersion: 2, profileLevel: (Array.isArray(i.profile) ? i.profile : [i.profile]).map((c) => s.findIndex((a) => c.toString().includes(a))).filter((c) => c > -1).sort((c, a) => a - c)[0] };
560
561
  } else if (e || r)
561
562
  return { majorVersion: 3, profileLevel: parseInt(t.profile) };
562
563
  }, O = (t, e, r) => {
563
- const i = m(t, "id"), s = t.profile || "";
564
+ const i = g(t, "id"), s = t.profile || "";
564
565
  if (typeof s == "string" && (s.includes("level0") || s.includes("level:0"))) {
565
566
  if ("sizes" in t && Array.isArray(t.sizes)) {
566
567
  const o = t.sizes.sort((c, a) => a.width * a.height - c.width * c.height).filter((c) => c.width * c.height >= e * r)[0];
@@ -570,16 +571,16 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
570
571
  return `${i}/full/full/0/default.jpg`;
571
572
  }
572
573
  return `${i}/full/!${e},${r}/0/default.jpg`;
573
- }, xt = (t, e, r) => {
574
- const i = m(t, "id"), s = t.profile || "";
574
+ }, $t = (t, e, r) => {
575
+ const i = g(t, "id"), s = t.profile || "";
575
576
  if (typeof s == "string" && (s.includes("level0") || s.includes("level:0"))) return;
576
577
  const { x: o, y: c, w: a, h: l } = e, u = a / l, v = u < 1, d = Math.ceil(v ? r / u : r), p = Math.ceil(v ? r : r / u), f = `${Math.round(o)},${Math.round(c)},${Math.round(a)},${Math.round(l)}`;
577
578
  return `${i}/${f}/!${p},${d}/0/default.jpg`;
578
- }, $t = (t) => (e, r = 400) => {
579
+ }, Mt = (t) => (e, r = 400) => {
579
580
  if (t.type === "dynamic")
580
- return xt(t.service, e, r);
581
+ return $t(t.service, e, r);
581
582
  console.error("Level 0 or static image canvas: unsupported");
582
- }, Mt = (t, e = []) => (r = 400) => {
583
+ }, jt = (t, e = []) => (r = 400) => {
583
584
  const { width: i, height: s } = t;
584
585
  if (!i || !s) return;
585
586
  const n = i / s, o = n < 1, c = Math.ceil(o ? r / n : r), a = Math.ceil(o ? r : r / n);
@@ -598,31 +599,36 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
598
599
  if (l.type === "static")
599
600
  return l.url;
600
601
  }
601
- }, jt = (t, e = []) => (r = 800) => {
602
- const { width: i, height: s } = t;
603
- if (!i || !s) return;
604
- const n = i / s, o = n < 1, c = Math.ceil(o ? r / n : r), a = Math.ceil(o ? r : r / n);
605
- for (const l of e) {
606
- if (l.type === "dynamic" || l.type === "level0")
607
- return O(l.service, a, c);
608
- if (l.type === "static")
609
- return l.url;
610
- }
611
- }, ae = (t) => t.endsWith("/info.json") ? t : `${t.endsWith("/") ? t : `${t}/`}info.json`, kt = (t) => {
612
- const { format: e, height: r, width: i } = t, s = m(t, "id"), n = (t.service || []).find(se), o = n ? ne(n) : void 0;
613
- if (o) {
614
- const c = {
602
+ }, ae = (t) => t.endsWith("/info.json") ? t : `${t.endsWith("/") ? t : `${t}/`}info.json`, kt = (t, e, r) => (i = 800) => {
603
+ if (!t || !e) return;
604
+ const s = t / e, n = s < 1, o = Math.ceil(n ? i / s : i), c = Math.ceil(n ? i : i / s);
605
+ return O(r, c, o);
606
+ }, Pt = (t) => () => fetch(t).then((e) => e.json()).then((e) => {
607
+ const r = e.width, i = e.height;
608
+ return r !== void 0 && i !== void 0 ? { width: r, height: i } : void 0;
609
+ }), Ot = (t) => () => {
610
+ const e = typeof window < "u";
611
+ return fetch(t).then((r) => r.blob()).then((r) => e ? createImageBitmap(r).then((i) => {
612
+ const { width: s, height: n } = i;
613
+ return i.close(), { width: s, height: n };
614
+ }) : r.arrayBuffer().then((i) => ce(new Uint8Array(i))));
615
+ }, Ut = (t) => {
616
+ const { format: e, height: r, width: i } = t, s = g(t, "id"), n = (t.service || []).find(se), o = n ? ne(n) : void 0;
617
+ if (n && o) {
618
+ const c = ae(g(n, "id")), a = {
615
619
  source: t,
616
620
  type: o.profileLevel === 0 ? "level0" : "dynamic",
617
621
  service: n,
618
622
  width: i,
619
623
  height: r,
620
624
  majorVersion: o.majorVersion,
621
- serviceUrl: ae(m(n, "id"))
625
+ serviceUrl: c,
626
+ getImageURL: kt(i, r, n),
627
+ getPixelSize: Pt(c)
622
628
  };
623
- return o.profileLevel === 0 ? c : {
624
- ...c,
625
- getRegionURL: $t(c)
629
+ return o.profileLevel === 0 ? a : {
630
+ ...a,
631
+ getRegionURL: Mt(a)
626
632
  };
627
633
  } else
628
634
  return {
@@ -631,19 +637,21 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
631
637
  width: i,
632
638
  height: r,
633
639
  url: s,
634
- format: e
640
+ format: e,
641
+ getImageURL: () => s,
642
+ getPixelSize: Ot(s)
635
643
  };
636
- }, Pt = (t) => {
644
+ }, Dt = (t) => {
637
645
  const e = [];
638
646
  return new D({
639
647
  annotation: [(i) => {
640
648
  if (i.motivation === "painting" || !i.motivation) {
641
649
  const n = (i.body ? Array.isArray(i.body) ? i.body : [i.body] : []).filter((o) => o.type === "Image");
642
- e.push(...n.map((o) => kt(o)));
650
+ e.push(...n.map((o) => Ut(o)));
643
651
  }
644
652
  }]
645
653
  }).traverseCanvas(t), e;
646
- }, Ot = (t) => () => {
654
+ }, Nt = (t) => () => {
647
655
  const e = /* @__PURE__ */ new Map(), r = (a, l, u = 0) => {
648
656
  const v = {
649
657
  id: a.id,
@@ -658,8 +666,8 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
658
666
  };
659
667
  a.items && a.items.length > 0 && a.items.forEach((h) => {
660
668
  if (h.source.type === "Range") {
661
- const x = r(h, v, u + 1);
662
- v.children.push(x);
669
+ const T = r(h, v, u + 1);
670
+ v.children.push(T);
663
671
  } else {
664
672
  const L = {
665
673
  id: h.id,
@@ -690,7 +698,7 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
690
698
  const u = (v, d = []) => v.parent ? u(v.parent, [v, ...d]) : [v, ...d];
691
699
  return u(l);
692
700
  }, getNode: (a) => e.get(a) };
693
- }, Ut = async (t) => {
701
+ }, Et = async (t) => {
694
702
  try {
695
703
  new URL(t);
696
704
  } catch {
@@ -744,7 +752,7 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
744
752
  code: "INVALID_MANIFEST",
745
753
  message: "Missing @context"
746
754
  };
747
- const i = m(t, "id");
755
+ const i = g(t, "id");
748
756
  if (!i)
749
757
  return {
750
758
  type: "error",
@@ -753,18 +761,18 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
753
761
  };
754
762
  if (r.includes("presentation/2") || r.includes("presentation/3")) {
755
763
  const s = r.includes("presentation/2") ? 2 : 3;
756
- return m(t, "type").includes("Collection") ? {
764
+ return g(t, "type").includes("Collection") ? {
757
765
  type: "collection",
758
766
  url: e || i,
759
- resource: Dt(t, s)
767
+ resource: qt(t, s)
760
768
  } : {
761
769
  type: "manifest",
762
770
  url: e || i,
763
- resource: Nt(t, s)
771
+ resource: _t(t, s)
764
772
  };
765
773
  }
766
774
  if (r.includes("image/2") || r.includes("image/3")) {
767
- const s = Et(t);
775
+ const s = Bt(t);
768
776
  return s ? {
769
777
  type: "iiif-image",
770
778
  url: e || i,
@@ -780,7 +788,7 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
780
788
  code: "INVALID_MANIFEST",
781
789
  message: "JSON resource is not a recognized IIIF format"
782
790
  };
783
- }, Dt = (t, e) => {
791
+ }, qt = (t, e) => {
784
792
  const r = (n) => {
785
793
  const o = [];
786
794
  return new D({
@@ -800,7 +808,7 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
800
808
  getLabel: S(i),
801
809
  getMetadata: j(i)
802
810
  };
803
- }, Nt = (t, e) => {
811
+ }, _t = (t, e) => {
804
812
  const r = (o) => {
805
813
  const c = [], a = [];
806
814
  new D({
@@ -812,7 +820,7 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
812
820
  }]
813
821
  }).traverseManifest(o);
814
822
  const u = c.map((p) => {
815
- const f = Pt(p);
823
+ const f = Dt(p);
816
824
  return {
817
825
  source: p,
818
826
  id: p.id,
@@ -820,18 +828,19 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
820
828
  height: p.height,
821
829
  images: f,
822
830
  annotations: p.annotations || [],
823
- getImageURL: jt(p, f),
831
+ getImageURL: f.length > 0 ? f[0].getImageURL : () => {
832
+ },
824
833
  getLabel: S(p),
825
834
  getMetadata: j(p),
826
- getThumbnailURL: Mt(p, f)
835
+ getThumbnailURL: jt(p, f)
827
836
  };
828
837
  }), v = (p) => {
829
- const f = p.items || [], h = f.filter((y) => y.type === "Canvas").map((y) => u.find(($) => $.id === y.id)).filter(Boolean), L = f.filter((y) => y.type === "Range").map((y) => v(y)), x = [...h, ...L];
838
+ const f = p.items || [], h = f.filter((y) => y.type === "Canvas").map((y) => u.find(($) => $.id === y.id)).filter(Boolean), L = f.filter((y) => y.type === "Range").map((y) => v(y)), T = [...h, ...L];
830
839
  return {
831
840
  source: p,
832
841
  id: p.id,
833
842
  // Maintain original order
834
- items: f.map((y) => x.find(($) => $.id === y.id)),
843
+ items: f.map((y) => T.find(($) => $.id === y.id)),
835
844
  canvases: h,
836
845
  ranges: L,
837
846
  getLabel: S(p)
@@ -847,9 +856,9 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
847
856
  structure: n,
848
857
  getLabel: S(i),
849
858
  getMetadata: j(i),
850
- getTableOfContents: Ot(n)
859
+ getTableOfContents: Nt(n)
851
860
  };
852
- }, Et = (t) => {
861
+ }, Bt = (t) => {
853
862
  const { width: e, height: r } = t, i = ne(t);
854
863
  if (i)
855
864
  return {
@@ -858,22 +867,21 @@ const se = (t) => m(t, "type").startsWith("ImageService") || t.profile && t.prof
858
867
  width: e,
859
868
  height: r,
860
869
  majorVersion: i.majorVersion,
861
- serviceUrl: ae(m(t, "id"))
870
+ serviceUrl: ae(g(t, "id"))
862
871
  };
863
- }, _t = { parse: oe, parseURL: Ut };
872
+ }, Wt = { parse: oe, parseURL: Et };
864
873
  export {
865
- _t as Cozy,
866
- jt as getImageURL,
874
+ Wt as Cozy,
867
875
  O as getImageURLFromService,
868
- Pt as getImages,
876
+ Dt as getImages,
869
877
  S as getLabel,
870
878
  j as getMetadata,
871
- m as getPropertyValue,
872
- $t as getRegionURL,
873
- xt as getRegionURLFromService,
874
- Wt as getStringValue,
875
- Ot as getTableOfContents,
876
- Mt as getThumbnailURL,
879
+ g as getPropertyValue,
880
+ Mt as getRegionURL,
881
+ $t as getRegionURLFromService,
882
+ zt as getStringValue,
883
+ Nt as getTableOfContents,
884
+ jt as getThumbnailURL,
877
885
  se as isImageService,
878
886
  ae as normalizeServiceUrl,
879
887
  ne as parseImageService
@@ -1,3 +1,4 @@
1
+ import "image-size";
1
2
  import { g as $ } from "../resource-DS2brz47.js";
2
3
  const F = (t) => ({ id: $(t, "id"), ...t }), T = (t) => fetch(t.serviceUrl).then((e) => e.json()).then(F), P = new FinalizationRegistry(({ signal: t, aborted: e }) => {
3
4
  t == null || t.removeEventListener("abort", e);
@@ -92,7 +93,7 @@ const H = () => {
92
93
  });
93
94
  }
94
95
  return d;
95
- }, L = async (t, e) => {
96
+ }, O = async (t, e) => {
96
97
  const c = await T(t), i = R(c, e), r = document.createElement("canvas"), n = r.getContext("2d");
97
98
  if (!n)
98
99
  throw new Error("Error initializing canvas context");
@@ -164,7 +165,7 @@ const H = () => {
164
165
  });
165
166
  }
166
167
  return a;
167
- }, O = async (t, e) => {
168
+ }, X = async (t, e) => {
168
169
  const c = await T(t), i = k(c, e), r = b(c, e), n = document.createElement("canvas");
169
170
  n.width = r.width, n.height = r.height;
170
171
  const o = n.getContext("2d");
@@ -181,6 +182,6 @@ const H = () => {
181
182
  });
182
183
  };
183
184
  export {
184
- L as cropRegion,
185
- O as getThumbnail
185
+ O as cropRegion,
186
+ X as getThumbnail
186
187
  };
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Manifest, Canvas, ImageService2, ImageService3, IIIFExternalWebResource, Collection, Range, AnnotationPage } from '@iiif/presentation-3';
1
+ import { Manifest, Canvas, IIIFExternalWebResource, Collection, Range, AnnotationPage, Service } from '@iiif/presentation-3';
2
2
  export type CozyParseResult = {
3
3
  type: 'collection';
4
4
  url: string;
@@ -94,6 +94,11 @@ interface BaseImageResource {
94
94
  readonly type: 'static' | 'dynamic' | 'level0';
95
95
  readonly width: number;
96
96
  readonly height: number;
97
+ getImageURL(minSize?: number): string;
98
+ getPixelSize(): Promise<{
99
+ width: number;
100
+ height: number;
101
+ }>;
97
102
  }
98
103
  export interface StaticImageResource extends BaseImageResource {
99
104
  readonly type: 'static';
@@ -101,7 +106,7 @@ export interface StaticImageResource extends BaseImageResource {
101
106
  }
102
107
  export interface DynamicImageServiceResource extends BaseImageResource {
103
108
  readonly type: 'dynamic';
104
- readonly service: ImageService2 | ImageService3;
109
+ readonly service: Service;
105
110
  readonly serviceUrl: string;
106
111
  readonly majorVersion: number;
107
112
  getRegionURL(bounds: Bounds, minSize?: number): string;
@@ -109,7 +114,7 @@ export interface DynamicImageServiceResource extends BaseImageResource {
109
114
  export interface Level0ImageServiceResource extends BaseImageResource {
110
115
  readonly type: 'level0';
111
116
  readonly majorVersion: number;
112
- readonly service: ImageService2 | ImageService3;
117
+ readonly service: Service;
113
118
  readonly serviceUrl: string;
114
119
  }
115
120
  export interface ImageRequestOptions {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-iiif",
3
- "version": "0.2.7",
3
+ "version": "0.3.1",
4
4
  "description": "A developer-friendly collection of abstractions and utilities built on top of @iiif/presentation-3 and @iiif/parser",
5
5
  "license": "MIT",
6
6
  "author": "Rainer Simon",
@@ -30,11 +30,12 @@
30
30
  "devDependencies": {
31
31
  "vite": "^6.3.5",
32
32
  "vite-plugin-dts": "^4.5.4",
33
- "vitest": "^3.2.2"
33
+ "vitest": "^3.2.3"
34
34
  },
35
35
  "dependencies": {
36
36
  "@iiif/parser": "2.1.7",
37
37
  "@iiif/presentation-3": "^2.2.3",
38
+ "image-size": "^2.0.2",
38
39
  "p-throttle": "^7.0.0",
39
40
  "uuid": "^11.1.0"
40
41
  }
package/src/Cozy.ts CHANGED
@@ -2,8 +2,7 @@ import type { Canvas, Collection, Manifest, Range } from '@iiif/presentation-3';
2
2
  import { convertPresentation2 } from '@iiif/parser/presentation-2';
3
3
  import { Traverse } from '@iiif/parser';
4
4
  import {
5
- getImages,
6
- getImageURL,
5
+ getImages,
7
6
  getLabel,
8
7
  getMetadata,
9
8
  getPropertyValue,
@@ -15,7 +14,7 @@ import {
15
14
  import type {
16
15
  CozyCanvas,
17
16
  CozyCollection,
18
- CozyCollectionItem,
17
+ CozyCollectionItem,
19
18
  CozyManifest,
20
19
  CozyParseResult,
21
20
  CozyRange,
@@ -194,7 +193,7 @@ const parseManifestResource = (resource: any, majorVersion: number): CozyManifes
194
193
  height: c.height,
195
194
  images,
196
195
  annotations: (c.annotations || []),
197
- getImageURL: getImageURL(c, images),
196
+ getImageURL: images.length > 0 ? images[0].getImageURL : () => undefined,
198
197
  getLabel: getLabel(c),
199
198
  getMetadata: getMetadata(c),
200
199
  getThumbnailURL: getThumbnailURL(c, images)
@@ -1,4 +1,5 @@
1
- import type { Canvas, IIIFExternalWebResource } from '@iiif/presentation-3';
1
+ import { imageSize } from 'image-size';
2
+ import type { Canvas, IIIFExternalWebResource, Service } from '@iiif/presentation-3';
2
3
  import { Traverse } from '@iiif/parser';
3
4
  import { getPropertyValue } from './resource';
4
5
  import { getImageURLFromService, getRegionURL, isImageService, parseImageService } from './image-service';
@@ -42,9 +43,14 @@ export const getThumbnailURL = (canvas: Canvas, images: CozyImageResource[] = []
42
43
  }
43
44
  }
44
45
 
45
- export const getImageURL = (canvas: Canvas, images: CozyImageResource[] = []) => (minSize = 800) => {
46
- const { width, height } = canvas;
46
+ export const normalizeServiceUrl = (url: string) =>
47
+ url.endsWith('/info.json') ? url : `${url.endsWith('/') ? url : `${url}/`}info.json`;
47
48
 
49
+ const getImageURL = (
50
+ width: number | undefined,
51
+ height: number | undefined,
52
+ service: Service
53
+ ) => (minSize = 800) => {
48
54
  if (!width || !height) return;
49
55
 
50
56
  const aspect = width / height;
@@ -53,17 +59,31 @@ export const getImageURL = (canvas: Canvas, images: CozyImageResource[] = []) =>
53
59
  const h = Math.ceil(isPortrait ? minSize / aspect : minSize);
54
60
  const w = Math.ceil(isPortrait ? minSize : minSize / aspect);
55
61
 
56
- for (const image of images) {
57
- if (image.type === 'dynamic' || image.type === 'level0') {
58
- return getImageURLFromService(image.service, w, h);
59
- } else if (image.type === 'static') {
60
- return image.url;
61
- }
62
- }
62
+ return getImageURLFromService(service!, w, h);
63
63
  }
64
64
 
65
- export const normalizeServiceUrl = (url: string) =>
66
- url.endsWith('/info.json') ? url : `${url.endsWith('/') ? url : `${url}/`}info.json`;
65
+ const getPixelSizeFromServiceUrl = (serviceUrl: string) => () =>
66
+ fetch(serviceUrl).then(res => res.json()).then(data => {
67
+ const width: number = data.width;
68
+ const height: number = data.height;
69
+ return (width !== undefined && height !== undefined) ? { width, height } : undefined;
70
+ });
71
+
72
+ const getStaticImagePixelSize = (url: string) => () => {
73
+ const isBrowser = typeof window !== 'undefined';
74
+
75
+ return fetch(url).then(res => res.blob()).then(blob => {
76
+ if (isBrowser) {
77
+ return createImageBitmap(blob).then(bitmap => {
78
+ const { width, height } = bitmap;
79
+ bitmap.close();
80
+ return { width, height }
81
+ });
82
+ } else { return blob.arrayBuffer().then(buffer =>
83
+ imageSize(new Uint8Array(buffer)));
84
+ }
85
+ });
86
+ }
67
87
 
68
88
  const toCozyImageResource = (resource: IIIFExternalWebResource) => {
69
89
  const { format, height, width } = resource;
@@ -74,7 +94,9 @@ const toCozyImageResource = (resource: IIIFExternalWebResource) => {
74
94
 
75
95
  const service = imageService ? parseImageService(imageService) : undefined;
76
96
 
77
- if (service) {
97
+ if (imageService && service) {
98
+ const serviceUrl = normalizeServiceUrl(getPropertyValue<string>(imageService, 'id'));
99
+
78
100
  const image = {
79
101
  source: resource,
80
102
  type: service.profileLevel === 0 ? 'level0' : 'dynamic',
@@ -82,7 +104,9 @@ const toCozyImageResource = (resource: IIIFExternalWebResource) => {
82
104
  width,
83
105
  height,
84
106
  majorVersion: service.majorVersion,
85
- serviceUrl: normalizeServiceUrl(getPropertyValue<string>(imageService, 'id'))
107
+ serviceUrl,
108
+ getImageURL: getImageURL(width, height, imageService),
109
+ getPixelSize: getPixelSizeFromServiceUrl(serviceUrl)
86
110
  } as ImageServiceResource;
87
111
 
88
112
  if (service.profileLevel === 0) {
@@ -100,7 +124,9 @@ const toCozyImageResource = (resource: IIIFExternalWebResource) => {
100
124
  width,
101
125
  height,
102
126
  url: id,
103
- format
127
+ format,
128
+ getImageURL: () => id,
129
+ getPixelSize: getStaticImagePixelSize(id)
104
130
  } as StaticImageResource;
105
131
  }
106
132
  }
@@ -36,7 +36,7 @@ export const parseImageService = (service: Service) => {
36
36
  }
37
37
 
38
38
  export const getImageURLFromService = (
39
- service: ImageService2 | ImageService3,
39
+ service: Service,
40
40
  width: number,
41
41
  height: number
42
42
  ): string => {
@@ -66,7 +66,7 @@ export const getImageURLFromService = (
66
66
  }
67
67
 
68
68
  export const getRegionURLFromService = (
69
- service: ImageService2 | ImageService3,
69
+ service: Service,
70
70
  bounds: Bounds,
71
71
  minSize: number
72
72
  ): string | undefined => {
@@ -102,4 +102,4 @@ export const getRegionURL = (
102
102
  } else {
103
103
  console.error('Level 0 or static image canvas: unsupported');
104
104
  }
105
- }
105
+ }
package/src/types.ts CHANGED
@@ -1,12 +1,11 @@
1
1
  import type {
2
2
  Manifest,
3
- Canvas,
4
- ImageService2,
5
- ImageService3,
3
+ Canvas,
6
4
  IIIFExternalWebResource,
7
5
  Collection,
8
6
  Range,
9
- AnnotationPage
7
+ AnnotationPage,
8
+ Service
10
9
  } from '@iiif/presentation-3';
11
10
 
12
11
  export type CozyParseResult =
@@ -169,6 +168,10 @@ interface BaseImageResource {
169
168
 
170
169
  readonly height: number;
171
170
 
171
+ getImageURL(minSize?: number): string;
172
+
173
+ getPixelSize(): Promise<{ width: number, height: number }>;
174
+
172
175
  }
173
176
 
174
177
  export interface StaticImageResource extends BaseImageResource {
@@ -183,7 +186,7 @@ export interface DynamicImageServiceResource extends BaseImageResource {
183
186
 
184
187
  readonly type: 'dynamic';
185
188
 
186
- readonly service: ImageService2 | ImageService3;
189
+ readonly service: Service;
187
190
 
188
191
  readonly serviceUrl: string;
189
192
 
@@ -199,7 +202,7 @@ export interface Level0ImageServiceResource extends BaseImageResource {
199
202
 
200
203
  readonly majorVersion: number;
201
204
 
202
- readonly service: ImageService2 | ImageService3;
205
+ readonly service: Service;
203
206
 
204
207
  readonly serviceUrl: string;
205
208
 
@@ -0,0 +1,42 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { Cozy, CozyManifest } from '../../src';
3
+
4
+ import { STATIC_IMAGE, WITH_DIFFERENT_CANVAS_DIMENSIONS } from './fixtures';
5
+
6
+ describe('canvas', () => {
7
+
8
+ it('should determine correct pixel size for image service', async () => {
9
+ const result = await Cozy.parseURL(WITH_DIFFERENT_CANVAS_DIMENSIONS);
10
+ expect(result.type).toBe('manifest');
11
+ expect('resource' in result).toBeTruthy();
12
+
13
+ const manifest = (result as any).resource as CozyManifest;
14
+ expect(manifest.canvases.length).toBe(66);
15
+
16
+ const page2 = manifest.canvases[1];
17
+ expect(page2.getLabel()).toBe('Page 2');
18
+ expect(page2.images.length).toBe(1);
19
+
20
+ const image = page2.images[0];
21
+ const { width, height } = await image.getPixelSize();
22
+ expect(width).toBe(3796);
23
+ expect(height).toBe(5910);
24
+ });
25
+
26
+ it('should determine correct pixel size for static image', async () => {
27
+ const result = await Cozy.parseURL(STATIC_IMAGE);
28
+ expect(result.type).toBe('manifest');
29
+ expect('resource' in result).toBeTruthy();
30
+
31
+ const manifest = (result as any).resource as CozyManifest;
32
+ expect(manifest.canvases.length).toBe(1);
33
+
34
+ const image = manifest.canvases[0].images[0];
35
+ expect(image.type).toBe('static');
36
+
37
+ const { width, height } = await image.getPixelSize();
38
+ expect(width).toBe(1200);
39
+ expect(height).toBe(1800);
40
+ });
41
+
42
+ });
@@ -1,2 +1,12 @@
1
+ // IIIF cookbook static image
2
+ export const STATIC_IMAGE =
3
+ 'https://iiif.io/api/cookbook/recipe/0001-mvm-image/manifest.json';
4
+
5
+ // Manifest that uses `structures` to define a Table of Contents
1
6
  export const WITH_STRUCTURES =
2
- 'https://lib.is/IE19255085/manifest';
7
+ 'https://lib.is/IE19255085/manifest';
8
+
9
+ // Manifest that specifies a different size for the canvas
10
+ // then the physical image pixel size
11
+ export const WITH_DIFFERENT_CANVAS_DIMENSIONS =
12
+ 'https://www.loc.gov/item/00552972/manifest.json';
package/vite.config.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { defineConfig } from 'vite';
2
- import { resolve } from 'path';
3
2
  import dts from 'vite-plugin-dts';
4
3
 
5
4
  export default defineConfig({
@@ -7,11 +6,14 @@ export default defineConfig({
7
6
  build: {
8
7
  lib: {
9
8
  entry: {
10
- 'index': resolve(__dirname, 'src/index.ts'),
11
- 'helpers/index': resolve(__dirname, 'src/helpers/index.ts'),
12
- 'level-0/index': resolve(__dirname, 'src/level-0/index.ts'),
9
+ 'index': './src/index.ts',
10
+ 'helpers/index': './src/helpers/index.ts',
11
+ 'level-0/index': './src/level-0/index.ts',
13
12
  },
14
13
  formats: ['es']
14
+ },
15
+ rollupOptions: {
16
+ external: ['image-size']
15
17
  }
16
18
  }
17
19
  });