cozy-iiif 0.3.1 → 0.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.
@@ -1,5 +1,5 @@
1
1
  import { ImageService2, ImageService3, Service } from '@iiif/presentation-3';
2
- import { Bounds, CozyImageResource } from '../types';
2
+ import { Bounds, CozyImageResource, GetRegionURLOpts } from '../types';
3
3
  type ImageService = ImageService2 | ImageService3;
4
4
  export declare const isImageService: (data: any) => data is ImageService;
5
5
  export declare const parseImageService: (service: Service) => {
@@ -7,6 +7,6 @@ export declare const parseImageService: (service: Service) => {
7
7
  profileLevel: number;
8
8
  } | undefined;
9
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
- export declare const getRegionURL: (image: CozyImageResource) => (bounds: Bounds, minSize?: number) => string | undefined;
10
+ export declare const getRegionURLFromService: (service: Service, bounds: Bounds, opts?: GetRegionURLOpts) => string | undefined;
11
+ export declare const getRegionURL: (image: CozyImageResource) => (bounds: Bounds, opts?: GetRegionURLOpts) => string | undefined;
12
12
  export {};
package/dist/index.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import { imageSize as ce } from "image-size";
2
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) {
3
+ import { c as Jt } 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", me = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level0", ge = "http://library.stanford.edu/iiif/image-api/1.1/conformance.html#level1", z = "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", H = "http://iiif.io/api/image/1/level2.json", J = "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, z, H, J, G, K, Q], Me = [xe, Te, X, le, pe, V, ve, he, F, ue, fe, W, me, ge, z, de, ye, Ae, Ce, H, J, be, Re, Le, we, G, K, Ie, Se, Q], je = Me;
5
+ function d(t) {
6
6
  for (let e in t) (typeof t[e] > "u" || t[e] === null) && delete t[e];
7
7
  return t;
8
8
  }
9
9
  function w(t) {
10
10
  return Array.isArray(t) ? t : t ? [t] : [];
11
11
  }
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"];
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, R = (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
13
  function Oe(t) {
14
14
  if (typeof t > "u" || t === null) throw new Error("Null or undefined is not a valid entity.");
15
15
  if (Array.isArray(t)) throw new Error("Array is not a valid entity");
@@ -24,7 +24,7 @@ function Oe(t) {
24
24
  }
25
25
  var Ue = class Y {
26
26
  constructor(e, r = {}) {
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
+ R(this, "traversals"), R(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 };
28
28
  }
29
29
  static all(e) {
30
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] });
@@ -153,7 +153,7 @@ var Ue = class Y {
153
153
  return typeof n > "u" && !this.options.allowUndefinedReturn ? i : n;
154
154
  }, e);
155
155
  }
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" };
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", ze = "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", 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, ze, He, Je, Ge, Ke, Qe, Xe, Ye, Ze], k = { attributionLabel: "Attribution", providerId: "http://example.org/provider", providerName: "Unknown" };
157
157
  function it(t) {
158
158
  if (typeof t == "string") return [t];
159
159
  if (!t) return [];
@@ -308,13 +308,13 @@ function ee(t, e) {
308
308
  let r = encodeURI(t.id || t["@id"] || "").trim();
309
309
  return r && e ? `${r}/${e}` : r || (q++, `http://example.org/${t["@type"]}${e ? `/${e}` : ""}/${q}`);
310
310
  }
311
- function A(t) {
311
+ function C(t) {
312
312
  let e = [...t.behavior || []];
313
313
  t.viewingHint && e.push(t.viewingHint);
314
314
  let r;
315
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 };
316
316
  }
317
- function C(t) {
317
+ function b(t) {
318
318
  let [e, r] = lt(t.license), i = [...t.metadata ? ht(t.metadata) : [], ...r];
319
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) };
320
320
  }
@@ -333,21 +333,21 @@ function ft(t) {
333
333
  } else i["@id"] && r.push({ id: i["@id"], type: U(i) });
334
334
  return r.length ? r : void 0;
335
335
  }
336
- function R(t) {
336
+ function L(t) {
337
337
  let e = t.related ? Array.isArray(t.related) ? t.related : [t.related] : [], r = t.contentLayer;
338
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 };
339
339
  }
340
- function gt(t) {
340
+ function mt(t) {
341
341
  return { chars: t.chars, format: t.format ? t.format : void 0, language: t.language };
342
342
  }
343
- function mt(t) {
344
- return m({ ...A(t), ...C(t), ...R(t), items: t.members });
343
+ function gt(t) {
344
+ return d({ ...C(t), ...b(t), ...L(t), items: t.members });
345
345
  }
346
346
  function dt(t) {
347
347
  let e = [], r = [], i;
348
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);
349
- let s = A(t);
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) });
349
+ let s = C(t);
350
+ return r.length && (s.behavior ? s.behavior.push(...r) : s.behavior = r), d({ ...s, ...b(t), ...L(t), start: i, items: e, structures: yt(t.structures) });
351
351
  }
