diff --git a/Makefile b/Makefile index b1da89168..6eaca66be 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ docs-serve: ## serve docs for local viewing mkdocs serve --dev-addr=0.0.0.0:7979 .PHONY: install-requirements -install-requirements: ## install requirements +install-requirements: ## install Python dependencies from the diverse requirements.txt files python3 -m pip install --upgrade pip pip3 install -r requirements.txt pip3 install -r docs/requirements.txt @@ -50,25 +50,25 @@ install: ## install from source (runs setup.py) pip3 install -e . .PHONY: test -test: dsp-stack ## run all tests - pytest test/ +test: dsp-stack ## run all tests located in the "test" folder (intended for local usage) + -pytest test/ $(MAKE) stack-down .PHONY: test-no-stack -test-no-stack: ## run tests without starting the stack (if a dsp-stack is already running) +test-no-stack: ## run all tests located in the "test" folder, without starting the stack (intended for local usage) pytest test/ .PHONY: test-end-to-end -test-end-to-end: dsp-stack ## run e2e tests - pytest test/e2e/ +test-end-to-end: dsp-stack ## run e2e tests (intended for local usage) + -pytest test/e2e/ $(MAKE) stack-down .PHONY: test-end-to-end-ci -test-end-to-end-ci: dsp-stack ## run e2e tests on GitHub CI, where it isn't possible nor necessary to remove .tmp +test-end-to-end-ci: dsp-stack ## run e2e tests (intended for GitHub CI, where it isn't possible nor necessary to remove .tmp) pytest test/e2e/ .PHONY: test-end-to-end-no-stack -test-end-to-end-no-stack: ## run e2e tests without starting the dsp-stack (if a dsp-stack is already running) +test-end-to-end-no-stack: ## run e2e tests without starting the dsp-stack (intended for local usage) pytest test/e2e/ .PHONY: test-unittests @@ -77,7 +77,7 @@ test-unittests: ## run unit tests .PHONY: clean clean: ## clean local project directories - @rm -rf dist/ build/ site/ dsp_tools.egg-info/ + @rm -rf dist/ build/ site/ dsp_tools.egg-info/ id2iri_*_mapping_*.json stashed_*_properties_*.txt .PHONY: help help: ## show this help diff --git a/docs/assets/images/img-excel2xml.png b/docs/assets/images/img-excel2xml.png index 45840ea30..834d86ea2 100644 Binary files a/docs/assets/images/img-excel2xml.png and b/docs/assets/images/img-excel2xml.png differ diff --git a/docs/dsp-tools-excel.md b/docs/dsp-tools-excel.md index 0bb349273..d162dca12 100644 --- a/docs/dsp-tools-excel.md +++ b/docs/dsp-tools-excel.md @@ -220,4 +220,7 @@ Some notes: - The special tags ``, ``, and `` are represented as resources of restype `Annotation`, `LinkObj`, and `Region`. - - The columns "ark" and "iri" are only used for DaSCH-internal data migration. + - The columns "ark", "iri", and "creation_date" are only used for DaSCH-internal data migration. + - If `file` is provided, but no `file permissions`, an attempt will be started to deduce them from the resource + permissions (`res-default` --> `prop-default` and `res-restricted` --> `prop-restricted`). If this attempt is not + successful, a `BaseError` will be raised. diff --git a/docs/dsp-tools-xmlupload.md b/docs/dsp-tools-xmlupload.md index 6356e97d2..e4ce289f2 100644 --- a/docs/dsp-tools-xmlupload.md +++ b/docs/dsp-tools-xmlupload.md @@ -201,14 +201,18 @@ To take `KnownUser` as example: A `` element contains all necessary information to create a resource. It has the following attributes: -- `label`: a human-readable, preferably meaningful short name of the resource (required) -- `restype`: the resource type as defined within the ontology (required) -- `id`: a unique, arbitrary string providing a unique ID to the resource in order to be referencable by other resources; - the ID is only used during the import process and later replaced by the IRI used internally by DSP (required) -- `permissions`: a reference to a permission set; the permissions will be applied to the created resource (optional) -- `iri`: a custom IRI used when migrating existing resources (optional) -- `ark`: a version 0 ARK used when migrating existing resources from salsah.org to DSP (optional), it is not possible to -use `iri` and `ark` in the same resource. When `ark` is used, it overrides `iri`. +- `label` (required): a human-readable, preferably meaningful short name of the resource +- `restype` (required): the resource type as defined within the ontology +- `id` (required): a unique, arbitrary string providing a unique ID to the resource in order to be referencable by other + resources; the ID is only used during the import process and later replaced by the IRI used internally by DSP +- `permissions` (optional, but if omitted, users who are lower than a `ProjectAdmin` have no permissions at all, not + even view rights): a reference to a permission set; the permissions will be applied to the created resource +- `iri` (optional): a custom IRI, used when migrating existing resources (DaSCH-internal only) +- `ark` (optional): a version 0 ARK, used when migrating existing resources. It is not possible + to use `iri` and `ark` in the same resource. When `ark` is used, it overrides `iri` (DaSCH-internal only). +- `creation_date` (optional): the creation date of the resource, used when migrating existing resources + . It must be formatted according to the constraints of [xsd:dateTimeStamp](https://www.w3.org/TR/xmlschema11-2/#dateTimeStamp), + which means that the timezone is required, e.g.: `2005-10-23T13:45:12.502951+02:00` (DaSCH-internal only) A complete `` element may look as follows: diff --git a/docs/index.md b/docs/index.md index 94d0ab143..c05b4f153 100644 --- a/docs/index.md +++ b/docs/index.md @@ -20,7 +20,7 @@ dsp-tools helps you with the following tasks: a DSP server and writes it into a JSON file. - [`dsp-tools xmlupload`](./dsp-tools-usage.md#upload-data-to-a-dsp-server) uploads data from an XML file (bulk data import) and writes the mapping from internal IDs to IRIs into a local file. -- [`dsp-tools excel`](./dsp-tools-usage.md#create-the-lists-section-of-a-json-project-file-from-excel-files) +- [`dsp-tools excel2lists`](./dsp-tools-usage.md#create-the-lists-section-of-a-json-project-file-from-excel-files) creates the "lists" section of a JSON project file from one or several Excel files. The resulting section can be integrated into a JSON project file and then be uploaded to a DSP server with `dsp-tools create`. - [`dsp-tools excel2resources`](./dsp-tools-usage.md#create-the-resources-section-of-a-json-project-file-from-an-excel-file) diff --git a/knora/dsplib/models/helpers.py b/knora/dsplib/models/helpers.py index 14c7fc16e..e0d39ce4b 100644 --- a/knora/dsplib/models/helpers.py +++ b/knora/dsplib/models/helpers.py @@ -2,7 +2,6 @@ import sys from dataclasses import dataclass from enum import Enum, unique -from traceback import format_exc from typing import NewType, Optional, Any, Tuple, Union, Pattern from pystrict import strict @@ -63,7 +62,7 @@ def __str__(self) -> str: Convert to string :return: stringyfied error message """ - return self._message + "\n\n" + format_exc() + return self._message @property def message(self) -> str: @@ -423,67 +422,74 @@ def print(self) -> None: print(a[0] + ': "' + a[1].iri + '"') -class LastModificationDate: +class DateTimeStamp: """ - Class to hold and process the last modification date of a ontology + Class to hold and process an xsd:dateTimeStamp """ - _last_modification_date: str + _dateTimeStamp: str + _validation_regex = r"^-?([1-9][0-9]{3,}|0[0-9]{3})" \ + r"-(0[1-9]|1[0-2])" \ + r"-(0[1-9]|[12][0-9]|3[01])" \ + r"T(([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\.[0-9]+)?|(24:00:00(\.0+)?))" \ + r"(Z|(\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))$" def __init__(self, val: Any): """ The constructor works for different inputs: - - a string holding the modification date - - an instance of "LastModificationDate" + - a string + - an instance of "DateTimeStamp" - json-ld construct of the form { "@type": "xsd:dateTimeStamp", "@value": "date-str" } - :param val: datetimestamp as string, instance of "LastModificationDate" or json-ld construct + :param val: xsd:dateTimeStamp as string, instance of "DateTimeStamp" or json-ld construct """ if isinstance(val, str): - self._last_modification_date = val - elif isinstance(val, LastModificationDate): - self._last_modification_date = str(val) + if not re.search(self._validation_regex, val): + raise BaseError(f"Invalid xsd:dateTimeStamp: '{val}'") + self._dateTimeStamp = val + elif isinstance(val, DateTimeStamp): + self._dateTimeStamp = str(val) else: - if val.get("@type") is not None and val.get("@type") == "xsd:dateTimeStamp": - self._last_modification_date = val["@value"] + if val.get("@type") == "xsd:dateTimeStamp" and re.search(self._validation_regex, str(val.get("@value"))): + self._dateTimeStamp = val["@value"] else: - raise BaseError("Invalid LastModificationDate") + raise BaseError(f"Invalid xsd:dateTimeStamp: '{val}'") - def __eq__(self, other: Union[str, 'LastModificationDate']) -> bool: + def __eq__(self, other: Union[str, 'DateTimeStamp']) -> bool: if isinstance(other, str): - other = LastModificationDate(other) - return self._last_modification_date == other._last_modification_date + other = DateTimeStamp(other) + return self._dateTimeStamp == other._dateTimeStamp - def __lt__(self, other: 'LastModificationDate') -> bool: + def __lt__(self, other: 'DateTimeStamp') -> bool: if isinstance(other, str): - other = LastModificationDate(other) - return self._last_modification_date < other._last_modification_date + other = DateTimeStamp(other) + return self._dateTimeStamp < other._dateTimeStamp - def __le__(self, other: 'LastModificationDate') -> bool: + def __le__(self, other: 'DateTimeStamp') -> bool: if isinstance(other, str): - other = LastModificationDate(other) - return self._last_modification_date <= other._last_modification_date + other = DateTimeStamp(other) + return self._dateTimeStamp <= other._dateTimeStamp - def __gt__(self, other: 'LastModificationDate') -> bool: + def __gt__(self, other: 'DateTimeStamp') -> bool: if isinstance(other, str): - other = LastModificationDate(other) - return self._last_modification_date > other._last_modification_date + other = DateTimeStamp(other) + return self._dateTimeStamp > other._dateTimeStamp - def __ge__(self, other: 'LastModificationDate') -> bool: + def __ge__(self, other: 'DateTimeStamp') -> bool: if isinstance(other, str): - other = LastModificationDate(other) - return self._last_modification_date >= other._last_modification_date + other = DateTimeStamp(other) + return self._dateTimeStamp >= other._dateTimeStamp - def __ne__(self, other: 'LastModificationDate') -> bool: + def __ne__(self, other: 'DateTimeStamp') -> bool: if isinstance(other, str): - other = LastModificationDate(other) - return self._last_modification_date != other._last_modification_date + other = DateTimeStamp(other) + return self._dateTimeStamp != other._dateTimeStamp - def __str__(self: 'LastModificationDate') -> Union[None, str]: - return self._last_modification_date + def __str__(self: 'DateTimeStamp') -> Union[None, str]: + return self._dateTimeStamp def toJsonObj(self): return { "@type": "xsd:dateTimeStamp", - "@value": self._last_modification_date + "@value": self._dateTimeStamp } diff --git a/knora/dsplib/models/ontology.py b/knora/dsplib/models/ontology.py index c4ba93b2a..021849159 100644 --- a/knora/dsplib/models/ontology.py +++ b/knora/dsplib/models/ontology.py @@ -7,7 +7,7 @@ from pystrict import strict from .connection import Connection -from .helpers import Actions, BaseError, Context, LastModificationDate, OntoIri, WithId +from .helpers import Actions, BaseError, Context, DateTimeStamp, OntoIri, WithId from .model import Model from .project import Project from .propertyclass import PropertyClass @@ -64,7 +64,7 @@ class Ontology(Model): _name: str _label: str _comment: str - _lastModificationDate: LastModificationDate + _lastModificationDate: DateTimeStamp _resource_classes: list[ResourceClass] _property_classes: list[PropertyClass] _context: Context @@ -77,7 +77,7 @@ def __init__(self, name: Optional[str] = None, label: Optional[str] = None, comment: Optional[str] = None, - lastModificationDate: Optional[Union[str, LastModificationDate]] = None, + lastModificationDate: Optional[Union[str, DateTimeStamp]] = None, resource_classes: list[ResourceClass] = [], property_classes: list[PropertyClass] = [], context: Context = None): @@ -92,10 +92,10 @@ def __init__(self, self._comment = comment if lastModificationDate is None: self._lastModificationDate = None - elif isinstance(lastModificationDate, LastModificationDate): + elif isinstance(lastModificationDate, DateTimeStamp): self._lastModificationDate = lastModificationDate else: - self._lastModificationDate = LastModificationDate(lastModificationDate) + self._lastModificationDate = DateTimeStamp(lastModificationDate) self._resource_classes = resource_classes self._property_classes = property_classes self._context = context if context is not None else Context() @@ -144,12 +144,12 @@ def comment(self, value: str): self._changed.add('comment') @property - def lastModificationDate(self) -> LastModificationDate: + def lastModificationDate(self) -> DateTimeStamp: return self._lastModificationDate @lastModificationDate.setter - def lastModificationDate(self, value: Union[str, LastModificationDate]): - self._lastModificationDate = LastModificationDate(value) + def lastModificationDate(self, value: Union[str, DateTimeStamp]): + self._lastModificationDate = DateTimeStamp(value) @property def resource_classes(self) -> list[ResourceClass]: @@ -250,7 +250,7 @@ def fromJsonObj(cls, con: Connection, json_obj: Any) -> 'Ontology': project = json_obj[knora_api + ':attachedToProject']['@id'] tmp = json_obj.get(knora_api + ':lastModificationDate') if tmp is not None: - last_modification_date = LastModificationDate(json_obj.get(knora_api + ':lastModificationDate')) + last_modification_date = DateTimeStamp(json_obj.get(knora_api + ':lastModificationDate')) else: last_modification_date = None resource_classes = None @@ -303,7 +303,7 @@ def __oneOntologiesFromJsonObj(cls, con: Connection, json_obj: Any, context: Con project = json_obj[knora_api + ':attachedToProject']['@id'] tmp = json_obj.get(knora_api + ':lastModificationDate') if tmp is not None: - last_modification_date = LastModificationDate(json_obj.get(knora_api + ':lastModificationDate')) + last_modification_date = DateTimeStamp(json_obj.get(knora_api + ':lastModificationDate')) else: last_modification_date = None label = json_obj.get(rdfs + ':label') diff --git a/knora/dsplib/models/propertyclass.py b/knora/dsplib/models/propertyclass.py index 306d266f1..322d28959 100644 --- a/knora/dsplib/models/propertyclass.py +++ b/knora/dsplib/models/propertyclass.py @@ -6,7 +6,7 @@ from pystrict import strict from .connection import Connection -from .helpers import Actions, BaseError, Context, LastModificationDate, WithId +from .helpers import Actions, BaseError, Context, DateTimeStamp, WithId from .langstring import Languages, LangString from .listnode import ListNode from .model import Model @@ -301,7 +301,7 @@ def fromJsonObj(cls, con: Connection, context: Context, json_obj: Any) -> Any: editable=editable, linkvalue=linkvalue) - def toJsonObj(self, lastModificationDate: LastModificationDate, action: Actions, what: Optional[str] = None) -> Any: + def toJsonObj(self, lastModificationDate: DateTimeStamp, action: Actions, what: Optional[str] = None) -> Any: def resolve_propref(resref: str): tmp = resref.split(':') @@ -379,14 +379,14 @@ def resolve_propref(resref: str): return tmp - def create(self, last_modification_date: LastModificationDate) -> Tuple[LastModificationDate, 'PropertyClass']: + def create(self, last_modification_date: DateTimeStamp) -> Tuple[DateTimeStamp, 'PropertyClass']: jsonobj = self.toJsonObj(last_modification_date, Actions.Create) jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=2) result = self._con.post(PropertyClass.ROUTE, jsondata) - last_modification_date = LastModificationDate(result['knora-api:lastModificationDate']) + last_modification_date = DateTimeStamp(result['knora-api:lastModificationDate']) return last_modification_date, PropertyClass.fromJsonObj(self._con, self._context, result['@graph']) - def update(self, last_modification_date: LastModificationDate) -> Tuple[LastModificationDate, 'ResourceClass']: + def update(self, last_modification_date: DateTimeStamp) -> Tuple[DateTimeStamp, 'ResourceClass']: # # Note: Knora is able to change only one thing per call, either label or comment! # @@ -396,23 +396,23 @@ def update(self, last_modification_date: LastModificationDate) -> Tuple[LastModi jsonobj = self.toJsonObj(last_modification_date, Actions.Update, 'label') jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=4) result = self._con.put(PropertyClass.ROUTE, jsondata) - last_modification_date = LastModificationDate(result['knora-api:lastModificationDate']) + last_modification_date = DateTimeStamp(result['knora-api:lastModificationDate']) something_changed = True if 'comment' in self._changed: jsonobj = self.toJsonObj(last_modification_date, Actions.Update, 'comment') jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=4) result = self._con.put(PropertyClass.ROUTE, jsondata) - last_modification_date = LastModificationDate(result['knora-api:lastModificationDate']) + last_modification_date = DateTimeStamp(result['knora-api:lastModificationDate']) something_changed = True if something_changed: return last_modification_date, PropertyClass.fromJsonObj(self._con, self._context, result['@graph']) else: return last_modification_date, self - def delete(self, last_modification_date: LastModificationDate) -> LastModificationDate: + def delete(self, last_modification_date: DateTimeStamp) -> DateTimeStamp: result = self._con.delete(PropertyClass.ROUTE + '/' + quote_plus(self._id) + '?lastModificationDate=' + str( last_modification_date)) - return LastModificationDate(result['knora-api:lastModificationDate']) + return DateTimeStamp(result['knora-api:lastModificationDate']) def createDefinitionFileObj(self, context: Context, shortname: str): """ diff --git a/knora/dsplib/models/resource.py b/knora/dsplib/models/resource.py index 781f33177..f36f246aa 100644 --- a/knora/dsplib/models/resource.py +++ b/knora/dsplib/models/resource.py @@ -9,7 +9,7 @@ from .bitstream import Bitstream from .connection import Connection -from .helpers import OntoIri, Actions, BaseError, Cardinality, Context +from .helpers import OntoIri, Actions, BaseError, Cardinality, Context, DateTimeStamp from .listnode import ListNode from .model import Model from .ontology import Ontology @@ -28,6 +28,8 @@ def default(self, obj) -> str: return '\n' + str(obj) + '' elif isinstance(obj, OntoIri): return obj.iri + "#" if obj.hashtag else "" + elif isinstance(obj, DateTimeStamp): + return str(obj) return json.JSONEncoder.default(self, obj) @@ -71,6 +73,7 @@ class ResourceInstance(Model): _iri: Optional[str] _ark: Optional[str] _version_ark: Optional[str] + _creation_date: Optional[DateTimeStamp] _label: Optional[str] _permissions: Optional[Permissions] _user_permission: Optional[PermissionValue] @@ -82,6 +85,7 @@ def __init__(self, iri: Optional[str] = None, ark: Optional[str] = None, version_ark: Optional[str] = None, + creation_date: Optional[DateTimeStamp] = None, label: Optional[str] = None, permissions: Optional[Permissions] = None, user_permission: Optional[PermissionValue] = None, @@ -93,6 +97,7 @@ def __init__(self, self._iri = iri self._ark = ark self._version_ark = version_ark + self._creation_date = creation_date self._label = label self._permissions = permissions self._user_permission = user_permission @@ -181,6 +186,10 @@ def iri(self) -> str: def ark(self) -> str: return self._ark + @property + def creation_date(self) -> Optional[DateTimeStamp]: + return self._creation_date + @property def vark(self) -> str: return self._version_ark @@ -286,6 +295,12 @@ def toJsonLdObj(self, action: Actions) -> Any: tmp[property_name] = value.toJsonLdObj(action) tmp['@context'] = self.context + + if self._creation_date: + tmp['knora-api:creationDate'] = { + '@type': 'xsd:dateTimeStamp', + '@value': self._creation_date + } return tmp def create(self) -> 'ResourceInstance': diff --git a/knora/dsplib/models/resourceclass.py b/knora/dsplib/models/resourceclass.py index c3efab891..9f5796bfc 100644 --- a/knora/dsplib/models/resourceclass.py +++ b/knora/dsplib/models/resourceclass.py @@ -7,7 +7,7 @@ from pystrict import strict from .connection import Connection -from .helpers import Actions, BaseError, Context, Cardinality, LastModificationDate +from .helpers import Actions, BaseError, Context, Cardinality, DateTimeStamp from .langstring import Languages, LangString from .model import Model from ..utils.set_encoder import SetEncoder @@ -187,7 +187,7 @@ def fromJsonObj(cls, con: Connection, context: Context, jsonld_obj: Any) -> Tupl is_inherited=is_inherited, ptype=ptype) - def toJsonObj(self, lastModificationDate: LastModificationDate, action: Actions) -> Any: + def toJsonObj(self, lastModificationDate: DateTimeStamp, action: Actions) -> Any: if self._cardinality is None: raise BaseError("There must be a cardinality given!") tmp = {} @@ -240,7 +240,7 @@ def toJsonObj(self, lastModificationDate: LastModificationDate, action: Actions) tmp["@graph"][0]["rdfs:subClassOf"]["salsah-gui:guiOrder"] = self._gui_order return tmp - def create(self, last_modification_date: LastModificationDate) -> Tuple[LastModificationDate, 'ResourceClass']: + def create(self, last_modification_date: DateTimeStamp) -> Tuple[DateTimeStamp, 'ResourceClass']: if self._ontology_id is None: raise BaseError("Ontology id required") if self._property_id is None: @@ -251,10 +251,10 @@ def create(self, last_modification_date: LastModificationDate) -> Tuple[LastModi jsonobj = self.toJsonObj(last_modification_date, Actions.Create) jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=2) result = self._con.post(HasProperty.ROUTE, jsondata) - last_modification_date = LastModificationDate(result['knora-api:lastModificationDate']) + last_modification_date = DateTimeStamp(result['knora-api:lastModificationDate']) return last_modification_date, ResourceClass.fromJsonObj(self._con, self._context, result['@graph']) - def update(self, last_modification_date: LastModificationDate) -> Tuple[LastModificationDate, 'ResourceClass']: + def update(self, last_modification_date: DateTimeStamp) -> Tuple[DateTimeStamp, 'ResourceClass']: if self._ontology_id is None: raise BaseError("Ontology id required") if self._property_id is None: @@ -264,11 +264,11 @@ def update(self, last_modification_date: LastModificationDate) -> Tuple[LastModi jsonobj = self.toJsonObj(last_modification_date, Actions.Update) jsondata = json.dumps(jsonobj, indent=4, cls=SetEncoder) result = self._con.put(HasProperty.ROUTE, jsondata) - last_modification_date = LastModificationDate(result['knora-api:lastModificationDate']) + last_modification_date = DateTimeStamp(result['knora-api:lastModificationDate']) # TODO: self._changed = str() return last_modification_date, ResourceClass.fromJsonObj(self._con, self._context, result['@graph']) - def delete(self, last_modification_date: LastModificationDate) -> LastModificationDate: + def delete(self, last_modification_date: DateTimeStamp) -> DateTimeStamp: raise BaseError("Cannot remove a single property from a class!") # ToDo: Check with Ben if we could add this feature... @@ -358,12 +358,12 @@ class ResourceClass(Model): returns a HasProperty-instance addProperty: Add a new property to the resource class - addProperty(property_id: str, cardinality: Cardinality, last_modification_date: LastModificationDate) - -> Optional[LastModificationDate] + addProperty(property_id: str, cardinality: Cardinality, last_modification_date: DateTimeStamp) + -> Optional[DateTimeStamp] updateProperty: Updates the cardinality parameters of the given property with the resource class - updateProperty(self, property_id: str, cardinality: Cardinality, last_modification_date: LastModificationDate) - -> Optional[LastModificationDate] + updateProperty(self, property_id: str, cardinality: Cardinality, last_modification_date: DateTimeStamp) + -> Optional[DateTimeStamp] Please note that the cardinality usually can only be changed to be *less* restrictive! create: Create a new resource class on the connected server @@ -565,11 +565,11 @@ def getProperty(self, property_id) -> Optional[HasProperty]: return self._has_properties.get(self._context.get_prefixed_iri(property_id)) def addProperty(self, - last_modification_date: LastModificationDate, + last_modification_date: DateTimeStamp, property_id: str, cardinality: Cardinality, gui_order: Optional[int] = None, - ) -> LastModificationDate: + ) -> DateTimeStamp: if self._has_properties.get(property_id) is None: latest_modification_date, resclass = HasProperty(con=self._con, context=self._context, @@ -587,11 +587,11 @@ def addProperty(self, raise BaseError("Property already has cardinality in this class! " + property_id) def updateProperty(self, - last_modification_date: LastModificationDate, + last_modification_date: DateTimeStamp, property_id: str, cardinality: Optional[Cardinality], gui_order: Optional[int] = None, - ) -> Optional[LastModificationDate]: + ) -> Optional[DateTimeStamp]: property_id = self._context.get_prefixed_iri(property_id) if self._has_properties.get(property_id) is not None: has_properties = self._has_properties[property_id] @@ -669,7 +669,7 @@ def fromJsonObj(cls, con: Connection, context: Context, json_obj: Any) -> Any: comment=comment, has_properties=has_properties) - def toJsonObj(self, lastModificationDate: LastModificationDate, action: Actions, what: Optional[str] = None) -> Any: + def toJsonObj(self, lastModificationDate: DateTimeStamp, action: Actions, what: Optional[str] = None) -> Any: def resolve_resref(resref: str): tmp = resref.split(':') @@ -736,14 +736,14 @@ def resolve_resref(resref: str): tmp['@graph'][0]['rdfs:comment'] = self._comment.toJsonLdObj() return tmp - def create(self, last_modification_date: LastModificationDate) -> Tuple[LastModificationDate, 'ResourceClass']: + def create(self, last_modification_date: DateTimeStamp) -> Tuple[DateTimeStamp, 'ResourceClass']: jsonobj = self.toJsonObj(last_modification_date, Actions.Create) jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=4) result = self._con.post(ResourceClass.ROUTE, jsondata) - last_modification_date = LastModificationDate(result['knora-api:lastModificationDate']) + last_modification_date = DateTimeStamp(result['knora-api:lastModificationDate']) return last_modification_date, ResourceClass.fromJsonObj(self._con, self._context, result['@graph']) - def update(self, last_modification_date: LastModificationDate) -> Tuple[LastModificationDate, 'ResourceClass']: + def update(self, last_modification_date: DateTimeStamp) -> Tuple[DateTimeStamp, 'ResourceClass']: # # Note: Knora is able to change only one thing per call, either label or comment! # @@ -753,23 +753,23 @@ def update(self, last_modification_date: LastModificationDate) -> Tuple[LastModi jsonobj = self.toJsonObj(last_modification_date, Actions.Update, 'label') jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=4) result = self._con.put(ResourceClass.ROUTE, jsondata) - last_modification_date = LastModificationDate(result['knora-api:lastModificationDate']) + last_modification_date = DateTimeStamp(result['knora-api:lastModificationDate']) something_changed = True if 'comment' in self._changed: jsonobj = self.toJsonObj(last_modification_date, Actions.Update, 'comment') jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=4) result = self._con.put(ResourceClass.ROUTE, jsondata) - last_modification_date = LastModificationDate(result['knora-api:lastModificationDate']) + last_modification_date = DateTimeStamp(result['knora-api:lastModificationDate']) something_changed = True if something_changed: return last_modification_date, ResourceClass.fromJsonObj(self._con, self._context, result['@graph']) else: return last_modification_date, self - def delete(self, last_modification_date: LastModificationDate) -> LastModificationDate: + def delete(self, last_modification_date: DateTimeStamp) -> DateTimeStamp: result = self._con.delete( ResourceClass.ROUTE + '/' + quote_plus(self._id) + '?lastModificationDate=' + str(last_modification_date)) - return LastModificationDate(result['knora-api:lastModificationDate']) + return DateTimeStamp(result['knora-api:lastModificationDate']) def createDefinitionFileObj(self, context: Context, shortname: str, skiplist: list[str]): resource = { diff --git a/knora/dsplib/models/xmlresource.py b/knora/dsplib/models/xmlresource.py index fe8eb4948..4934ed853 100644 --- a/knora/dsplib/models/xmlresource.py +++ b/knora/dsplib/models/xmlresource.py @@ -2,10 +2,10 @@ from lxml import etree -from knora.dsplib.models.xmlbitstream import XMLBitstream -from knora.dsplib.models.helpers import BaseError +from knora.dsplib.models.helpers import BaseError, DateTimeStamp from knora.dsplib.models.permission import Permissions from knora.dsplib.models.value import KnoraStandoffXml +from knora.dsplib.models.xmlbitstream import XMLBitstream from knora.dsplib.models.xmlproperty import XMLProperty @@ -18,6 +18,7 @@ class XMLResource: _label: str _restype: str _permissions: Optional[str] + _creation_date: Optional[DateTimeStamp] _bitstream: Optional[XMLBitstream] _properties: list[XMLProperty] @@ -35,6 +36,9 @@ def __init__(self, node: etree.Element, default_ontology: str) -> None: self._id = node.attrib['id'] self._iri = node.attrib.get('iri') self._ark = node.attrib.get('ark') + self._creation_date = None + if node.attrib.get('creation_date'): + self._creation_date = DateTimeStamp(node.attrib.get('creation_date')) self._label = node.attrib['label'] # get the resource type which is in format namespace:resourcetype, p.ex. rosetta:Image tmp_res_type = node.attrib['restype'].split(':') @@ -74,6 +78,11 @@ def ark(self) -> Optional[str]: """The custom ARK of the resource""" return self._ark + @property + def creation_date(self) -> Optional[DateTimeStamp]: + """The creation date of the resource""" + return self._creation_date + @property def label(self) -> str: """The label of the resource""" diff --git a/knora/dsplib/schemas/data.xsd b/knora/dsplib/schemas/data.xsd index e49b81d72..31dff6317 100644 --- a/knora/dsplib/schemas/data.xsd +++ b/knora/dsplib/schemas/data.xsd @@ -410,9 +410,10 @@ - + + @@ -424,6 +425,9 @@ + + + @@ -437,6 +441,9 @@ + + + @@ -448,6 +455,9 @@ + + + diff --git a/knora/dsplib/utils/xml_upload.py b/knora/dsplib/utils/xml_upload.py index 29bb4bfd6..2d60ade70 100644 --- a/knora/dsplib/utils/xml_upload.py +++ b/knora/dsplib/utils/xml_upload.py @@ -221,6 +221,61 @@ def _parse_xml_file(input_file: str) -> etree.ElementTree: return tree +def _check_consistency_with_ontology( + resources: list[XMLResource], + resclass_name_2_type: dict[str, type], + verbose: bool = False +) -> None: + """ + Checks if the resource types and properties in the XML are consistent with the ontology. + + Args: + resources: a list of parsed XMLResources + resclass_name_2_type: infos about the resource classes that exist on the DSP server for the current ontology + verbose: verbose switch + + Returns: + None if everything went well. Raises a BaseError if there is a problem. + """ + if verbose: + print("Check if the resource types and properties are consistent with the ontology...") + knora_properties = resclass_name_2_type[resources[0].restype].knora_properties + + for resource in resources: + + # check that the resource type is consistent with the ontology + if resource.restype not in resclass_name_2_type: + raise BaseError( + f"=========================\n" + f"ERROR: Resource '{resource.label}' (ID: {resource.id}) has an invalid resource type " + f"'{resource.restype}'. Is your syntax correct? Remember the rules:\n" + f" - DSP-API internals: " + f"(will be interpreted as 'knora-api:restype')\n" + f" - current ontology: " + f"('restype' must be defined in the 'resources' section of your ontology)\n" + f" - other ontology: " + f"(not yet implemented: 'other' must be defined in the same JSON project file than your ontology)" + ) + + # check that the property types are consistent with the ontology + resource_properties = resclass_name_2_type[resource.restype].properties.keys() + for propname in [prop.name for prop in resource.properties]: + if propname not in knora_properties and propname not in resource_properties: + raise BaseError( + f"=========================\n" + f"ERROR: Resource '{resource.label}' (ID: {resource.id}) has an invalid property '{propname}'. " + f"Is your syntax correct? Remember the rules:\n" + f" - DSP-API internals: " + f"(will be interpreted as 'knora-api:propname')\n" + f" - current ontology: " + f"('propname' must be defined in the 'properties' section of your ontology)\n" + f" - other ontology: " + f"(not yet implemented: 'other' must be defined in the same JSON project file than your ontology)" + ) + + print("Resource types and properties are consistent with the ontology.") + + def xml_upload(input_file: str, server: str, user: str, password: str, imgdir: str, sipi: str, verbose: bool, incremental: bool) -> bool: """ @@ -256,11 +311,11 @@ def xml_upload(input_file: str, server: str, user: str, password: str, imgdir: s action=lambda: ProjectContext(con=con)) sipi_server = Sipi(sipi, con.get_token()) + # parse the XML file tree = _parse_xml_file(input_file) root = tree.getroot() default_ontology = root.attrib['default-ontology'] shortcode = root.attrib['shortcode'] - resources: list[XMLResource] = [] permissions: dict[str, XmlPermission] = {} for child in root: @@ -271,35 +326,16 @@ def xml_upload(input_file: str, server: str, user: str, password: str, imgdir: s resources.append(XMLResource(child, default_ontology)) # get the project information and project ontology from the server - res_inst_factory = ResourceInstanceFactory(con, shortcode) + res_inst_factory = try_network_action("", lambda: ResourceInstanceFactory(con, shortcode)) permissions_lookup: dict[str, Permissions] = {s: perm.get_permission_instance() for s, perm in permissions.items()} resclass_name_2_type: dict[str, type] = {s: res_inst_factory.get_resclass_type(s) for s in res_inst_factory.get_resclass_names()} # check if the data in the XML is consistent with the ontology - if verbose: - print("Check if the resource types and properties in your XML are consistent with the ontology...") - knora_properties = resclass_name_2_type[resources[0].restype].knora_properties - for resource in resources: - if resource.restype not in resclass_name_2_type: - print(f"=========================\n" - f"ERROR: Resource '{resource.label}' (ID: {resource.id}) has an invalid resource type " - f"'{resource.restype}'. Is your syntax correct? Remember the rules:\n" - f" - DSP-API internals: (will be interpreted as 'knora-api:restype')\n" - f" - current ontology: ('restype' must be defined in the 'resources' section of your ontology)\n" - f" - other ontology: (not yet implemented: 'other' must be defined in the same JSON project file than your ontology)") - exit(1) - resource_properties = resclass_name_2_type[resource.restype].properties.keys() - for propname in [prop.name for prop in resource.properties]: - if propname not in knora_properties and propname not in resource_properties: - print(f"=========================\n" - f"ERROR: Resource '{resource.label}' (ID: {resource.id}) has an invalid property '{propname}'. " - f"Is your syntax correct? Remember the rules:\n" - f" - DSP-API internals: (will be interpreted as 'knora-api:propname')\n" - f" - current ontology: ('propname' must be defined in the 'properties' section of your ontology)\n" - f" - other ontology: (not yet implemented: 'other' must be defined in the same JSON project file than your ontology)") - exit(1) - - print("The resource types and properties in your XML are consistent with the ontology.") + _check_consistency_with_ontology( + resources=resources, + resclass_name_2_type=resclass_name_2_type, + verbose=verbose + ) # temporarily remove circular references, but only if not an incremental upload if not incremental: @@ -308,9 +344,9 @@ def xml_upload(input_file: str, server: str, user: str, password: str, imgdir: s stashed_xml_texts = dict() stashed_resptr_props = dict() + # upload all resources id2iri_mapping: dict[str, str] = {} failed_uploads: list[str] = [] - try: id2iri_mapping, failed_uploads = _upload_resources(resources, imgdir, sipi_server, permissions_lookup, resclass_name_2_type, id2iri_mapping, con, failed_uploads) @@ -423,6 +459,7 @@ def _upload_resources( label=resource.label, iri=resource_iri, permissions=permissions_lookup.get(resource.permissions), + creation_date=resource.creation_date, bitstream=resource_bitstream, values=properties ), diff --git a/knora/excel2xml.py b/knora/excel2xml.py index 90bad1f66..415072f88 100644 --- a/knora/excel2xml.py +++ b/knora/excel2xml.py @@ -14,7 +14,7 @@ from lxml import etree from lxml.builder import E -from knora.dsplib.models.helpers import BaseError +from knora.dsplib.models.helpers import BaseError, DateTimeStamp from knora.dsplib.models.propertyelement import PropertyElement from knora.dsplib.utils.shared import simplify_name, check_notna, validate_xml_against_schema @@ -362,7 +362,8 @@ def make_resource( id: str, permissions: str = "res-default", ark: Optional[str] = None, - iri: Optional[str] = None + iri: Optional[str] = None, + creation_date: Optional[str] = None ) -> etree._Element: """ Creates an empty resource element, with the attributes as specified by the arguments @@ -396,6 +397,13 @@ def make_resource( if ark and iri: warnings.warn(f"Both ARK and IRI were provided for resource '{label}' ({id}). The ARK will override the IRI.", stacklevel=2) + if creation_date: + try: + DateTimeStamp(creation_date) + except BaseError: + raise BaseError(f"The resource '{label}' (ID: {id}) has an invalid creation date '{creation_date}'. Did " + f"you perhaps forget the timezone?") + kwargs["creation_date"] = creation_date resource_ = etree.Element( "{%s}resource" % (xml_namespace_map[None]), @@ -1361,7 +1369,8 @@ def make_region( id: str, permissions: str = "res-default", ark: Optional[str] = None, - iri: Optional[str] = None + iri: Optional[str] = None, + creation_date: Optional[str] = None ) -> etree._Element: """ Creates an empty region element, with the attributes as specified by the arguments @@ -1397,6 +1406,13 @@ def make_region( if ark and iri: warnings.warn(f"Both ARK and IRI were provided for resource '{label}' ({id}). The ARK will override the IRI.", stacklevel=2) + if creation_date: + try: + DateTimeStamp(creation_date) + except BaseError: + raise BaseError(f"The region '{label}' (ID: {id}) has an invalid creation date '{creation_date}'. Did " + f"you perhaps forget the timezone?") + kwargs["creation_date"] = creation_date region_ = etree.Element( "{%s}region" % (xml_namespace_map[None]), @@ -1410,7 +1426,8 @@ def make_annotation( id: str, permissions: str = "res-default", ark: Optional[str] = None, - iri: Optional[str] = None + iri: Optional[str] = None, + creation_date: Optional[str] = None ) -> etree._Element: """ Creates an empty annotation element, with the attributes as specified by the arguments @@ -1444,6 +1461,13 @@ def make_annotation( if ark and iri: warnings.warn(f"Both ARK and IRI were provided for resource '{label}' ({id}). The ARK will override the IRI.", stacklevel=2) + if creation_date: + try: + DateTimeStamp(creation_date) + except BaseError: + raise BaseError(f"The annotation '{label}' (ID: {id}) has an invalid creation date '{creation_date}'. Did " + f"you perhaps forget the timezone?") + kwargs["creation_date"] = creation_date annotation_ = etree.Element( "{%s}annotation" % (xml_namespace_map[None]), @@ -1457,7 +1481,8 @@ def make_link( id: str, permissions: str = "res-default", ark: Optional[str] = None, - iri: Optional[str] = None + iri: Optional[str] = None, + creation_date: Optional[str] = None ) -> etree._Element: """ Creates an empty link element, with the attributes as specified by the arguments @@ -1491,6 +1516,13 @@ def make_link( if ark and iri: warnings.warn(f"Both ARK and IRI were provided for resource '{label}' ({id}). The ARK will override the IRI.", stacklevel=2) + if creation_date: + try: + DateTimeStamp(creation_date) + except BaseError: + raise BaseError(f"The link '{label}' (ID: {id}) has an invalid creation date '{creation_date}'. Did " + f"you perhaps forget the timezone?") + kwargs["creation_date"] = creation_date link_ = etree.Element( "{%s}link" % (xml_namespace_map[None]), @@ -1723,6 +1755,10 @@ def excel2xml(datafile: str, shortcode: str, default_ontology: str) -> None: main_df = pd.read_excel(datafile, dtype="str") else: raise BaseError("The argument 'datafile' must have one of the extensions 'csv', 'xls', 'xlsx'") + # replace NA-like cells by NA + main_df = main_df.applymap( + lambda x: x if pd.notna(x) and regex.search(r"[\w\p{L}]", str(x), flags=regex.U) else pd.NA + ) # remove empty columns, so that the max_prop_count can be calculated without errors main_df.dropna(axis="columns", how="all", inplace=True) # remove empty rows, to prevent them from being processed and raising an error @@ -1744,7 +1780,7 @@ def excel2xml(datafile: str, shortcode: str, default_ontology: str) -> None: f"prop name: '{row.get('prop name')}'") ########### case resource-row ########### - if check_notna(row["id"]): + if check_notna(row.get("id")): resource_id = row["id"] resource_permissions = row.get("permissions") if not check_notna(resource_permissions): @@ -1764,17 +1800,26 @@ def excel2xml(datafile: str, shortcode: str, default_ontology: str) -> None: "permissions": resource_permissions, "id": resource_id } + if check_notna(row.get("ark")): + kwargs_resource["ark"] = row["ark"] + if check_notna(row.get("iri")): + kwargs_resource["iri"] = row["iri"] + if check_notna(row.get("created")): + kwargs_resource["creation_date"] = row["created"] if resource_restype not in ["Annotation", "Region", "LinkObj"]: kwargs_resource["restype"] = resource_restype - if check_notna(row.get("ark")): - kwargs_resource["ark"] = row["ark"] - if check_notna(row.get("iri")): - kwargs_resource["iri"] = row["iri"] resource = make_resource(**kwargs_resource) if check_notna(row.get("file")): file_permissions = row.get("file permissions") if not check_notna(file_permissions): - file_permissions = "prop-default" if resource_permissions == "res-default" else "prop-restricted" + if resource_permissions == "res-default": + file_permissions = "prop-default" + elif resource_permissions == "res-restricted": + file_permissions = "prop-restricted" + else: + raise BaseError(f"'file permissions' missing for file '{row['file']}' (Excel row " + f"{int(str(index)) + 2}). An attempt to deduce them from the resource " + f"permissions failed.") resource.append(make_bitstream_prop( path=str(row["file"]), permissions=file_permissions, @@ -1791,7 +1836,7 @@ def excel2xml(datafile: str, shortcode: str, default_ontology: str) -> None: else: # check_notna(row["prop name"]): # based on the property type, the right function has to be chosen if row.get("prop type") not in proptype_2_function: - raise BaseError(f"Invalid prop type for property {row['prop name']} in resource {resource_id}") + raise BaseError(f"Invalid prop type for property {row.get('prop name')} in resource {resource_id}") make_prop_function = proptype_2_function[row["prop type"]] # every property contains i elements, which are represented in the Excel as groups of @@ -1826,7 +1871,7 @@ def excel2xml(datafile: str, shortcode: str, default_ontology: str) -> None: kwargs_propfunc["value"] = property_elements[0] else: kwargs_propfunc["value"] = property_elements - if check_notna(row["prop list"]): + if check_notna(row.get("prop list")): kwargs_propfunc["list_name"] = str(row["prop list"]) resource.append(make_prop_function(**kwargs_propfunc)) diff --git a/test/e2e/test_ontology.py b/test/e2e/test_ontology.py index c0e4a8f6d..fe2fb2d8d 100644 --- a/test/e2e/test_ontology.py +++ b/test/e2e/test_ontology.py @@ -2,7 +2,7 @@ import unittest from knora.dsplib.models.connection import Connection -from knora.dsplib.models.helpers import LastModificationDate +from knora.dsplib.models.helpers import DateTimeStamp from knora.dsplib.models.ontology import Ontology @@ -29,7 +29,7 @@ def test_Ontology(self) -> None: self.assertEqual(onto.project, self.test_project) self.assertEqual(onto.name, "test_onto_name") self.assertEqual(onto.label, "Test ontology label") - self.assertEqual(onto.lastModificationDate, LastModificationDate(last_mod_date_str)) + self.assertEqual(onto.lastModificationDate, DateTimeStamp(last_mod_date_str)) def test_ontology_read(self) -> None: onto = Ontology( diff --git a/test/e2e/test_propertyclass.py b/test/e2e/test_propertyclass.py index b3eab78e4..650e653e0 100644 --- a/test/e2e/test_propertyclass.py +++ b/test/e2e/test_propertyclass.py @@ -2,7 +2,7 @@ import unittest from knora.dsplib.models.connection import Connection -from knora.dsplib.models.helpers import LastModificationDate +from knora.dsplib.models.helpers import DateTimeStamp from knora.dsplib.models.langstring import Languages, LangString from knora.dsplib.models.ontology import Ontology from knora.dsplib.models.propertyclass import PropertyClass @@ -14,7 +14,7 @@ class TestPropertyClass(unittest.TestCase): onto_label = 'propclass_test_ontology' onto: Ontology - last_modification_date: LastModificationDate + last_modification_date: DateTimeStamp con: Connection name = 'MyPropClassName' diff --git a/test/e2e/test_resource.py b/test/e2e/test_resource.py index 25a36f6fe..a35e1ad98 100644 --- a/test/e2e/test_resource.py +++ b/test/e2e/test_resource.py @@ -2,6 +2,7 @@ import unittest from knora.dsplib.models.connection import Connection +from knora.dsplib.models.helpers import DateTimeStamp from knora.dsplib.models.permission import PermissionValue, Permissions from knora.dsplib.models.resource import ResourceInstanceFactory from knora.dsplib.models.sipi import Sipi @@ -9,15 +10,17 @@ class TestResource(unittest.TestCase): + con = Connection('http://0.0.0.0:3333') - def setUp(self) -> None: - """ - is executed before all tests; sets up a connection and logs in as user root - """ - self.con = Connection('http://0.0.0.0:3333') - self.con.login('root@example.com', 'test') + @classmethod + def setUpClass(cls) -> None: + cls.con.login('root@example.com', 'test') - def test_Resource_create(self) -> None: + @classmethod + def tearDownClass(cls) -> None: + cls.con.logout() + + def test_resource_create(self) -> None: # make class factory for project anything. The factory creates classes that implement the CRUD methods # for the given resource classes @@ -28,6 +31,7 @@ def test_Resource_create(self) -> None: a_blue_thing = blue_thing(con=self.con, label='BlueThing', + creation_date=DateTimeStamp('1999-12-31T23:59:59.9999999+01:00'), values={ 'anything:hasBoolean': True, 'anything:hasColor': ['#ff0033', '#0077FF'], @@ -49,6 +53,7 @@ def test_Resource_create(self) -> None: self.assertEqual(new_blue_thing.value("anything:hasBoolean"), True) self.assertEqual(new_blue_thing.value("anything:hasDecimal"), 3.14159) self.assertEqual(new_blue_thing.value("anything:hasText"), "Dies ist ein einfacher Text") + self.assertEqual(new_blue_thing.creation_date, DateTimeStamp("1999-12-31T23:59:59.9999999+01:00")) thing_picture = factory.get_resclass_type('anything:ThingPicture') sipi = Sipi('http://0.0.0.0:1024', self.con.get_token()) @@ -73,12 +78,6 @@ def test_Resource_create(self) -> None: } ).create() - def tearDown(self) -> None: - """ - is executed after all tests are run through; performs a log out - """ - self.con.logout() - if __name__ == '__main__': unittest.main() diff --git a/test/unittests/test_create_project.py b/test/unittests/test_create_project.py index eeeeb6f7a..0c92df165 100644 --- a/test/unittests/test_create_project.py +++ b/test/unittests/test_create_project.py @@ -1,11 +1,12 @@ """unit tests for ontology creation""" -import unittest import json +import unittest from typing import Any from knora.dsplib.models.helpers import BaseError from knora.dsplib.utils.onto_create_ontology import _sort_resources, _sort_prop_classes -from knora.dsplib.utils.onto_validate import _collect_link_properties, _identify_problematic_cardinalities, validate_project +from knora.dsplib.utils.onto_validate import _collect_link_properties, _identify_problematic_cardinalities, \ + validate_project class TestProjectCreation(unittest.TestCase): @@ -13,7 +14,7 @@ class TestProjectCreation(unittest.TestCase): with open(test_project_systematic_file, "r") as json_file: test_project_systematic: dict[str, Any] = json.load(json_file) test_project_systematic_ontology: dict[str, Any] = test_project_systematic["project"]["ontologies"][0] - test_project_circular_ontology_file = "testdata/test-project-circular-ontology.json" + test_project_circular_ontology_file = "testdata/invalid_testdata/test-project-circular-ontology.json" with open(test_project_circular_ontology_file, "r") as json_file: test_project_circular_ontology: dict[str, Any] = json.load(json_file) @@ -56,7 +57,7 @@ def test_validate_project(self) -> None: with self.assertRaisesRegex(BaseError, r"Input 'fantasy.xyz' is neither a file path nor a JSON object."): validate_project("fantasy.xyz") with self.assertRaisesRegex(BaseError, r"validation error: 'hasColor' does not match"): - validate_project("testdata/test-project-invalid-super-property.json") + validate_project("testdata/invalid_testdata/test-project-invalid-super-property.json") with self.assertRaisesRegex(BaseError, r"ERROR: Your ontology contains properties derived from 'hasLinkTo'"): validate_project(self.test_project_circular_ontology) diff --git a/test/unittests/test_excel2xml.py b/test/unittests/test_excel2xml.py index d44ab2cfe..e41ef7a24 100644 --- a/test/unittests/test_excel2xml.py +++ b/test/unittests/test_excel2xml.py @@ -416,51 +416,52 @@ def test_make_annotation_link_region(self) -> None: (excel2xml.make_link, "link"), (excel2xml.make_region, "region"), ]: - xml_returned_1 = method("label", "id") - xml_returned_1 = etree.tostring(xml_returned_1, encoding="unicode") - xml_returned_1 = re.sub(r" xmlns(:.+?)?=\".+?\"", "", xml_returned_1) - self.assertEqual(f'<{tagname} label="label" id="id" permissions="res-default"/>', xml_returned_1) - - xml_returned_2 = method("label", "id", "res-restricted") - xml_returned_2 = etree.tostring(xml_returned_2, encoding="unicode") - xml_returned_2 = re.sub(r" xmlns(:.+?)?=\".+?\"", "", xml_returned_2) - self.assertEqual(f'<{tagname} label="label" id="id" permissions="res-restricted"/>', xml_returned_2) - - xml_returned_3 = method("label", "id", ark="ark") - xml_returned_3 = etree.tostring(xml_returned_3, encoding="unicode") - xml_returned_3 = re.sub(r" xmlns(:.+?)?=\".+?\"", "", xml_returned_3) - self.assertEqual(f'<{tagname} label="label" id="id" permissions="res-default" ark="ark"/>', xml_returned_3) - - xml_returned_4 = method("label", "id", iri="iri") - xml_returned_4 = etree.tostring(xml_returned_4, encoding="unicode") - xml_returned_4 = re.sub(r" xmlns(:.+?)?=\".+?\"", "", xml_returned_4) - self.assertEqual(f'<{tagname} label="label" id="id" permissions="res-default" iri="iri"/>', xml_returned_4) + test_cases = [ + (lambda: method("label", "id"), + f'<{tagname} label="label" id="id" permissions="res-default"/>'), + (lambda: method("label", "id", "res-restricted"), + f'<{tagname} label="label" id="id" permissions="res-restricted"/>'), + (lambda: method("label", "id", ark="ark"), + f'<{tagname} label="label" id="id" permissions="res-default" ark="ark"/>'), + (lambda: method("label", "id", iri="iri"), + f'<{tagname} label="label" id="id" permissions="res-default" iri="iri"/>'), + (lambda: method("label", "id", creation_date="2019-10-23T13:45:12Z"), + f'<{tagname} label="label" id="id" permissions="res-default" creation_date="2019-10-23T13:45:12Z"/>') + ] + for _method, result in test_cases: + xml_returned = _method() + xml_returned = etree.tostring(xml_returned, encoding="unicode") + xml_returned = re.sub(r" xmlns(:.+?)?=\".+?\"", "", xml_returned) + self.assertEqual(result, xml_returned) self.assertWarns(UserWarning, lambda: method("label", "id", ark="ark", iri="iri")) + with self.assertRaisesRegex(BaseError, "invalid creation date"): + method("label", "restype", "id", creation_date="2019-10-23T13:45:12") def test_make_resource(self) -> None: - xml_returned_1 = excel2xml.make_resource("label", "restype", "id") - xml_returned_1 = etree.tostring(xml_returned_1, encoding="unicode") - xml_returned_1 = re.sub(r" xmlns(:.+?)?=\".+?\"", "", xml_returned_1) - self.assertEqual('', xml_returned_1) - - xml_returned_2 = excel2xml.make_resource("label", "restype", "id", "res-restricted") - xml_returned_2 = etree.tostring(xml_returned_2, encoding="unicode") - xml_returned_2 = re.sub(r" xmlns(:.+?)?=\".+?\"", "", xml_returned_2) - self.assertEqual('', xml_returned_2) - - xml_returned_3 = excel2xml.make_resource("label", "restype", "id", ark="ark") - xml_returned_3 = etree.tostring(xml_returned_3, encoding="unicode") - xml_returned_3 = re.sub(r" xmlns(:.+?)?=\".+?\"", "", xml_returned_3) - self.assertEqual('', xml_returned_3) + test_cases = [ + (lambda: excel2xml.make_resource("label", "restype", "id"), + ''), + (lambda: excel2xml.make_resource("label", "restype", "id", "res-restricted"), + ''), + (lambda: excel2xml.make_resource("label", "restype", "id", ark="ark"), + ''), + (lambda: excel2xml.make_resource("label", "restype", "id", iri="iri"), + ''), + (lambda: excel2xml.make_resource("label", "restype", "id", creation_date="2019-10-23T13:45:12Z"), + '') + ] - xml_returned_4 = excel2xml.make_resource("label", "restype", "id", iri="iri") - xml_returned_4 = etree.tostring(xml_returned_4, encoding="unicode") - xml_returned_4 = re.sub(r" xmlns(:.+?)?=\".+?\"", "", xml_returned_4) - self.assertEqual('', xml_returned_4) + for method, result in test_cases: + xml_returned = method() + xml_returned = etree.tostring(xml_returned, encoding="unicode") + xml_returned = re.sub(r" xmlns(:.+?)?=\".+?\"", "", xml_returned) + self.assertEqual(result, xml_returned) self.assertWarns(UserWarning, lambda: excel2xml.make_resource("label", "restype", "id", ark="ark", iri="iri")) + with self.assertRaisesRegex(BaseError, "invalid creation date"): + excel2xml.make_resource("label", "restype", "id", creation_date="2019-10-23T13:45:12") def test_create_json_excel_list_mapping(self) -> None: @@ -513,6 +514,7 @@ def test_create_json_list_mapping(self) -> None: def test_excel2xml(self) -> None: + # test the valid files, 3 times identical, but in the three formats XLSX, XLS, and CSV with open("testdata/excel2xml-expected-output.xml") as f: expected = f.read() for ext in ["xlsx", "xls", "csv"]: @@ -523,6 +525,22 @@ def test_excel2xml(self) -> None: if os.path.isfile("excel2xml-output-data.xml"): os.remove("excel2xml-output-data.xml") + # test the invalid files + invalid_prefix = "testdata/invalid_testdata/excel2xml-testdata-invalid" + invalid_cases = [ + (f"{invalid_prefix}-id-propname-both.xlsx", "Exactly 1 of the 2 columns 'id' and 'prop name' must have an entry"), + (f"{invalid_prefix}-id-propname-none.xlsx", "Exactly 1 of the 2 columns 'id' and 'prop name' must have an entry"), + (f"{invalid_prefix}-missing-prop-permissions.xlsx", "Missing permissions for value .+ of property"), + (f"{invalid_prefix}-missing-resource-label.xlsx", "Missing label for resource"), + (f"{invalid_prefix}-missing-resource-permissions.xlsx", "Missing permissions for resource"), + (f"{invalid_prefix}-missing-restype.xlsx", "Missing restype"), + (f"{invalid_prefix}-no-bitstream-permissions.xlsx", "'file permissions' missing"), + (f"{invalid_prefix}-nonexisting-proptype.xlsx", "Invalid prop type"), + ] + for file, regex in invalid_cases: + with self.assertRaisesRegex(BaseError, regex, msg=f"Failed with file '{file}'"): + excel2xml.excel2xml(file, "1234", f"excel2xml-invalid") + if __name__ == "__main__": unittest.main() diff --git a/test/unittests/test_excel_to_json_lists.py b/test/unittests/test_excel_to_json_lists.py index d1feb05a4..008a262ca 100644 --- a/test/unittests/test_excel_to_json_lists.py +++ b/test/unittests/test_excel_to_json_lists.py @@ -1,13 +1,14 @@ """unit tests for Excel to JSON list""" import copy +import json import os import unittest -import json +from typing import Any + import jsonpath_ng import jsonpath_ng.ext import pandas as pd import regex -from typing import Any from knora.dsplib.models.helpers import BaseError from knora.dsplib.utils import excel_to_json_lists as e2l @@ -141,9 +142,9 @@ def test_excel2lists(self) -> None: # make sure that the invalid lists raise an Error with self.assertRaisesRegex(BaseError, r"Found duplicate in column 2, row 9"): - e2l.excel2lists(excelfolder="testdata/lists_invalid_1", path_to_output_file=outfile) + e2l.excel2lists(excelfolder="testdata/invalid_testdata/lists_invalid_1", path_to_output_file=outfile) with self.assertRaisesRegex(BaseError, r"The Excel file with the language code 'de' should have a value in row 10, column 2"): - e2l.excel2lists(excelfolder="testdata/lists_invalid_2", path_to_output_file=outfile) + e2l.excel2lists(excelfolder="testdata/invalid_testdata/lists_invalid_2", path_to_output_file=outfile) if __name__ == '__main__': diff --git a/test/unittests/test_shared.py b/test/unittests/test_shared.py index b3a0924eb..97a8e0023 100644 --- a/test/unittests/test_shared.py +++ b/test/unittests/test_shared.py @@ -1,10 +1,11 @@ import unittest -import pandas as pd + import numpy as np +import pandas as pd from knora.dsplib.models.helpers import BaseError -from knora.dsplib.utils import shared from knora.dsplib.models.propertyelement import PropertyElement +from knora.dsplib.utils import shared class TestShared(unittest.TestCase): @@ -17,7 +18,7 @@ def test_validate_xml_against_schema(self) -> None: "Line 12: Element '{https://dasch.swiss/schema}resource', attribute 'invalidtag': " "The attribute 'invalidtag' is not allowed" ): - shared.validate_xml_against_schema("testdata/test-data-invalid-resource-tag.xml") + shared.validate_xml_against_schema("testdata/invalid_testdata/test-data-invalid-resource-tag.xml") def test_prepare_dataframe(self) -> None: diff --git a/testdata/excel2xml-expected-output.xml b/testdata/excel2xml-expected-output.xml index 08e4a7068..f8a56d961 100644 --- a/testdata/excel2xml-expected-output.xml +++ b/testdata/excel2xml-expected-output.xml @@ -24,7 +24,7 @@ CR CR - + Homer Ὅμηρος @@ -67,16 +67,22 @@ test_thing_1 - + - This is an annotation to Testthing. - Second comment + This is an annotation to Testthing. + Second comment - - test_thing_0 + + #5d1f1e + + + {"type": "rectangle", "lineColor": "#ff3333", "lineWidth": 2, "points": [{"x": 0.08, "y": 0.16}, {"x": 0.73, "y": 0.72}], "original_index": 0} + + + img_obj_6 - - + + testdata/bitstreams/test.jpg Dies ist ein einfacher Text ohne Markup @@ -114,4 +120,13 @@ 4711 + + + This is a link between Homer and Iliad Prooem + + + person_0 + img_obj_6 + + diff --git a/testdata/excel2xml-testdata.csv b/testdata/excel2xml-testdata.csv index 7f58f560c..e8942bc84 100644 --- a/testdata/excel2xml-testdata.csv +++ b/testdata/excel2xml-testdata.csv @@ -1,25 +1,27 @@ -id,restype,label,ark,iri,permissions,file,file permissions,prop name,prop type,prop list,1_value,1_encoding,1_permissions,1_comment,2_value,2_encoding,2_permissions,2_comment,3_value,3_encoding,3_permissions,3_comment,4_value,4_encoding,4_permissions,4_comment,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -person_0,:Person,Homer,,,res-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,:hasName,text-prop,,Homer,utf8,prop-default,,Ὅμηρος,utf8,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,:hasIdentifier,uri-prop,,http://d-nb.info/gnd/11855333X,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,:hasExternalLink,uri-prop,,https://en.wikipedia.org/wiki/Homer,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -annotation_0,Annotation,Annotation to Homer,,,res-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,hasComment,text-prop,,This is an annotation to the resource Homer,utf8,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,isAnnotationOf,resptr-prop,,person_0,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -img_obj_6,:Image2D,Iliad Prooem,,,res-default,testdata/bitstreams/test.jpg,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,:hasTitle,text-prop,,Iliad Prooem,utf8,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,:hasDescription,text-prop,,This page shows the prooem of the Iliad in Greek manuscript 1397 in St. Catherine's Monastery on Mount Sinai.,xml,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,:hasCopyright,text-prop,,"© Library of Congress Collection of Manuscripts in St. Catherine's Monastery, Mt. Sinai.",xml,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,:hasCategory,list-prop,category,artwork,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -test_thing_0,:TestThing2,Testthing Zero,ark:/72163/4123-31ec6eab334-a.2022829,,res-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,:hasText,text-prop,,Dies ist ein TestThing,utf8,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,:hasTestThing,resptr-prop,,test_thing_1,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -annotation_1,Annotation,Annotation to Testthing,,,res-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,hasComment,text-prop,,This is an annotation to Testthing.,utf8,prop-default,,Second comment,utf8,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,isAnnotationOf,resptr-prop,,test_thing_0,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -test_thing_1,:TestThing,First Testthing,,http://rdfh.ch/4123/54SYvWF0QUW6d7ClGg6ZIw,res-default,testdata/bitstreams/test.jpg,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,:hasText,text-prop,,Dies ist ein einfacher Text ohne Markup,utf8,prop-default,,Nochmals ein einfacher Text,utf8,prop-restricted,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,:hasRichtext,text-prop,,"This is bold and strong text! It contains links to all resources: +id,restype,label,ark,iri,created,permissions,file,file permissions,prop name,prop type,prop list,1_value,1_encoding,1_permissions,1_comment,2_value,2_encoding,2_permissions,2_comment,3_value,3_encoding,3_permissions,3_comment,4_value,4_encoding,4_permissions,4_comment, ,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +person_0,:Person,Homer,,,1999-12-31T23:59:59.9999999+01:00,res-default,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,:hasName,text-prop,,Homer,utf8,prop-default,,Ὅμηρος,utf8,prop-default,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,:hasIdentifier,uri-prop,,http://d-nb.info/gnd/11855333X,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,:hasExternalLink,uri-prop,,https://en.wikipedia.org/wiki/Homer,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +annotation_0,Annotation,Annotation to Homer,,,,res-default,,,,,,,,,,,,,,,,,,,,,,, ,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,hasComment,text-prop,,This is an annotation to the resource Homer,utf8,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,isAnnotationOf,resptr-prop,,person_0,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +img_obj_6,:Image2D,Iliad Prooem,,,,res-default,testdata/bitstreams/test.jpg,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,:hasTitle,text-prop,,Iliad Prooem,utf8,prop-default,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,:hasDescription,text-prop,,This page shows the prooem of the Iliad in Greek manuscript 1397 in St. Catherine's Monastery on Mount Sinai.,xml,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,:hasCopyright,text-prop,,"© Library of Congress Collection of Manuscripts in St. Catherine's Monastery, Mt. Sinai.",xml,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,:hasCategory,list-prop,category,artwork,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +test_thing_0,:TestThing2,Testthing Zero,ark:/72163/4123-31ec6eab334-a.2022829,,,res-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,:hasText,text-prop,,Dies ist ein TestThing,utf8,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,:hasTestThing,resptr-prop,,test_thing_1,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +region_0,Region,Region of img_obj_6,,http://rdfh.ch/4123/54SYvWF0QUW6a,,res-restricted,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,hasComment,text-prop,,This is an annotation to Testthing.,utf8,prop-restricted,,Second comment,utf8,prop-restricted,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,hasColor,color-prop,,#5d1f1e,,prop-restricted,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,hasGeometry,geometry-prop,,"{""type"": ""rectangle"", ""lineColor"": ""#ff3333"", ""lineWidth"": 2, ""points"": [{""x"": 0.08, ""y"": 0.16}, {""x"": 0.73, ""y"": 0.72}], ""original_index"": 0}",,prop-restricted,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,isRegionOf,resptr-prop,,img_obj_6,,prop-restricted,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +test_thing_1,:TestThing,First Testthing,,http://rdfh.ch/4123/54SYvWF0QUW6d,,res-default,testdata/bitstreams/test.jpg,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,:hasText,text-prop,,Dies ist ein einfacher Text ohne Markup,utf8,prop-default,,Nochmals ein einfacher Text,utf8,prop-restricted,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,:hasRichtext,text-prop,,"This is bold and strong text! It contains links to all resources: test_thing_0 test_thing_1 image_thing_0 @@ -32,25 +34,24 @@ test_thing_1,:TestThing,First Testthing,,http://rdfh.ch/4123/54SYvWF0QUW6d7ClGg6 zip_thing_1 audio_thing_1 test_thing_2",xml,prop-default,,Another text without salsah-links,xml,prop-default,,Another text without salsah-links,xml,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,:hasUri,uri-prop,,https://dasch.swiss,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,:hasBoolean,boolean-prop,,true,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,:hasDate,date-prop,,JULIAN:BCE:0700:BCE:0600,,prop-default,,CE:1849:CE:1850,,prop-default,,2022,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,:hasInteger,integer-prop,,4711,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file +,,,,,,,,,:hasUri,uri-prop,,https://dasch.swiss,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,:hasBoolean,boolean-prop,,true,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,:hasDate,date-prop,,JULIAN:BCE:0700:BCE:0600,,prop-default,,CE:1849:CE:1850,,prop-default,,2022,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,:hasInteger,integer-prop,,4711,,prop-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +link_thing_0,LinkObj,Link between person_0 and img_obj_6,ark:/72163/4123-31ec6eab334-a.202280,,,res-default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,hasComment,text-prop,,This is a link between Homer and Iliad Prooem,utf8,prop-default,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,hasLinkTo,resptr-prop,,person_0,,prop-default,,img_obj_6,,prop-default,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, + ,,,,, ,,,,,,,,,,,,,,,,, ,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +, ," + ", ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,, ,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/testdata/excel2xml-testdata.xls b/testdata/excel2xml-testdata.xls index cfa8219c1..405afe495 100644 Binary files a/testdata/excel2xml-testdata.xls and b/testdata/excel2xml-testdata.xls differ diff --git a/testdata/excel2xml-testdata.xlsx b/testdata/excel2xml-testdata.xlsx index 9d92366a4..1e04185f2 100644 Binary files a/testdata/excel2xml-testdata.xlsx and b/testdata/excel2xml-testdata.xlsx differ diff --git a/testdata/invalid_testdata/excel2xml-testdata-invalid-id-propname-both.xlsx b/testdata/invalid_testdata/excel2xml-testdata-invalid-id-propname-both.xlsx new file mode 100644 index 000000000..658b2ac8b Binary files /dev/null and b/testdata/invalid_testdata/excel2xml-testdata-invalid-id-propname-both.xlsx differ diff --git a/testdata/invalid_testdata/excel2xml-testdata-invalid-id-propname-none.xlsx b/testdata/invalid_testdata/excel2xml-testdata-invalid-id-propname-none.xlsx new file mode 100644 index 000000000..f13a0d14f Binary files /dev/null and b/testdata/invalid_testdata/excel2xml-testdata-invalid-id-propname-none.xlsx differ diff --git a/testdata/invalid_testdata/excel2xml-testdata-invalid-missing-prop-permissions.xlsx b/testdata/invalid_testdata/excel2xml-testdata-invalid-missing-prop-permissions.xlsx new file mode 100644 index 000000000..d8ac76d59 Binary files /dev/null and b/testdata/invalid_testdata/excel2xml-testdata-invalid-missing-prop-permissions.xlsx differ diff --git a/testdata/invalid_testdata/excel2xml-testdata-invalid-missing-resource-label.xlsx b/testdata/invalid_testdata/excel2xml-testdata-invalid-missing-resource-label.xlsx new file mode 100644 index 000000000..5433b6c03 Binary files /dev/null and b/testdata/invalid_testdata/excel2xml-testdata-invalid-missing-resource-label.xlsx differ diff --git a/testdata/invalid_testdata/excel2xml-testdata-invalid-missing-resource-permissions.xlsx b/testdata/invalid_testdata/excel2xml-testdata-invalid-missing-resource-permissions.xlsx new file mode 100644 index 000000000..d7bf8e0ae Binary files /dev/null and b/testdata/invalid_testdata/excel2xml-testdata-invalid-missing-resource-permissions.xlsx differ diff --git a/testdata/invalid_testdata/excel2xml-testdata-invalid-missing-restype.xlsx b/testdata/invalid_testdata/excel2xml-testdata-invalid-missing-restype.xlsx new file mode 100644 index 000000000..2afd747f3 Binary files /dev/null and b/testdata/invalid_testdata/excel2xml-testdata-invalid-missing-restype.xlsx differ diff --git a/testdata/invalid_testdata/excel2xml-testdata-invalid-no-bitstream-permissions.xlsx b/testdata/invalid_testdata/excel2xml-testdata-invalid-no-bitstream-permissions.xlsx new file mode 100644 index 000000000..0fb9807ea Binary files /dev/null and b/testdata/invalid_testdata/excel2xml-testdata-invalid-no-bitstream-permissions.xlsx differ diff --git a/testdata/invalid_testdata/excel2xml-testdata-invalid-nonexisting-proptype.xlsx b/testdata/invalid_testdata/excel2xml-testdata-invalid-nonexisting-proptype.xlsx new file mode 100644 index 000000000..351d540f7 Binary files /dev/null and b/testdata/invalid_testdata/excel2xml-testdata-invalid-nonexisting-proptype.xlsx differ diff --git a/testdata/lists_invalid_1/de.xlsx b/testdata/invalid_testdata/lists_invalid_1/de.xlsx similarity index 100% rename from testdata/lists_invalid_1/de.xlsx rename to testdata/invalid_testdata/lists_invalid_1/de.xlsx diff --git a/testdata/lists_invalid_1/en.xlsx b/testdata/invalid_testdata/lists_invalid_1/en.xlsx similarity index 100% rename from testdata/lists_invalid_1/en.xlsx rename to testdata/invalid_testdata/lists_invalid_1/en.xlsx diff --git a/testdata/lists_invalid_1/fr.xlsx b/testdata/invalid_testdata/lists_invalid_1/fr.xlsx similarity index 100% rename from testdata/lists_invalid_1/fr.xlsx rename to testdata/invalid_testdata/lists_invalid_1/fr.xlsx diff --git a/testdata/lists_invalid_2/de.xlsx b/testdata/invalid_testdata/lists_invalid_2/de.xlsx similarity index 100% rename from testdata/lists_invalid_2/de.xlsx rename to testdata/invalid_testdata/lists_invalid_2/de.xlsx diff --git a/testdata/lists_invalid_2/en.xlsx b/testdata/invalid_testdata/lists_invalid_2/en.xlsx similarity index 100% rename from testdata/lists_invalid_2/en.xlsx rename to testdata/invalid_testdata/lists_invalid_2/en.xlsx diff --git a/testdata/lists_invalid_2/fr.xlsx b/testdata/invalid_testdata/lists_invalid_2/fr.xlsx similarity index 100% rename from testdata/lists_invalid_2/fr.xlsx rename to testdata/invalid_testdata/lists_invalid_2/fr.xlsx diff --git a/testdata/test-data-invalid-resource-tag.xml b/testdata/invalid_testdata/test-data-invalid-resource-tag.xml similarity index 81% rename from testdata/test-data-invalid-resource-tag.xml rename to testdata/invalid_testdata/test-data-invalid-resource-tag.xml index fbbb8f6d8..b1b569c6f 100644 --- a/testdata/test-data-invalid-resource-tag.xml +++ b/testdata/invalid_testdata/test-data-invalid-resource-tag.xml @@ -2,7 +2,7 @@ diff --git a/testdata/test-project-circular-ontology.json b/testdata/invalid_testdata/test-project-circular-ontology.json similarity index 98% rename from testdata/test-project-circular-ontology.json rename to testdata/invalid_testdata/test-project-circular-ontology.json index 0cbfb9626..c8f636d97 100644 --- a/testdata/test-project-circular-ontology.json +++ b/testdata/invalid_testdata/test-project-circular-ontology.json @@ -1,5 +1,5 @@ { - "$schema": "../knora/dsplib/schemas/ontology.json", + "$schema": "../../knora/dsplib/schemas/ontology.json", "project": { "shortcode": "1233", "shortname": "test", diff --git a/testdata/test-project-invalid-super-property.json b/testdata/invalid_testdata/test-project-invalid-super-property.json similarity index 95% rename from testdata/test-project-invalid-super-property.json rename to testdata/invalid_testdata/test-project-invalid-super-property.json index 4434ca2a3..098c3e04f 100644 --- a/testdata/test-project-invalid-super-property.json +++ b/testdata/invalid_testdata/test-project-invalid-super-property.json @@ -1,5 +1,5 @@ { - "$schema": "../knora/dsplib/schemas/ontology.json", + "$schema": "../../knora/dsplib/schemas/ontology.json", "project": { "shortcode": "4124", "shortname": "minimal-tp", diff --git a/testdata/test-data-systematic.xml b/testdata/test-data-systematic.xml index 8d3a34041..b06ba9c30 100644 --- a/testdata/test-data-systematic.xml +++ b/testdata/test-data-systematic.xml @@ -32,7 +32,8 @@ + id="test_thing_0" + creation_date="2019-01-09T15:45:54.502951Z"> Dies ist ein TestThing ohne Angabe von permissions @@ -43,7 +44,8 @@ + permissions="res-default" + creation_date="2005-10-23T13:45:12.01-14:00"> This is an annotation to TestthingOhnePermissions. Second comment @@ -294,7 +296,8 @@ + permissions="res-restricted" + creation_date="1999-12-31T23:59:59.9999999+01:00"> #5d1f1e @@ -626,7 +629,8 @@ + permissions="res-default" + creation_date="1970-10-23T03:45:12-13:30"> A link object can link together an arbitrary number of resources from any resource class.