@paulhectork/aiiinotate 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +206 -0
- package/cli/export.js +118 -0
- package/cli/import.js +111 -0
- package/cli/index.js +45 -0
- package/cli/migrate.js +131 -0
- package/cli/serve.js +29 -0
- package/cli/utils/fastifyClient.js +86 -0
- package/cli/utils/io.js +225 -0
- package/cli/utils/mongoClient.js +21 -0
- package/cli/utils/progressbar.js +86 -0
- package/cli/xywhToInt.js +99 -0
- package/config/.env.template +48 -0
- package/docker/Dockerfile +39 -0
- package/docker/README.md +5 -0
- package/docker/docker-compose.yaml +49 -0
- package/docker/docker.sh +43 -0
- package/docker/docker_aiiinotate_import.sh +62 -0
- package/docs/api.md +381 -0
- package/docs/cli.md +132 -0
- package/docs/dev_documentation/dev_architecture.md +88 -0
- package/docs/dev_documentation/dev_db.md +58 -0
- package/docs/dev_documentation/dev_iiif_compatibility.md +43 -0
- package/docs/dev_documentation/dev_notes_quirks_and_troubleshooting.md +143 -0
- package/docs/docker.md +98 -0
- package/docs/includes/report_benchmark_aiiinotate_2026-05-28-02:50:48_7steps.png +0 -0
- package/docs/scalability.md +34 -0
- package/docs/specifications/0_w3c_open_annotations.md +332 -0
- package/docs/specifications/1_w3c_web_annotations.md +577 -0
- package/docs/specifications/2_iiif_apis.md +428 -0
- package/docs/specifications/3_iiif_annotations.md +103 -0
- package/docs/specifications/4_search_api.md +135 -0
- package/docs/specifications/5_sas.md +119 -0
- package/docs/specifications/6_mirador.md +119 -0
- package/docs/specifications/7_aikon.md +137 -0
- package/docs/specifications/include/presentation_2.0.webp +0 -0
- package/docs/specifications/include/presentation_2.0_white.png +0 -0
- package/docs/specifications/include/presentation_3.0.png +0 -0
- package/docs/specifications/include/presentation_3.0_resize.png +0 -0
- package/eslint.config.js +30 -0
- package/migrations/baseConfig.js +57 -0
- package/migrations/manageIndex.js +55 -0
- package/migrations/migrate-mongo-config-main.js +8 -0
- package/migrations/migrate-mongo-config-test.js +8 -0
- package/migrations/migrationScripts/20250825185706-collections.js +48 -0
- package/migrations/migrationScripts/20250826194832-annotations2-schema.js +42 -0
- package/migrations/migrationScripts/20250904080710-annotations2-indexes.js +69 -0
- package/migrations/migrationScripts/20251002141951-manifests2-schema.js +43 -0
- package/migrations/migrationScripts/20251006212110-manifests2-indexes.js +35 -0
- package/migrations/migrationTemplate.js +25 -0
- package/package.json +82 -0
- package/scripts/get_version.py +12 -0
- package/scripts/run.sh +36 -0
- package/scripts/setup_mongodb.sh +70 -0
- package/scripts/setup_node.sh +15 -0
- package/scripts/update_version.py +30 -0
- package/scripts/utils.sh +65 -0
- package/src/app.js +116 -0
- package/src/constants.js +73 -0
- package/src/data/annotations/annotations2.js +681 -0
- package/src/data/annotations/annotations3.js +28 -0
- package/src/data/annotations/routes.js +335 -0
- package/src/data/annotations/routes.test.js +271 -0
- package/src/data/collectionAbstract.js +283 -0
- package/src/data/index.js +29 -0
- package/src/data/manifests/manifests2.js +378 -0
- package/src/data/manifests/manifests2.test.js +53 -0
- package/src/data/manifests/manifests3.js +23 -0
- package/src/data/manifests/routes.js +122 -0
- package/src/data/manifests/routes.test.js +70 -0
- package/src/data/routes.js +181 -0
- package/src/data/routes.test.js +166 -0
- package/src/db/index.js +50 -0
- package/src/fixtures/annotations.js +41 -0
- package/src/fixtures/data/annotationList_aikon_wit9_man11_anno165_all.jsonld +827 -0
- package/src/fixtures/data/annotationList_vhs_wit250_man250_anno250_all.jsonld +37514 -0
- package/src/fixtures/data/annotationList_vhs_wit253_man253_anno253_all.jsonld +20111 -0
- package/src/fixtures/data/annotations2Invalid.jsonld +39 -0
- package/src/fixtures/data/annotations2SvgValid.jsonld +81 -0
- package/src/fixtures/data/annotations2Valid.jsonld +39 -0
- package/src/fixtures/data/bnf_invalid_manifest.json +2806 -0
- package/src/fixtures/data/bnf_valid_manifest.json +2817 -0
- package/src/fixtures/data/vhs_wit253_man253_anno253_anno-24.json +1 -0
- package/src/fixtures/generate.js +181 -0
- package/src/fixtures/index.js +69 -0
- package/src/fixtures/manifests.js +14 -0
- package/src/fixtures/utils.js +37 -0
- package/src/schemas/index.js +100 -0
- package/src/schemas/schemasBase.js +19 -0
- package/src/schemas/schemasPresentation2.js +410 -0
- package/src/schemas/schemasPresentation3.js +33 -0
- package/src/schemas/schemasResolver.js +71 -0
- package/src/schemas/schemasRoutes.js +318 -0
- package/src/server.js +25 -0
- package/src/types.js +97 -0
- package/src/utils/iiif2Utils.js +332 -0
- package/src/utils/iiif2Utils.test.js +146 -0
- package/src/utils/iiif3Utils.js +0 -0
- package/src/utils/iiifUtils.js +18 -0
- package/src/utils/logger.js +119 -0
- package/src/utils/routeUtils.js +137 -0
- package/src/utils/svg.js +417 -0
- package/src/utils/testUtils.js +289 -0
- package/src/utils/utils.js +403 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# Open annotations data model
|
|
2
|
+
|
|
3
|
+
[https://web.archive.org/web/20220119101135/http://www.openannotation.org/spec/core](https://web.archive.org/web/20220119101135/http://www.openannotation.org/spec/core)
|
|
4
|
+
|
|
5
|
+
[https://web.archive.org/web/20221225112722/http://www.openannotation.org/spec/core/core.html](https://web.archive.org/web/20221225112722/http://www.openannotation.org/spec/core/core.html)
|
|
6
|
+
|
|
7
|
+
[https://www.w3.org/TR/annotation-vocab/](https://www.w3.org/TR/annotation-vocab/)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
The IIIF 2.x standard relies on the W3C Open annotations (OA) standard. Established in 2013, it has since been deprecated in favour of the W3C's Web annotations model, described in the next section. To make things fun, the site is not longer available and must be accessed through the wayback machine.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## In general
|
|
15
|
+
|
|
16
|
+
- an Annotation is **a set of interconnected resources**, made mostly of a `Body` and a `Target`
|
|
17
|
+
- the data model is **implementation independant** and can be implemented in JSON, RDF-XML, Turtle...
|
|
18
|
+
- the standard extamples are in RDF, while IIIF uses JSON-ld. In turn, keys vary from the IIIF standard. When there are differences, I indicate both what is in the OA examples, and what is used in IIIF.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Vocabulary
|
|
23
|
+
|
|
24
|
+
- `Annotation`: a set of interconnected resources, with at its core a `Body` and a `Target`, where the `Body` is about the `Target`.
|
|
25
|
+
- `Target`: the object being annotated
|
|
26
|
+
- `Body`: the annotation's contents
|
|
27
|
+
- `Motivation`: the motivation further describes the relationship between `Body` and `Target`
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Namespaces
|
|
32
|
+
|
|
33
|
+
<table>
|
|
34
|
+
<tbody><tr><th>Prefix</th><th>Namespace</th><th>Description</th></tr>
|
|
35
|
+
<tr><td>oa</td><td>http://www.w3.org/ns/oa#</td> <td>The Open Annotation ontology</td></tr>
|
|
36
|
+
|
|
37
|
+
<tr><td>cnt</td><td>http://www.w3.org/2011/content#</td><td><a href="https://web.archive.org/web/20220119101135/http://www.w3.org/TR/Content-in-RDF10/">Representing Content in RDF</a></td></tr>
|
|
38
|
+
<tr><td>dc</td><td>http://purl.org/dc/elements/1.1/</td><td><a href="https://web.archive.org/web/20220119101135/http://dublincore.org/documents/dces/">Dublin Core Elements</a></td></tr>
|
|
39
|
+
<tr><td>dcterms</td><td>http://purl.org/dc/terms/</td><td><a href="https://web.archive.org/web/20220119101135/http://dublincore.org/documents/dcmi-terms/">Dublin Core Terms</a></td></tr>
|
|
40
|
+
<tr><td>dctypes</td><td>http://purl.org/dc/dcmitype/</td><td><a href="https://web.archive.org/web/20220119101135/http://dublincore.org/documents/dcmi-type-vocabulary/">Dublin Core Type Vocabulary</a></td></tr>
|
|
41
|
+
<tr><td>foaf</td><td>http://xmlns.com/foaf/0.1/</td><td><a href="https://web.archive.org/web/20220119101135/http://xmlns.com/foaf/spec/">Friend-of-a-Friend Vocabulary</a></td></tr>
|
|
42
|
+
<tr><td>prov</td><td>http://www.w3.org/ns/prov#</td><td><a href="https://web.archive.org/web/20220119101135/http://www.w3.org/TR/prov-o/">Provenance Ontology</a></td></tr>
|
|
43
|
+
<tr><td>rdf</td><td>http://www.w3.org/1999/02/22-rdf-syntax-ns#</td><td><a href="https://web.archive.org/web/20220119101135/http://www.w3.org/TR/rdf-syntax-grammar/">RDF</a></td></tr>
|
|
44
|
+
<tr><td>rdfs</td><td>http://www.w3.org/2000/01/rdf-schema#</td><td><a href="https://web.archive.org/web/20220119101135/http://www.w3.org/TR/rdf-schema/">RDF Schema</a></td></tr>
|
|
45
|
+
<tr><td>skos</td><td>http://www.w3.org/2004/02/skos/core#</td><td><a href="https://web.archive.org/web/20220119101135/http://www.w3.org/TR/skos-reference/">Simple Knowledge Organization System</a></td></tr>
|
|
46
|
+
<tr><td>trig</td><td>http://www.w3.org/2004/03/trix/rdfg-1/</td><td><a href="https://web.archive.org/web/20220119101135/http://www.w3.org/2004/03/trix/">TriG Named Graphs</a></td></tr>
|
|
47
|
+
|
|
48
|
+
</tbody></table>
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Annotations
|
|
53
|
+
|
|
54
|
+
An annotation has 1+ `Targets` and 0+ `Bodies`
|
|
55
|
+
- IIIF `@id`: `URI`
|
|
56
|
+
- is used to identify with an URI the `Annotation`, `Body` and `Target`
|
|
57
|
+
- in Turtle, there is no specific key because the standard is different.
|
|
58
|
+
- `a` (IIIF `@type`): `oa:Annotation`
|
|
59
|
+
- this indicates that the resource is an `Annotation`
|
|
60
|
+
- `oa:hasBody` (IIIF `resource`): `Body | Body[]`
|
|
61
|
+
- the relationship between `Annotation` and `Body`
|
|
62
|
+
- the body MAY be omitted if there is no content to annotate
|
|
63
|
+
- `oa:hasTarget` (IIIF `on`): `Target | Target[]`
|
|
64
|
+
- the relationship between `Annotation` and `Target`
|
|
65
|
+
- `oa:Motivation` (IIIF `motivation`): `string[]` (in IIIF, `oa:commenting | sc:painting` are frequent)
|
|
66
|
+
- the motivation, or role of the annotation
|
|
67
|
+
- `all allowed values are: `oa:bookmarking | oa:classifying | oa:commenting | oa:describing | oa:editing | oa:highlighting | oa:identifying | oa:linking | oa:moderating | oa:questionning | oa:replying | oa:tagging`
|
|
68
|
+
- in IIIF, `sc:painting` is also allowed to indicate a painting annotation. The most useful values are `sc:painting | oa:commenting`.
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
// basic structure
|
|
72
|
+
{
|
|
73
|
+
"@id": "<URI>",
|
|
74
|
+
"@type": "oa:Annotation",
|
|
75
|
+
"motivation": "sc:painting" || "oa:commenting", // or an array of values
|
|
76
|
+
"resource": {
|
|
77
|
+
"@id": "<URI?>",
|
|
78
|
+
"@type": "<dctype>",
|
|
79
|
+
// other keys
|
|
80
|
+
},
|
|
81
|
+
"on": "<URI>" || SpecificResource // `on` can be either specified as the URI to a canvas, or as a SpecificResource
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
### Bodies and targets
|
|
85
|
+
|
|
86
|
+
- `a` (IIIF `@type`): `dctypes:Dataset | dctypes:Image | dctypes:MovingImage | dctypes:Sound | dcTypes:Text`
|
|
87
|
+
- SHOULD be used to describe the type of a `Body` or `Target`
|
|
88
|
+
- IIIF `@id`: `URI`
|
|
89
|
+
|
|
90
|
+
Special cases:
|
|
91
|
+
- an annotation may have **no `Body`**
|
|
92
|
+
- an annotation may have **multiple `Bodies` or `Targets`**.
|
|
93
|
+
- in that case, **each body is related to each target individually**. If we have 2 bodies and 2 targets, we have the following situation:
|
|
94
|
+
```
|
|
95
|
+
body1 <-> target1
|
|
96
|
+
body1 <-> target2
|
|
97
|
+
body2 <-> target1
|
|
98
|
+
body2 <-> target2
|
|
99
|
+
```
|
|
100
|
+
- you may have 1 `Target` and N `Bodies` (several annotations apply to a single body), or N `Target` and 1 `Bodies` (1 annotation applies to several images) or an N to N relationship.
|
|
101
|
+
|
|
102
|
+
### Embedded textual body (ETB)
|
|
103
|
+
|
|
104
|
+
ETBs are used to embed textual content directly in an annotation instead of referencing it by an `id`.
|
|
105
|
+
- `a` (IIIF `@type`): `cnt:ContentAsText | dctypes:Text`
|
|
106
|
+
- MUST be used to indicate that this is an ETB. MAY contain both values described above.
|
|
107
|
+
- `cnt:chars` (IIIF `chars`): `string`
|
|
108
|
+
- MUST Be used to contain the contents of the ETB.
|
|
109
|
+
- `dc:format` (SAS `format`): `mimetype`
|
|
110
|
+
- SHOULD be used to describe the mimetype of the ETB
|
|
111
|
+
- for example, it can distinguish plain text form HTML.
|
|
112
|
+
- `dc:language`: `string`
|
|
113
|
+
- the language the ETB is in
|
|
114
|
+
- language codes SHOULD follow [RFC 3066](https://www.ietf.org/rfc/rfc3066.txt)
|
|
115
|
+
|
|
116
|
+
```js
|
|
117
|
+
{
|
|
118
|
+
"@type" : "dctypes:Text",
|
|
119
|
+
"format" : "text/html",
|
|
120
|
+
"chars" : "<p>This is en embedded textual content from SAS</p>",
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Tags
|
|
125
|
+
|
|
126
|
+
A tag is a specific type of `Body`: a keyword or label used to annotate a `Target`. There are 2 types of tags: "normal" and "semantic" tags
|
|
127
|
+
- `a` (IIIF `@type`): `oa:Tag | oa:SemanticTag`
|
|
128
|
+
- `oa:Tag` describes a non-semantic tag. In that case, the tag functions like an ETB
|
|
129
|
+
- `oa:SemanticTag` describes a semantic tag. Instead of containing the contents of the tag, the `Body` references an external URI.
|
|
130
|
+
- `oa:Motivation` (IIIF `motivation`): `oa:tagging`
|
|
131
|
+
- `oa:tagging` should be added to the `oa:Motivation` of the annotation to indicate it's a tag
|
|
132
|
+
|
|
133
|
+
### Fragment URIs
|
|
134
|
+
|
|
135
|
+
Fragment URIs can be used to target part of a resource.
|
|
136
|
+
- fragments ARE NOT COMPATIBLE with `SpecificResources`. Either use one or the other.
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
{
|
|
140
|
+
"@id": "http://example.com/image.jpg#xywh=1,1,1,1"
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Specific Resources
|
|
147
|
+
|
|
148
|
+
[https://web.archive.org/web/20221225112722/http://www.openannotation.org/spec/core/specific.html](https://web.archive.org/web/20221225112722/http://www.openannotation.org/spec/core/specific.html)
|
|
149
|
+
|
|
150
|
+
`SpecificResources` are an extension of the core data model to reference part of a resource with more precision than Fragment URIs. They can be used either in `Bodies` or `Targets` (though in IIIF they are used mostly in `Targets`).
|
|
151
|
+
|
|
152
|
+
```js
|
|
153
|
+
// basic IIIF structure for a SpecificResource
|
|
154
|
+
{
|
|
155
|
+
"@id": "<annotationId>",
|
|
156
|
+
"@type": "oa:SpecificResource",
|
|
157
|
+
"full": {
|
|
158
|
+
// link to the full image
|
|
159
|
+
},
|
|
160
|
+
"selector": {
|
|
161
|
+
"@type": "<selectorType>",
|
|
162
|
+
"value": "<selectorValue>"
|
|
163
|
+
},
|
|
164
|
+
"within": {
|
|
165
|
+
// extra context, such as the IIIF manifest in which to include the annotation
|
|
166
|
+
},
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Basic units
|
|
171
|
+
|
|
172
|
+
3 conceptual units are present in the Specific Resource model:
|
|
173
|
+
- `Source resource`: the complete target , i.e. an entire image that we want to select a section of.
|
|
174
|
+
- `SpecificResource`: the segment of the resource described by the `Specifier`
|
|
175
|
+
- `Specifiers`: describes how to determine the aspects of the `Source` that constitute the Specific Resource.
|
|
176
|
+
|
|
177
|
+
### Specifiers
|
|
178
|
+
|
|
179
|
+
There are 3 types of specifiers:
|
|
180
|
+
- `oa:State`: specifies the state of a `Body` or a `Target` applicable to an `Annotation` in order to retrieve the proper representation of the resource. For example,
|
|
181
|
+
- the timestamp at which a `Body` was created (if there are several versions of the same resource with different timestamps)
|
|
182
|
+
- `oa:Selector`: specifies the segment of a resource relevant to the `Annotation`: text range, image section, SVG selector...
|
|
183
|
+
- `oa:Style`: a description of how to style an `Annotation`
|
|
184
|
+
|
|
185
|
+
If `State` and `Selector` are present in a annotation, the `State` will be processed before `Selector` to be sure that we have the proper state.
|
|
186
|
+
|
|
187
|
+
Keys:
|
|
188
|
+
- `a` (IIIF `@type`) `oa:SpecificResource`: the specific resource
|
|
189
|
+
- `oa:hasSource` (SAS `full`): the `Source Resource` being specified by the `Specific Resource`.
|
|
190
|
+
- MUST be used: the `Specific Resource` is defined relatively to the `Source Resource`, and so the renderer will fetch the `Source` before targeting the `Specific resource` part.
|
|
191
|
+
|
|
192
|
+
I'll only present selectors, not `states` or `styles` that aren't used in IIIF.
|
|
193
|
+
|
|
194
|
+
### Selectors
|
|
195
|
+
|
|
196
|
+
A `Selector` is a `Specifier` which describes how to determine the segment of interest from within the retrieved representation of the Source resource. There MUST be only 1 `Selector` per specifier, otherwise use the [multiplicity module](https://web.archive.org/web/20221225112718/http://www.openannotation.org/spec/core/multiplicity.html).
|
|
197
|
+
|
|
198
|
+
- `oa:hasSource` (IIIF `full`): the `Source resource`
|
|
199
|
+
- `oa:hasSelector` (IIIF `selector`): the `Selector`'s content
|
|
200
|
+
|
|
201
|
+
There are selectors other than those presented below: `RangeSelector`, `TextPositionSelector`, `TextQuoteSelector`... but they are out of scope with IIIF so I won't talk about them
|
|
202
|
+
|
|
203
|
+
#### FragmentSelector
|
|
204
|
+
|
|
205
|
+
- `a` (IIIF `@type`): `oa:FragmentSelector`
|
|
206
|
+
- `rdf:value` (IIIF `value`): `string'
|
|
207
|
+
- `dcterms:conformsTo`: the specification that defines the syntax of the fragment.
|
|
208
|
+
- for IIIF, targets can only be targeted using IIIF-specific `ImageApiSelector` or W3C media fragments (`xhwh=int,int,int,int`).
|
|
209
|
+
- SHOULD be used
|
|
210
|
+
- SHOULD be one of:
|
|
211
|
+
|
|
212
|
+
<table>
|
|
213
|
+
<tbody><tr><th>Fragment Specification</th><th>Description</th></tr>
|
|
214
|
+
<tr><td>http://tools.ietf.org/rfc/rfc3236</td><td><a href="https://web.archive.org/web/20221225112722/http://tools.ietf.org/rfc/rfc3236">XHTML, and HTML</a>. Example: #namedSection </td></tr>
|
|
215
|
+
<tr><td>http://tools.ietf.org/rfc/rfc3778</td><td><a href="https://web.archive.org/web/20221225112722/http://tools.ietf.org/rfc/rfc3778">PDF</a>. Example: #page=10&viewrect=50,50,640,480</td></tr>
|
|
216
|
+
<tr><td>http://tools.ietf.org/rfc/rfc5147</td><td><a href="https://web.archive.org/web/20221225112722/http://tools.ietf.org/rfc/rfc5147">Plain Text</a>. Example: #char=0,10</td></tr>
|
|
217
|
+
<tr><td>http://tools.ietf.org/rfc/rfc3023</td><td><a href="https://web.archive.org/web/20221225112722/http://tools.ietf.org/rfc/rfc3023">XML</a>. Example: #xpointer(/a/b/c) </td></tr>
|
|
218
|
+
<tr><td>http://www.ietf.org/rfc/rfc3870</td><td><a href="https://web.archive.org/web/20221225112722/http://www.ietf.org/rfc/rfc3870">RDF/XML</a>. Example: #namedResource </td></tr>
|
|
219
|
+
<tr><td>http://www.w3.org/TR/media-frags/</td><td><a href="https://web.archive.org/web/20221225112722/http://www.w3.org/TR/media-frags/">W3C Media Fragments</a>. Example: #xywh=50,50,640,480</td></tr>
|
|
220
|
+
<tr><td>http://www.w3.org/TR/SVG/</td><td><a href="https://web.archive.org/web/20221225112722/http://www.w3.org/TR/SVG/">SVG</a>. Example: #svgView(viewBox(50,50,640,480))</td></tr>
|
|
221
|
+
</tbody></table>
|
|
222
|
+
|
|
223
|
+
```js
|
|
224
|
+
{
|
|
225
|
+
// ...
|
|
226
|
+
selector: {
|
|
227
|
+
"@type": "oa:FragmentSelector",
|
|
228
|
+
"value": "xywh=int,int,int,int" // so here we use the W3C media fragments selector
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
#### SVG selectors
|
|
235
|
+
|
|
236
|
+
`SvgSelectors` define an area through an SVG.
|
|
237
|
+
- the `SvgSelector`'s value MUST be a valid and complete SVG document
|
|
238
|
+
- the SVG SHOULD be a single shape: `path|rect|circle|ellipse|polyline|polygone|g`
|
|
239
|
+
- dimensions in the SVG MUST be relative to the `Source resource`.
|
|
240
|
+
- For example, given an image which is 600 pixels by 400 pixels, and the desired section is a circle of 100 pixel radius at the center of the image, then the SVG element would be: `<circle cx="300" cy="200" r="100"/>`
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
### Examples
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
`Specific resource` structure in IIIF 2.x.
|
|
247
|
+
```js
|
|
248
|
+
{
|
|
249
|
+
"@type" : "oa:SpecificResource",
|
|
250
|
+
"within" : {
|
|
251
|
+
"@id" : "https://aikon.enpc.fr/aikon/iiif/v2/wit9_man11_anno165/manifest.json",
|
|
252
|
+
"@type" : "sc:Manifest"
|
|
253
|
+
},
|
|
254
|
+
"selector" : {
|
|
255
|
+
"@type" : "oa:FragmentSelector",
|
|
256
|
+
"value" : "xywh=0,31,1865,1670"
|
|
257
|
+
},
|
|
258
|
+
"full" : "https://aikon.enpc.fr/aikon/iiif/v2/wit9_man11_anno165/canvas/c16.json"
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
`Specific resource` that uses the IIIF `ImageApiSelector` extension
|
|
263
|
+
```js
|
|
264
|
+
{
|
|
265
|
+
// `@id` uses the IIIF Image api to describe the fragment
|
|
266
|
+
"@id": "http://www.example.org/iiif/book1-page1/50,50,1250,1850/full/0/default.jpg",
|
|
267
|
+
"@type": "oa:SpecificResource",
|
|
268
|
+
|
|
269
|
+
// `full` describes the full image.
|
|
270
|
+
"full": {
|
|
271
|
+
"@id": "http://example.org/iiif/book1-page1/full/full/0/default.jpg",
|
|
272
|
+
"@type": "dctypes:Image",
|
|
273
|
+
"service": {
|
|
274
|
+
"@context": "http://iiif.io/api/image/2/context.json",
|
|
275
|
+
"@id": "http://example.org/iiif/book1-page1",
|
|
276
|
+
"profile": "http://iiif.io/api/image/2/level2.json"
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
// `selector` describes the region targeted in `@id`
|
|
281
|
+
"selector": {
|
|
282
|
+
"@context": "http://iiif.io/api/annex/openannotation/context.json",
|
|
283
|
+
"@type": "iiif:ImageApiSelector",
|
|
284
|
+
"region": "50,50,1250,1850"
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Multiplicity
|
|
292
|
+
|
|
293
|
+
[https://web.archive.org/web/20221225112718/http://www.openannotation.org/spec/core/multiplicity.html](https://web.archive.org/web/20221225112718/http://www.openannotation.org/spec/core/multiplicity.html)
|
|
294
|
+
|
|
295
|
+
In IIIF, this module is useful if we want to specify more than 1 `SpecificResource`. In OA, the multiplicity module is used to have multiple bodies or targets in an annotation (IE: 3 bodies in 3 languages). Options for multiplicity are:
|
|
296
|
+
|
|
297
|
+
- `oa:Choice`: only one of several bodies/targets will be rendered at once. Done by defining 1 default value and other alternative values
|
|
298
|
+
- `oa:Composite`: when all resources are required for an annotation to function properly.
|
|
299
|
+
- `oa:List`: like a composite, but ordered
|
|
300
|
+
|
|
301
|
+
`Bodies` and `Targets` can use `multiplicity` by setting their `@type` to `oa:Choice | oa:Composite |oa:List`.
|
|
302
|
+
|
|
303
|
+
I have only ever seen `oa:Choice` be used in IIIF so that's the one I'll present.
|
|
304
|
+
|
|
305
|
+
### `oa:Choice`
|
|
306
|
+
|
|
307
|
+
```js
|
|
308
|
+
{
|
|
309
|
+
"@type": "oa:Choice",
|
|
310
|
+
"default": /** default choice */,
|
|
311
|
+
"item": /** one or several other available items */
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Example: a choice between a `FragmentSelector` and an `SvgSelector`
|
|
316
|
+
```js
|
|
317
|
+
{
|
|
318
|
+
"@type" : "oa:Choice",
|
|
319
|
+
"default" : {
|
|
320
|
+
"@type" : "oa:FragmentSelector",
|
|
321
|
+
"value" : "xywh=0,31,1865,1670"
|
|
322
|
+
},
|
|
323
|
+
"item" : {
|
|
324
|
+
"@type" : "oa:SvgSelector",
|
|
325
|
+
"value" : "<svg xmlns=\"http://www.w3.org/2000/svg\"><path xmlns='http://www.w3.org/2000/svg' d='M0 31 h 932 v 0 h 932 v 835 v 835 h -932 h -932 v -835Z' id='rectangle_wit9_man11_anno165_c16_5ebd8bc8044b45b58aae2a508ca75eed' data-paper-data='{"strokeWidth":1,"rotation":0,"annotation":null,"nonHoverStrokeColor":["Color",0,1,0],"editable":true,"deleteIcon":null,"rotationIcon":null,"group":null}' fill-opacity='0' fill='#00ff00' fill-rule='nonzero' stroke='#00ff00' stroke-width='1' stroke-linecap='butt' stroke-linejoin='miter' stroke-miterlimit='10' stroke-dashoffset='0' style='mix-blend-mode: normal'/></svg>"
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
|