352
352
  function yt(t) {
353
353
  if (!t) return t;
@@ -361,10 +361,10 @@ function yt(t) {
361
361
  return t.filter((i) => r.indexOf(i.id) === -1);
362
362
  }
363
363
  function At(t) {
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 });
364
+ return d({ ...C(t), ...b(t), ...L(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 });
365
365
  }
366
366
  function Ct(t) {
367
- return m({ ...A(t), ...C(t), ...R(t), items: t.resources && t.resources.length ? t.resources : void 0 });
367
+ return d({ ...C(t), ...b(t), ...L(t), items: t.resources && t.resources.length ? t.resources : void 0 });
368
368
  }
369
369
  function bt(t) {
370
370
  return !t.canvases || t.canvases.length === 0 ? { canvases: [], behavior: [] } : { canvases: t.canvases, behavior: t.viewingHint ? [t.viewingHint] : [], startCanvas: t.startCanvas };
@@ -385,30 +385,30 @@ function Rt(t) {
385
385
  return { type: "SpecificResource", source: i, selector: P(r.selector) };
386
386
  } else return encodeURI(r["@id"]).trim();
387
387
  }
388
- return m({ ...A(t), ...C(t), ...R(t), target: e(t.on), body: Array.isArray(t.resource) ? t.resource.map(_) : _(t.resource) });
388
+ return d({ ...C(t), ...b(t), ...L(t), target: e(t.on), body: Array.isArray(t.resource) ? t.resource.map(_) : _(t.resource) });
389
389
  }
390
390
  function _(t) {
391
391
  return t.type === "Choice" ? t : te(t);
392
392
  }
393
393
  function te(t) {
394
394
  let e = t;
395
- return m({ ...A(e), ...C(e), ...R(e), ...gt(e) });
395
+ return d({ ...C(e), ...b(e), ...L(e), ...mt(e) });
396
396
  }
397
397
  function Lt(t) {
398
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 });
399
+ return t.default && t.default !== "rdf:nil" && e.push(t.default), t.item && t.item !== "rdf:nil" && e.push(...t.item), d({ ...C(t), ...b(t), items: e });
400
400
  }
401
401
  function wt(t) {
402
- return m({ ...A(t), ...C(t), ...R(t), items: t.members });
402
+ return d({ ...C(t), ...b(t), ...L(t), items: t.members });
403
403
  }
404
404
  function It(t) {
405
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 });
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)), d({ ...o, ...n });
407
407
  }
408
408
  function St(t) {
409
- return m({ ...A(t), ...C(t), ...R(t) });
409
+ return d({ ...C(t), ...b(t), ...L(t) });
410
410
  }
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
+ var xt = new Ue({ collection: [gt], manifest: [dt], canvas: [At], annotationList: [Ct], sequence: [bt], annotation: [Rt], contentResource: [te], choice: [Lt], range: [wt], service: [It], layer: [St] });
412
412
  function re(t) {
413
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;
414
414
  }
@@ -442,7 +442,7 @@ function Tt(t, e) {
442
442
  }
443
443
  var D = class ie {
444
444
  constructor(e, 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
+ R(this, "traversals"), R(this, "options"), R(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))), R(this, "_traverseCanvas", x(this.traverseCanvasItems.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this), this.traverseLinkedCanvases.bind(this), this.traverseInlineAnnotationPages.bind(this))), R(this, "_traverseAnnotationPage", x(this.traverseAnnotationPageItems.bind(this), this.traverseLinking.bind(this), this.traverseDescriptive.bind(this))), R(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 };
446
446
  }
447
447
  static all(e) {
448
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] });
@@ -571,12 +571,18 @@ const se = (t) => g(t, "type").startsWith("ImageService") || t.profile && t.prof
571
571
  return `${i}/full/full/0/default.jpg`;
572
572
  }
573
573
  return `${i}/full/!${e},${r}/0/default.jpg`;
