diff --git a/__tests__/fixtures/bride-diff.json b/__tests__/fixtures/bride-diff.json
new file mode 100644
index 0000000..6cb3428
--- /dev/null
+++ b/__tests__/fixtures/bride-diff.json
@@ -0,0 +1,596 @@
+{
+ "@context": "http://iiif.io/api/presentation/3/context.json",
+ "type": "Manifest",
+ "id": "http://localhost/Item/vudl:173/Manifest",
+ "label": {
+ "en": [
+ "The bride of the tomb ; and, Queenie's terrible secret / by Mrs. Alex. McVeigh Miller."
+ ]
+ },
+ "metadata": [
+ {
+ "label": {
+ "en": ["Full Title"]
+ },
+ "value": {
+ "en": [
+ "The bride of the tomb ; and, Queenie's terrible secret / by Mrs. Alex. McVeigh Miller."
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Author"]
+ },
+ "value": {
+ "en": [
+ "Miller, Alex. McVeigh, Mrs."
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Contributor"]
+ },
+ "value": {
+ "en": [
+ "Street and Smith Publications."
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Date Added"]
+ },
+ "value": {
+ "en": ["2 October 2025"]
+ }
+ },
+ {
+ "label": {
+ "en": ["Format"]
+ },
+ "value": {
+ "en": [
+ "Book"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Language"]
+ },
+ "value": {
+ "en": [
+ "English"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Publish Date"]
+ },
+ "value": {
+ "en": [
+ "1883"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Publisher"]
+ },
+ "value": {
+ "en": [
+ "New York : Street & Smith"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Series"]
+ },
+ "value": {
+ "en": [
+ "Eagle series > no. 426"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Source"]
+ },
+ "value": {
+ "en": [
+ "Dime Novel and Popular Literature"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Alternate Title"]
+ },
+ "value": {
+ "en": [
+ "Queenie's terrible secret"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Topic"]
+ },
+ "value": {
+ "en": [
+ "Popular literature > Specimens.
Dime novels > Specimens."
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["About"]
+ },
+ "value": {
+ "en": [
+ "More Details
Permanent Link"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Description"]
+ },
+ "value": "fnord"
+ }
+ ],
+ "summary": {
+ "en": ["Bride of the Tomb"]
+ },
+ "requiredStatement": {
+ "label": {
+ "en": ["ATTRIBUTION"]
+ },
+ "value": {
+ "en": [
+ "Digital Library@Villanova University
Disclaimers:
Disclaimer of Liability
Disclaimer of Endorsement
License:
Rights Information"
+ ]
+ }
+ },
+ "seeAlso": [
+ {
+ "id": "http://localhost/Item/vudl:173",
+ "type": "Text",
+ "format": "text/html",
+ "label": {
+ "en": ["More Details"]
+ }
+ }
+ ],
+ "items": [
+ {
+ "type": "Canvas",
+ "id": "http://localhost/Item/vudl:173/Canvas/p0",
+ "label": {
+ "en": ["Front cover"]
+ },
+ "rendering": [
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:175/MASTER",
+ "format": "image/tiff",
+ "label": {
+ "en": ["Original source file - 20.63 MB"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:175/OCR-DIRTY",
+ "format": "text/plain",
+ "label": {
+ "en": ["Raw OCR Data"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:175/MASTER-MD",
+ "format": "application/xml",
+ "label": {
+ "en": ["Technical Metadata"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:181/MASTER",
+ "format": "application/pdf",
+ "label": {
+ "en": ["PDF"]
+ }
+ }
+ ],
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:175/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ],
+ "height": 3110,
+ "width": 2318,
+ "items": [
+ {
+ "id": "http://localhost/Record/vudl:173",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "http://localhost/files/vudl:175/LARGE",
+ "type": "Annotation",
+ "motivation": "painting",
+ "body": {
+ "id": "http://localhost:8182/iiif/2/vudl%3A175",
+ "type": "Image",
+ "format": "image/jpeg",
+ "service": [
+ {
+ "id": "http://localhost:8182/iiif/2/vudl%3A175",
+ "type": "ImageService3",
+ "profile": "level1"
+ }
+ ]
+ },
+ "height": 3110,
+ "width": 2318,
+ "target": "http://localhost/Item/vudl:173/Canvas/p0",
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:175/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "Canvas",
+ "id": "http://localhost/Item/vudl:173/Canvas/p1",
+ "label": {
+ "en": ["Inside front cover"]
+ },
+ "rendering": [
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:176/MASTER",
+ "format": "image/tiff",
+ "label": {
+ "en": ["Original source file - 19.00 MB"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:176/OCR-DIRTY",
+ "format": "text/plain",
+ "label": {
+ "en": ["Raw OCR Data"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:176/MASTER-MD",
+ "format": "application/xml",
+ "label": {
+ "en": ["Technical Metadata"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:181/MASTER",
+ "format": "application/pdf",
+ "label": {
+ "en": ["PDF"]
+ }
+ }
+ ],
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:176/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ],
+ "height": 3055,
+ "width": 2174,
+ "items": [
+ {
+ "id": "http://localhost/Record/vudl:173",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "http://localhost/files/vudl:176/LARGE",
+ "type": "Annotation",
+ "motivation": "painting",
+ "body": {
+ "id": "http://localhost:8182/iiif/2/vudl%3A176",
+ "type": "Image",
+ "format": "image/jpeg",
+ "service": [
+ {
+ "id": "http://localhost:8182/iiif/2/vudl%3A176",
+ "type": "ImageService3",
+ "profile": "level1"
+ }
+ ]
+ },
+ "height": 3055,
+ "width": 2174,
+ "target": "http://localhost/Item/vudl:173/Canvas/p1",
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:176/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "Canvas",
+ "id": "http://localhost/Item/vudl:173/Canvas/p2",
+ "label": {
+ "en": ["[i]"]
+ },
+ "rendering": [
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:177/MASTER",
+ "format": "image/tiff",
+ "label": {
+ "en": ["Original source file - 18.24 MB"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:177/OCR-DIRTY",
+ "format": "text/plain",
+ "label": {
+ "en": ["Raw OCR Data"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:177/MASTER-MD",
+ "format": "application/xml",
+ "label": {
+ "en": ["Technical Metadata"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:181/MASTER",
+ "format": "application/pdf",
+ "label": {
+ "en": ["PDF"]
+ }
+ }
+ ],
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:177/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ],
+ "height": 3040,
+ "width": 2097,
+ "items": [
+ {
+ "id": "http://localhost/Record/vudl:173",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "http://localhost/files/vudl:177/LARGE",
+ "type": "Annotation",
+ "motivation": "painting",
+ "body": {
+ "id": "http://localhost:8182/iiif/2/vudl%3A177",
+ "type": "Image",
+ "format": "image/jpeg",
+ "service": [
+ {
+ "id": "http://localhost:8182/iiif/2/vudl%3A177",
+ "type": "ImageService3",
+ "profile": "level1"
+ }
+ ]
+ },
+ "height": 3040,
+ "width": 2097,
+ "target": "http://localhost/Item/vudl:173/Canvas/p2",
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:177/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "Canvas",
+ "id": "http://localhost/Item/vudl:173/Canvas/p3",
+ "label": {
+ "en": ["[ii]"]
+ },
+ "rendering": [
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:178/MASTER",
+ "format": "image/tiff",
+ "label": {
+ "en": ["Original source file - 18.92 MB"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:178/OCR-DIRTY",
+ "format": "text/plain",
+ "label": {
+ "en": ["Raw OCR Data"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:178/MASTER-MD",
+ "format": "application/xml",
+ "label": {
+ "en": ["Technical Metadata"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:181/MASTER",
+ "format": "application/pdf",
+ "label": {
+ "en": ["PDF"]
+ }
+ }
+ ],
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:178/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ],
+ "height": 3040,
+ "width": 2175,
+ "items": [
+ {
+ "id": "http://localhost/Record/vudl:173",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "http://localhost/files/vudl:178/LARGE",
+ "type": "Annotation",
+ "motivation": "painting",
+ "body": {
+ "id": "http://localhost:8182/iiif/2/vudl%3A178",
+ "type": "Image",
+ "format": "image/jpeg",
+ "service": [
+ {
+ "id": "http://localhost:8182/iiif/2/vudl%3A178",
+ "type": "ImageService3",
+ "profile": "level1"
+ }
+ ]
+ },
+ "height": 3040,
+ "width": 2175,
+ "target": "http://localhost/Item/vudl:173/Canvas/p3",
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:178/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "Canvas",
+ "id": "http://localhost/Item/vudl:173/Canvas/p4",
+ "label": {
+ "en": ["[iii]"]
+ },
+ "rendering": [
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:179/MASTER",
+ "format": "image/tiff",
+ "label": {
+ "en": ["Original source file - 18.40 MB"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:179/OCR-DIRTY",
+ "format": "text/plain",
+ "label": {
+ "en": ["Raw OCR Data"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:179/MASTER-MD",
+ "format": "application/xml",
+ "label": {
+ "en": ["Technical Metadata"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:181/MASTER",
+ "format": "application/pdf",
+ "label": {
+ "en": ["PDF"]
+ }
+ }
+ ],
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:179/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ],
+ "height": 3040,
+ "width": 2115,
+ "items": [
+ {
+ "id": "http://localhost/Record/vudl:173",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "http://localhost/files/vudl:179/LARGE",
+ "type": "Annotation",
+ "motivation": "painting",
+ "body": {
+ "id": "http://localhost:8182/iiif/2/vudl%3A179",
+ "type": "Image",
+ "format": "image/jpeg",
+ "service": [
+ {
+ "id": "http://localhost:8182/iiif/2/vudl%3A179",
+ "type": "ImageService3",
+ "profile": "level1"
+ }
+ ]
+ },
+ "height": 3040,
+ "width": 2115,
+ "target": "http://localhost/Item/vudl:173/Canvas/p4",
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:179/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/__tests__/fixtures/bride-match.json b/__tests__/fixtures/bride-match.json
new file mode 100644
index 0000000..049de55
--- /dev/null
+++ b/__tests__/fixtures/bride-match.json
@@ -0,0 +1,598 @@
+{
+ "@context": "http://iiif.io/api/presentation/3/context.json",
+ "type": "Manifest",
+ "id": "http://localhost/Item/vudl:173/Manifest",
+ "label": {
+ "en": [
+ "The bride of the tomb ; and, Queenie's terrible secret / by Mrs. Alex. McVeigh Miller."
+ ]
+ },
+ "metadata": [
+ {
+ "label": {
+ "en": ["Full Title"]
+ },
+ "value": {
+ "en": [
+ "The bride of the tomb ; and, Queenie's terrible secret / by Mrs. Alex. McVeigh Miller."
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Author"]
+ },
+ "value": {
+ "en": [
+ "Miller, Alex. McVeigh, Mrs."
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Contributor"]
+ },
+ "value": {
+ "en": [
+ "Street and Smith Publications."
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Date Added"]
+ },
+ "value": {
+ "en": ["2 October 2025"]
+ }
+ },
+ {
+ "label": {
+ "en": ["Format"]
+ },
+ "value": {
+ "en": [
+ "Book"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Language"]
+ },
+ "value": {
+ "en": [
+ "English"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Publish Date"]
+ },
+ "value": {
+ "en": [
+ "1883"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Publisher"]
+ },
+ "value": {
+ "en": [
+ "New York : Street & Smith"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Series"]
+ },
+ "value": {
+ "en": [
+ "Eagle series > no. 426"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Source"]
+ },
+ "value": {
+ "en": [
+ "Dime Novel and Popular Literature"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Alternate Title"]
+ },
+ "value": {
+ "en": [
+ "Queenie's terrible secret"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Topic"]
+ },
+ "value": {
+ "en": [
+ "Popular literature > Specimens.
Dime novels > Specimens."
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["About"]
+ },
+ "value": {
+ "en": [
+ "More Details
Permanent Link"
+ ]
+ }
+ },
+ {
+ "label": {
+ "en": ["Description"]
+ },
+ "value": {
+ "en": ["Bride of the Tomb"]
+ }
+ }
+ ],
+ "summary": {
+ "en": ["Bride of the Tomb"]
+ },
+ "requiredStatement": {
+ "label": {
+ "en": ["ATTRIBUTION"]
+ },
+ "value": {
+ "en": [
+ "Digital Library@Villanova University
Disclaimers:
Disclaimer of Liability
Disclaimer of Endorsement
License:
Rights Information"
+ ]
+ }
+ },
+ "seeAlso": [
+ {
+ "id": "http://localhost/Item/vudl:173",
+ "type": "Text",
+ "format": "text/html",
+ "label": {
+ "en": ["More Details"]
+ }
+ }
+ ],
+ "items": [
+ {
+ "type": "Canvas",
+ "id": "http://localhost/Item/vudl:173/Canvas/p0",
+ "label": {
+ "en": ["Front cover"]
+ },
+ "rendering": [
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:175/MASTER",
+ "format": "image/tiff",
+ "label": {
+ "en": ["Original source file - 20.63 MB"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:175/OCR-DIRTY",
+ "format": "text/plain",
+ "label": {
+ "en": ["Raw OCR Data"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:175/MASTER-MD",
+ "format": "application/xml",
+ "label": {
+ "en": ["Technical Metadata"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:181/MASTER",
+ "format": "application/pdf",
+ "label": {
+ "en": ["PDF"]
+ }
+ }
+ ],
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:175/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ],
+ "height": 3110,
+ "width": 2318,
+ "items": [
+ {
+ "id": "http://localhost/Record/vudl:173",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "http://localhost/files/vudl:175/LARGE",
+ "type": "Annotation",
+ "motivation": "painting",
+ "body": {
+ "id": "http://localhost:8182/iiif/2/vudl%3A175",
+ "type": "Image",
+ "format": "image/jpeg",
+ "service": [
+ {
+ "id": "http://localhost:8182/iiif/2/vudl%3A175",
+ "type": "ImageService3",
+ "profile": "level1"
+ }
+ ]
+ },
+ "height": 3110,
+ "width": 2318,
+ "target": "http://localhost/Item/vudl:173/Canvas/p0",
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:175/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "Canvas",
+ "id": "http://localhost/Item/vudl:173/Canvas/p1",
+ "label": {
+ "en": ["Inside front cover"]
+ },
+ "rendering": [
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:176/MASTER",
+ "format": "image/tiff",
+ "label": {
+ "en": ["Original source file - 19.00 MB"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:176/OCR-DIRTY",
+ "format": "text/plain",
+ "label": {
+ "en": ["Raw OCR Data"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:176/MASTER-MD",
+ "format": "application/xml",
+ "label": {
+ "en": ["Technical Metadata"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:181/MASTER",
+ "format": "application/pdf",
+ "label": {
+ "en": ["PDF"]
+ }
+ }
+ ],
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:176/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ],
+ "height": 3055,
+ "width": 2174,
+ "items": [
+ {
+ "id": "http://localhost/Record/vudl:173",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "http://localhost/files/vudl:176/LARGE",
+ "type": "Annotation",
+ "motivation": "painting",
+ "body": {
+ "id": "http://localhost:8182/iiif/2/vudl%3A176",
+ "type": "Image",
+ "format": "image/jpeg",
+ "service": [
+ {
+ "id": "http://localhost:8182/iiif/2/vudl%3A176",
+ "type": "ImageService3",
+ "profile": "level1"
+ }
+ ]
+ },
+ "height": 3055,
+ "width": 2174,
+ "target": "http://localhost/Item/vudl:173/Canvas/p1",
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:176/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "Canvas",
+ "id": "http://localhost/Item/vudl:173/Canvas/p2",
+ "label": {
+ "en": ["[i]"]
+ },
+ "rendering": [
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:177/MASTER",
+ "format": "image/tiff",
+ "label": {
+ "en": ["Original source file - 18.24 MB"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:177/OCR-DIRTY",
+ "format": "text/plain",
+ "label": {
+ "en": ["Raw OCR Data"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:177/MASTER-MD",
+ "format": "application/xml",
+ "label": {
+ "en": ["Technical Metadata"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:181/MASTER",
+ "format": "application/pdf",
+ "label": {
+ "en": ["PDF"]
+ }
+ }
+ ],
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:177/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ],
+ "height": 3040,
+ "width": 2097,
+ "items": [
+ {
+ "id": "http://localhost/Record/vudl:173",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "http://localhost/files/vudl:177/LARGE",
+ "type": "Annotation",
+ "motivation": "painting",
+ "body": {
+ "id": "http://localhost:8182/iiif/2/vudl%3A177",
+ "type": "Image",
+ "format": "image/jpeg",
+ "service": [
+ {
+ "id": "http://localhost:8182/iiif/2/vudl%3A177",
+ "type": "ImageService3",
+ "profile": "level1"
+ }
+ ]
+ },
+ "height": 3040,
+ "width": 2097,
+ "target": "http://localhost/Item/vudl:173/Canvas/p2",
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:177/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "Canvas",
+ "id": "http://localhost/Item/vudl:173/Canvas/p3",
+ "label": {
+ "en": ["[ii]"]
+ },
+ "rendering": [
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:178/MASTER",
+ "format": "image/tiff",
+ "label": {
+ "en": ["Original source file - 18.92 MB"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:178/OCR-DIRTY",
+ "format": "text/plain",
+ "label": {
+ "en": ["Raw OCR Data"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:178/MASTER-MD",
+ "format": "application/xml",
+ "label": {
+ "en": ["Technical Metadata"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:181/MASTER",
+ "format": "application/pdf",
+ "label": {
+ "en": ["PDF"]
+ }
+ }
+ ],
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:178/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ],
+ "height": 3040,
+ "width": 2175,
+ "items": [
+ {
+ "id": "http://localhost/Record/vudl:173",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "http://localhost/files/vudl:178/LARGE",
+ "type": "Annotation",
+ "motivation": "painting",
+ "body": {
+ "id": "http://localhost:8182/iiif/2/vudl%3A178",
+ "type": "Image",
+ "format": "image/jpeg",
+ "service": [
+ {
+ "id": "http://localhost:8182/iiif/2/vudl%3A178",
+ "type": "ImageService3",
+ "profile": "level1"
+ }
+ ]
+ },
+ "height": 3040,
+ "width": 2175,
+ "target": "http://localhost/Item/vudl:173/Canvas/p3",
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:178/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "Canvas",
+ "id": "http://localhost/Item/vudl:173/Canvas/p4",
+ "label": {
+ "en": ["[iii]"]
+ },
+ "rendering": [
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:179/MASTER",
+ "format": "image/tiff",
+ "label": {
+ "en": ["Original source file - 18.40 MB"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:179/OCR-DIRTY",
+ "format": "text/plain",
+ "label": {
+ "en": ["Raw OCR Data"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:179/MASTER-MD",
+ "format": "application/xml",
+ "label": {
+ "en": ["Technical Metadata"]
+ }
+ },
+ {
+ "type": "rendering",
+ "id": "http://localhost/files/vudl:181/MASTER",
+ "format": "application/pdf",
+ "label": {
+ "en": ["PDF"]
+ }
+ }
+ ],
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:179/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ],
+ "height": 3040,
+ "width": 2115,
+ "items": [
+ {
+ "id": "http://localhost/Record/vudl:173",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "http://localhost/files/vudl:179/LARGE",
+ "type": "Annotation",
+ "motivation": "painting",
+ "body": {
+ "id": "http://localhost:8182/iiif/2/vudl%3A179",
+ "type": "Image",
+ "format": "image/jpeg",
+ "service": [
+ {
+ "id": "http://localhost:8182/iiif/2/vudl%3A179",
+ "type": "ImageService3",
+ "profile": "level1"
+ }
+ ]
+ },
+ "height": 3040,
+ "width": 2115,
+ "target": "http://localhost/Item/vudl:173/Canvas/p4",
+ "thumbnail": [
+ {
+ "id": "http://localhost/files/vudl:179/THUMBNAIL",
+ "type": "Image",
+ "format": "image/png"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/__tests__/helper.test.ts b/__tests__/helper.test.ts
index 9f85496..dfc4de1 100644
--- a/__tests__/helper.test.ts
+++ b/__tests__/helper.test.ts
@@ -8,6 +8,8 @@ const searchService2 = require("./fixtures/search-service-2.json");
const riksarkivetAltoAnnotations = require("./fixtures/riksarkivet.json");
const cookbookAnnotationsEmbedded = require("./fixtures/cookbook-annotations-embedded.json");
const wunder = require("./fixtures/wunder-pres2.json");
+const brideMatch = require("./fixtures/bride-match.json");
+const brideDiff = require("./fixtures/bride-diff.json");
function mockFetch(status: number, data?: any) {
const xhrMockObj = {
@@ -33,7 +35,62 @@ function mockFetch(status: number, data?: any) {
}, 0);
}
+function getMetadataValue(metadataGroups: any[], metaLabel: string) {
+ const metaValue: any[] = [];
+ metadataGroups.forEach((group) => {
+ group.items.forEach((item) => {
+ const labelText =
+ item.label?.getValue?.("en-GB") ??
+ item.label?.getValue?.() ??
+ item.label?.toString?.();
+ if (labelText && labelText.trim().toLowerCase() === metaLabel) {
+ metaValue.push(
+ item.value?.getValue?.("en-GB") ??
+ item.value?.getValue?.() ??
+ item.value?.toString?.()
+ );
+ }
+ });
+ });
+ return metaValue;
+}
+
describe("Helper", () => {
+ test("getMetadata records summary as description when duplicate value present in metadata for brideMatch manifest", async () => {
+ const helper = await loadManifestJson(brideMatch, {
+ manifestUri: brideMatch.id,
+ locale: "cy",
+ });
+ const metadataGroups = helper.getMetadata();
+ const summary = getMetadataValue(metadataGroups, "summary");
+ const description = getMetadataValue(metadataGroups, "description");
+ expect(description).toEqual(["Bride of the Tomb"]);
+ expect(summary).toEqual([]);
+ });
+
+ test("getMetadata records summary as summary when no duplicate value present in metadata for brideDiff manifest", async () => {
+ const helper = await loadManifestJson(brideDiff, {
+ manifestUri: brideDiff.id,
+ });
+ const metadataGroups = helper.getMetadata();
+ const summary = getMetadataValue(metadataGroups, "summary");
+ const description = getMetadataValue(metadataGroups, "description");
+ expect(description).toEqual(["fnord"]);
+ expect(summary).toEqual(["Bride of the Tomb"]);
+ });
+
+ test("getMetadata records summary as Description when locale is not En in metadata for brideDiff manifest", async () => {
+ const helper = await loadManifestJson(brideDiff, {
+ manifestUri: brideDiff.id,
+ locale: "cy",
+ });
+ const metadataGroups = helper.getMetadata();
+ const summary = getMetadataValue(metadataGroups, "summary");
+ const description = getMetadataValue(metadataGroups, "description");
+ expect(description).toEqual(["fnord", "Bride of the Tomb"]);
+ expect(summary).toEqual([]);
+ });
+
test("hasAnnotations returns true for single seeAlso object on pres2 manifest", async () => {
const helper = await loadManifestJson(wunder, {
manifestUri: wunder.id,
diff --git a/src/Helper.ts b/src/Helper.ts
index a342e40..853665a 100644
--- a/src/Helper.ts
+++ b/src/Helper.ts
@@ -211,6 +211,9 @@ export class Helper {
return this.getSequenceByIndex(this.sequenceIndex as number);
}
+ /**
+ * @deprecated Use getSummary instead
+ */
public getDescription(): string | null {
if (!this.manifest) {
throw new Error(Errors.manifestNotLoaded);
@@ -225,6 +228,20 @@ export class Helper {
return null;
}
+ public getSummary(): string | null {
+ if (!this.manifest) {
+ throw new Error(Errors.manifestNotLoaded);
+ }
+
+ const summary = this.manifest.getSummary();
+
+ if (summary) {
+ return summary.getValue(this.options.locale);
+ }
+
+ return null;
+ }
+
public getLabel(): string | null {
if (!this.manifest) {
throw new Error(Errors.manifestNotLoaded);
@@ -304,14 +321,36 @@ export class Helper {
manifestGroup.addMetadata(manifestMetadata, true);
}
- if (this.manifest.getDescription().length) {
- const metadataItem: LabelValuePair = new LabelValuePair(locale);
- metadataItem.label = new PropertyValue([
- new LocalizedValue("description", locale),
- ]);
- metadataItem.value = this.manifest.getDescription();
- (metadataItem).isRootLevel = true;
- manifestGroup.addItem(metadataItem);
+ // include summary if no description in metadata
+ const summaryText = String(
+ (this.manifest.getSummary() as any).getValue(locale) || ""
+ ).trim();
+ if (summaryText.length > 0) {
+ let descriptionMatches = false;
+ let description = "";
+ for (let i = 0; i < manifestMetadata.length; i++) {
+ const item = manifestMetadata[i];
+ description = String((item as any).getValue(locale) || "").trim();
+ if (description.length > 0 && summaryText === description) {
+ descriptionMatches = true;
+ break;
+ }
+ }
+
+ if (!descriptionMatches) {
+ // If the locale is set to English, describe this as "Summary." Use the legacy "description" for
+ // other languages to ensure back-compatibility with existing i18n. We may wish to revisit
+ // this in the future!
+ const isNonEnglish = (locale || "").split("-")[0] !== "en";
+ const labelText = isNonEnglish ? "description" : "Summary";
+ const metadataItem: LabelValuePair = new LabelValuePair(locale);
+ metadataItem.label = new PropertyValue([
+ new LocalizedValue(labelText, locale),
+ ]);
+ metadataItem.value = this.manifest.getSummary();
+ (metadataItem).isRootLevel = true;
+ manifestGroup.addItem(metadataItem);
+ }
}
if (this.manifest.getAttribution().length) {