574
- }, $t = (t, e, r) => {
574
+ }, $t = (t, e, r = { minSize: 400 }) => {
575
575
  const i = g(t, "id"), s = t.profile || "";
576
- if (typeof s == "string" && (s.includes("level0") || s.includes("level:0"))) return;
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)}`;
578
- return `${i}/${f}/!${p},${d}/0/default.jpg`;
579
- }, Mt = (t) => (e, r = 400) => {
576
+ if (typeof s == "string" && (s.includes("level0") || s.includes("level:0"))) {
577
+ console.warn(`Level 0 image service does not support custom region URLs: ${i}`);
578
+ return;
579
+ }
580
+ const { x: o, y: c, w: a, h: p } = e, { minSize: u = 400, maxSize: v } = r, m = a / p, l = m < 1;
581
+ let f = Math.ceil(l ? u / m : u), h = Math.ceil(l ? u : u / m);
582
+ v && (h > v || f > v) && (l ? (f = Math.min(f, v), h = Math.ceil(f * m)) : (h = Math.min(h, v), f = Math.ceil(h / m)));
583
+ const y = `${Math.round(o)},${Math.round(c)},${Math.round(a)},${Math.round(p)}`;
584
+ return `${i}/${y}/!${h},${f}/0/default.jpg`;
585
+ }, Mt = (t) => (e, r = { minSize: 400 }) => {
580
586
  if (t.type === "dynamic")
581
587
  return $t(t.service, e, r);
582
588
  console.error("Level 0 or static image canvas: unsupported");
@@ -585,19 +591,19 @@ const se = (t) => g(t, "type").startsWith("ImageService") || t.profile && t.prof
585
591
  if (!i || !s) return;
586
592
  const n = i / s, o = n < 1, c = Math.ceil(o ? r / n : r), a = Math.ceil(o ? r : r / n);
587
593
  if (t.thumbnail && t.thumbnail.length > 0) {
588
- const l = t.thumbnail[0];
589
- if ("service" in l && Array.isArray(l.service)) {
590
- const u = l.service.find((v) => se(v));
594
+ const p = t.thumbnail[0];
595
+ if ("service" in p && Array.isArray(p.service)) {
596
+ const u = p.service.find((v) => se(v));
591
597
  if (u)
592
598
  return O(u, a, c);
593
599
  }
594
- if ("id" in l) return l.id;
600
+ if ("id" in p) return p.id;
595
601
  }
596
- for (const l of e) {
597
- if (l.type === "dynamic" || l.type === "level0")
598
- return O(l.service, a, c);
599
- if (l.type === "static")
600
- return l.url;
602
+ for (const p of e) {
603
+ if (p.type === "dynamic" || p.type === "level0")
604
+ return O(p.service, a, c);
605
+ if (p.type === "static")
606
+ return p.url;
601
607
  }
602
608
  }, ae = (t) => t.endsWith("/info.json") ? t : `${t.endsWith("/") ? t : `${t}/`}info.json`, kt = (t, e, r) => (i = 800) => {
603
609
  if (!t || !e) return;
@@ -652,7 +658,7 @@ const se = (t) => g(t, "type").startsWith("ImageService") || t.profile && t.prof
652
658
  }]
653
659
  }).traverseCanvas(t), e;
654
660
  }, Nt = (t) => () => {
655
- const e = /* @__PURE__ */ new Map(), r = (a, l, u = 0) => {
661
+ const e = /* @__PURE__ */ new Map(), r = (a, p, u = 0) => {
656
662
  const v = {
657
663
  id: a.id,
658
664
  type: "range",
@@ -660,7 +666,7 @@ const se = (t) => g(t, "type").startsWith("ImageService") || t.profile && t.prof
660
666
  children: [],
661
667
  navItems: [],
662
668
  navSections: [],
663
- parent: l,
669
+ parent: p,
664
670
  level: u,
665
671
  getLabel: a.getLabel
666
672
  };
@@ -669,7 +675,7 @@ const se = (t) => g(t, "type").startsWith("ImageService") || t.profile && t.prof
669
675
  const T = r(h, v, u + 1);
670
676
  v.children.push(T);
671
677
  } else {
672
- const L = {
678
+ const y = {
673
679
  id: h.id,
674
680
  type: "canvas",
675
681
  source: h,
@@ -680,23 +686,23 @@ const se = (t) => g(t, "type").startsWith("ImageService") || t.profile && t.prof
680
686
  level: u + 1,
681
687
  getLabel: h.getLabel
682
688
  };
683
- v.children.push(L), e.set(L.id, L);
689
+ v.children.push(y), e.set(y.id, y);
684
690
  }
685
691
  });
686
- const d = v.children.map((h) => h.type === "canvas" ? h.source : h.children.length === 1 && h.children[0].type === "canvas" ? h.children[0].source : h.source), p = d.filter((h) => h.source.type === "Canvas"), f = d.filter((h) => h.source.type === "Range");
687
- return v.navItems.push(...p), v.navSections.push(...f), e.set(v.id, v), v;
692
+ const m = v.children.map((h) => h.type === "canvas" ? h.source : h.children.length === 1 && h.children[0].type === "canvas" ? h.children[0].source : h.source), l = m.filter((h) => h.source.type === "Canvas"), f = m.filter((h) => h.source.type === "Range");
693
+ return v.navItems.push(...l), v.navSections.push(...f), e.set(v.id, v), v;
688
694
  };
689
695
  return { root: t.filter((a) => {
690
- var l;
691
- return (l = a.source.behavior) == null ? void 0 : l.includes("top");
696
+ var p;
697
+ return (p = a.source.behavior) == null ? void 0 : p.includes("top");
692
698
  }).map((a) => r(a, void 0)), enumerateNodes: (a) => {
693
- const l = Array.from(e.values());
694
- return a ? l.filter((u) => u.type === a) : l;
699
+ const p = Array.from(e.values());
700
+ return a ? p.filter((u) => u.type === a) : p;
695
701
  }, getBreadcrumbs: (a) => {
696
- const l = e.get(a);
697
- if (!l) return [];
698
- const u = (v, d = []) => v.parent ? u(v.parent, [v, ...d]) : [v, ...d];
699
- return u(l);
702
+ const p = e.get(a);
703
+ if (!p) return [];
704
+ const u = (v, m = []) => v.parent ? u(v.parent, [v, ...m]) : [v, ...m];
705
+ return u(p);
700
706
  }, getNode: (a) => e.get(a) };
701
707
  }, Et = async (t) => {
702
708
  try {
@@ -812,41 +818,41 @@ const se = (t) => g(t, "type").startsWith("ImageService") || t.profile && t.prof
812
818
  const r = (o) => {
813
819
  const c = [], a = [];
814
820
  new D({
815
- canvas: [(p) => {
816
- p.items && c.push(p);
821
+ canvas: [(l) => {
822
+ l.items && c.push(l);
817
823
  }],
818
- range: [(p) => {
819
- p.type === "Range" && a.push(p);
824
+ range: [(l) => {
825
+ l.type === "Range" && a.push(l);
820
826
  }]
821
827
  }).traverseManifest(o);
822
- const u = c.map((p) => {
823
- const f = Dt(p);
828
+ const u = c.map((l) => {
829
+ const f = Dt(l);
824
830
  return {
825
- source: p,
826
- id: p.id,
827
- width: p.width,
828
- height: p.height,
831
+ source: l,
832
+ id: l.id,
833
+ width: l.width,
834
+ height: l.height,
829
835
  images: f,
830
- annotations: p.annotations || [],
836
+ annotations: l.annotations || [],
831
837
  getImageURL: f.length > 0 ? f[0].getImageURL : () => {
832
838
  },
833
- getLabel: S(p),
834
- getMetadata: j(p),
835
- getThumbnailURL: jt(p, f)
839
+ getLabel: S(l),
840
+ getMetadata: j(l),
841
+ getThumbnailURL: jt(l, f)
836
842
  };
837
- }), v = (p) => {
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];
843
+ }), v = (l) => {
844
+ const f = l.items || [], h = f.filter((A) => A.type === "Canvas").map((A) => u.find(($) => $.id === A.id)).filter(Boolean), y = f.filter((A) => A.type === "Range").map((A) => v(A)), T = [...h, ...y];
839
845
  return {
840
- source: p,
841
- id: p.id,
846
+ source: l,
847
+ id: l.id,
842
848
  // Maintain original order
843
- items: f.map((y) => T.find(($) => $.id === y.id)),
849
+ items: f.map((A) => T.find(($) => $.id === A.id)),
844
850
  canvases: h,
845
- ranges: L,
846
- getLabel: S(p)
851
+ ranges: y,
852
+ getLabel: S(l)
847
853
  };
848
- }, d = a.map((p) => v(p));
849
- return { canvases: u, ranges: d };
854
+ }, m = a.map((l) => v(l));
855
+ return { canvases: u, ranges: m };
850
856
  }, i = e === 2 ? re(t) : t, { canvases: s, ranges: n } = r(i);
851
857
  return {
852
858
  source: i,
@@ -879,7 +885,7 @@ export {
879
885
  g as getPropertyValue,
880
886
  Mt as getRegionURL,
881
887
  $t as getRegionURLFromService,
882
- zt as getStringValue,
888
+ Jt as getStringValue,
883
889
  Nt as getTableOfContents,
884
890
  jt as getThumbnailURL,
885
891
  se as isImageService,
package/dist/types.d.ts CHANGED
@@ -109,7 +109,7 @@ export interface DynamicImageServiceResource extends BaseImageResource {
109
109
  readonly service: Service;
110
110
  readonly serviceUrl: string;
111
111
  readonly majorVersion: number;
112
- getRegionURL(bounds: Bounds, minSize?: number): string;
112
+ getRegionURL(bounds: Bounds, opts?: GetRegionURLOpts): string;
113
113
  }
114
114
  export interface Level0ImageServiceResource extends BaseImageResource {
115
115
  readonly type: 'level0';
@@ -135,4 +135,8 @@ export interface Bounds {
135
135
  w: number;
136
136
  h: number;
137
137
  }
138
+ export interface GetRegionURLOpts {
139
+ minSize?: number;
140
+ maxSize?: number;
141
+ }
138
142
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-iiif",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
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",
@@ -1,6 +1,6 @@
1
1
  import type { ImageService2, ImageService3, Service } from '@iiif/presentation-3';
2
2
  import { getPropertyValue } from './resource';
3
- import type { Bounds, CozyImageResource } from '../types';
3
+ import type { Bounds, CozyImageResource, GetRegionURLOpts } from '../types';
4
4
 
5
5
  type ImageService = ImageService2 | ImageService3;
6
6
 
@@ -68,7 +68,7 @@ export const getImageURLFromService = (
68
68
  export const getRegionURLFromService = (
69
69
  service: Service,
70
70
  bounds: Bounds,
71
- minSize: number
71
+ opts: GetRegionURLOpts = { minSize: 400 }
72
72
  ): string | undefined => {
73
73
  const id = getPropertyValue(service, 'id');
74
74
  const compliance = service.profile || '';
@@ -76,16 +76,32 @@ export const getRegionURLFromService = (
76
76
  const isLevel0 = typeof compliance === 'string' &&
77
77
  (compliance.includes('level0') || compliance.includes('level:0'));
78
78
 
79
- // TODO
80
- if (isLevel0) return;
79
+ if (isLevel0) {
80
+ console.warn(`Level 0 image service does not support custom region URLs: ${id}`);
81
+ return;
82
+ }
81
83
 
82
84
  const { x, y, w , h } = bounds;
85
+ const { minSize = 400, maxSize } = opts;
83
86
 
84
87
  const aspect = w / h;
85
88
  const isPortrait = aspect < 1;
86
89
 
87
- const height = Math.ceil(isPortrait ? minSize / aspect : minSize);
88
- const width = Math.ceil(isPortrait ? minSize : minSize / aspect);
90
+ let height = Math.ceil(isPortrait ? minSize / aspect : minSize);
91
+ let width = Math.ceil(isPortrait ? minSize : minSize / aspect);
92
+
93
+ // Apply maxSize constraint if specified
94
+ if (maxSize) {
95
+ if (width > maxSize || height > maxSize) {
96
+ if (isPortrait) {
97
+ height = Math.min(height, maxSize);
98
+ width = Math.ceil(height * aspect);
99
+ } else {
100
+ width = Math.min(width, maxSize);
101
+ height = Math.ceil(width / aspect);
102
+ }
103
+ }
104
+ }
89
105
 
90
106
  const regionParam = `${Math.round(x)},${Math.round(y)},${Math.round(w)},${Math.round(h)}`;
91
107
  return `${id}/${regionParam}/!${width},${height}/0/default.jpg`;
@@ -95,10 +111,10 @@ export const getRegionURL = (
95
111
  image: CozyImageResource
96
112
  ) => (
97
113
  bounds: Bounds,
98
- minSize = 400
114
+ opts: GetRegionURLOpts = { minSize: 400 }
99
115
  ): string | undefined => {
100
116
  if (image.type === 'dynamic') {
101
- return getRegionURLFromService(image.service, bounds, minSize);
117
+ return getRegionURLFromService(image.service, bounds, opts);
102
118
  } else {
103
119
  console.error('Level 0 or static image canvas: unsupported');
104
120
  }
package/src/types.ts CHANGED
@@ -192,7 +192,7 @@ export interface DynamicImageServiceResource extends BaseImageResource {
192
192
 
193
193
  readonly majorVersion: number;
194
194
 
195
- getRegionURL(bounds: Bounds, minSize?: number): string;
195
+ getRegionURL(bounds: Bounds, opts?: GetRegionURLOpts): string;
196
196
 
197
197
  }
198
198
 
@@ -233,4 +233,12 @@ export interface Bounds {
233
233
 
234
234
  h: number;
235
235
 
236
+ }
237
+
238
+ export interface GetRegionURLOpts {
239
+
240
+ minSize?: number;
241
+
242
+ maxSize?: number;
243
+
236
244
  }