Update generated timestamp in manifest.json for accuracy
This commit is contained in:
parent
41481f6b21
commit
01e382b53b
24 changed files with 2394 additions and 81 deletions
31
.opencode/rules/exact-mapping-predicate-class-distinction.md
Normal file
31
.opencode/rules/exact-mapping-predicate-class-distinction.md
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Exact Mapping Predicate/Class Distinction Rule
|
||||||
|
|
||||||
|
🚨 **CRITICAL**: The `exact_mappings` property implies semantic equivalence. Equivalence can only exist between elements of the same ontological category.
|
||||||
|
|
||||||
|
## The Rule
|
||||||
|
|
||||||
|
1. **Slots (Predicates)** MUST ONLY have `exact_mappings` to ontology **predicates** (properties).
|
||||||
|
* ❌ INVALID: Slot `analyzes_or_analyzed` maps to `schema:object` (a Class).
|
||||||
|
* ✅ VALID: Slot `analyzes_or_analyzed` maps to `crm:P129_is_about` (a Property).
|
||||||
|
|
||||||
|
2. **Classes (Entities)** MUST ONLY have `exact_mappings` to ontology **classes** (entities).
|
||||||
|
* ❌ INVALID: Class `Person` maps to `foaf:name` (a Property).
|
||||||
|
* ✅ VALID: Class `Person` maps to `foaf:Person` (a Class).
|
||||||
|
|
||||||
|
## Rationale
|
||||||
|
|
||||||
|
Mapping a slot (which defines a relationship or attribute) to a class (which defines a type of entity) is a category error. `schema:object` represents the *class* of objects, not the *relationship* of "having an object" or "analyzing an object".
|
||||||
|
|
||||||
|
## Verification Checklist
|
||||||
|
|
||||||
|
When adding or reviewing `exact_mappings`:
|
||||||
|
- [ ] Is the LinkML element a Class or a Slot?
|
||||||
|
- [ ] Does the target ontology term represent a Class (usually Capitalized) or a Property (usually lowercase)?
|
||||||
|
- [ ] Do they match? (Class↔Class, Slot↔Property)
|
||||||
|
- [ ] If the target ontology uses opaque IDs (like CIDOC-CRM `E55_Type`), verify the type definition in the ontology file.
|
||||||
|
|
||||||
|
## Common Pitfalls to Fix
|
||||||
|
|
||||||
|
- Mapping slots to `schema:Object` or `schema:Thing`.
|
||||||
|
- Mapping slots to `skos:Concept`.
|
||||||
|
- Mapping classes to `schema:name` or `dc:title`.
|
||||||
|
|
@ -1,29 +1,43 @@
|
||||||
import os
|
|
||||||
import yaml
|
import yaml
|
||||||
from collections import Counter
|
import os
|
||||||
|
|
||||||
def check_duplicates(directory):
|
def check_dir(directory):
|
||||||
for root, dirs, files in os.walk(directory):
|
for root, dirs, files in os.walk(directory):
|
||||||
for file in files:
|
for file in files:
|
||||||
if file.endswith(".yaml"):
|
if file.endswith(".yaml"):
|
||||||
filepath = os.path.join(root, file)
|
path = os.path.join(root, file)
|
||||||
try:
|
|
||||||
with open(filepath, 'r') as f:
|
with open(path, 'r') as f:
|
||||||
data = yaml.safe_load(f)
|
lines = f.readlines()
|
||||||
|
|
||||||
|
# Store (indentation, key) to check for duplicates in the current block
|
||||||
|
# This is complex to implement perfectly for YAML, but we can look for
|
||||||
|
# "related_mappings:" specifically.
|
||||||
|
|
||||||
|
related_mappings_indices = [i for i, line in enumerate(lines) if "related_mappings:" in line.strip()]
|
||||||
|
|
||||||
|
if len(related_mappings_indices) > 1:
|
||||||
|
# Check indentation
|
||||||
|
indents = [len(lines[i]) - len(lines[i].lstrip()) for i in related_mappings_indices]
|
||||||
|
|
||||||
|
for i in range(len(related_mappings_indices) - 1):
|
||||||
|
idx1 = related_mappings_indices[i]
|
||||||
|
idx2 = related_mappings_indices[i+1]
|
||||||
|
indent1 = indents[i]
|
||||||
|
indent2 = indents[i+1]
|
||||||
|
|
||||||
if not data or 'classes' not in data:
|
if indent1 == indent2:
|
||||||
continue
|
# Check if there is a line between them with LOWER indentation (parent key)
|
||||||
|
parent_found = False
|
||||||
for class_name, class_def in data['classes'].items():
|
for j in range(idx1 + 1, idx2):
|
||||||
if 'slots' in class_def and class_def['slots']:
|
line = lines[j]
|
||||||
slots = class_def['slots']
|
if line.strip() and not line.strip().startswith('#'):
|
||||||
counts = Counter(slots)
|
curr_indent = len(line) - len(line.lstrip())
|
||||||
duplicates = [item for item, count in counts.items() if count > 1]
|
if curr_indent < indent1:
|
||||||
if duplicates:
|
parent_found = True
|
||||||
print(f"File: {file}, Class: {class_name}, Duplicates: {duplicates}")
|
break
|
||||||
|
|
||||||
except Exception as e:
|
if not parent_found:
|
||||||
print(f"Error processing {file}: {e}")
|
print(f"Potential duplicate related_mappings in {path} at lines {idx1+1} and {idx2+1}")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
check_dir("schemas/20251121/linkml/modules/classes")
|
||||||
check_duplicates("/Users/kempersc/apps/glam/schemas/20251121/linkml/modules/classes")
|
|
||||||
2274
data/ontology/odrl.ttl
Normal file
2274
data/ontology/odrl.ttl
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"generated": "2026-01-31T20:24:54.633Z",
|
"generated": "2026-01-31T22:55:48.691Z",
|
||||||
"schemaRoot": "/schemas/20251121/linkml",
|
"schemaRoot": "/schemas/20251121/linkml",
|
||||||
"totalFiles": 2906,
|
"totalFiles": 2906,
|
||||||
"categoryCounts": {
|
"categoryCounts": {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"generated": "2026-01-31T22:55:48.691Z",
|
"generated": "2026-02-01T01:04:01.193Z",
|
||||||
"schemaRoot": "/schemas/20251121/linkml",
|
"schemaRoot": "/schemas/20251121/linkml",
|
||||||
"totalFiles": 2906,
|
"totalFiles": 2906,
|
||||||
"categoryCounts": {
|
"categoryCounts": {
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ classes:
|
||||||
\ general labeling context"
|
\ general labeling context"
|
||||||
class_uri: skos:altLabel
|
class_uri: skos:altLabel
|
||||||
exact_mappings:
|
exact_mappings:
|
||||||
|
- skos:altLabel
|
||||||
|
close_mappings:
|
||||||
- schema:alternateName
|
- schema:alternateName
|
||||||
related_mappings:
|
related_mappings:
|
||||||
- rdfs:label
|
- rdfs:label
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ classes:
|
||||||
for hearing accessibility - Subtitles for multilingual content - Closed captions
|
for hearing accessibility - Subtitles for multilingual content - Closed captions
|
||||||
vs. open captions distinction MIGRATED 2026-01-22: Created per slot_fixes.yaml
|
vs. open captions distinction MIGRATED 2026-01-22: Created per slot_fixes.yaml
|
||||||
feedback to replace simple caption_available string with structured class.'
|
feedback to replace simple caption_available string with structured class.'
|
||||||
exact_mappings:
|
close_mappings:
|
||||||
- schema:caption
|
- schema:caption
|
||||||
slots:
|
slots:
|
||||||
- has_or_had_label
|
- has_or_had_label
|
||||||
|
|
|
||||||
|
|
@ -53,11 +53,10 @@ classes:
|
||||||
- \"Art + Culture Center\" \u2192 \"ACC\" (not \"A+CC\")\n- \"Museum/Gallery Amsterdam\" \u2192 \"MGA\" (not \"M/GA\")\n- \"Heritage@Digital\" \u2192 \"HD\" (not \"H@D\")\n- \"Archives (Historical)\" \u2192 \"AH\" (not \"A(H)\")\n\nSee: rules/ABBREVIATION_SPECIAL_CHAR_RULE.md for complete documentation\n\n===========================================================================\nMANDATORY RULE: Diacritics MUST Be Normalized to ASCII in Abbreviations\n===========================================================================\n\nWhen generating abbreviations for GHCID, diacritics (accented characters)\nMUST be normalized to their ASCII base letter equivalents. Only ASCII\nuppercase letters (A-Z) are permitted in the has_or_had_abbreviation component.\n\nRATIONALE:\n1. URI/URL safety - Non-ASCII requires percent-encoding\n2. Cross-system compatibility - ASCII is universally supported\n3. Parsing consistency - No special character handling needed\n4. Human readability - Easier to type\
|
- \"Art + Culture Center\" \u2192 \"ACC\" (not \"A+CC\")\n- \"Museum/Gallery Amsterdam\" \u2192 \"MGA\" (not \"M/GA\")\n- \"Heritage@Digital\" \u2192 \"HD\" (not \"H@D\")\n- \"Archives (Historical)\" \u2192 \"AH\" (not \"A(H)\")\n\nSee: rules/ABBREVIATION_SPECIAL_CHAR_RULE.md for complete documentation\n\n===========================================================================\nMANDATORY RULE: Diacritics MUST Be Normalized to ASCII in Abbreviations\n===========================================================================\n\nWhen generating abbreviations for GHCID, diacritics (accented characters)\nMUST be normalized to their ASCII base letter equivalents. Only ASCII\nuppercase letters (A-Z) are permitted in the has_or_had_abbreviation component.\n\nRATIONALE:\n1. URI/URL safety - Non-ASCII requires percent-encoding\n2. Cross-system compatibility - ASCII is universally supported\n3. Parsing consistency - No special character handling needed\n4. Human readability - Easier to type\
|
||||||
\ and communicate\n\nDIACRITICS TO NORMALIZE (examples by language):\n- Czech: \u010C\u2192C, \u0158\u2192R, \u0160\u2192S, \u017D\u2192Z, \u011A\u2192E, \u016E\u2192U\n- Polish: \u0141\u2192L, \u0143\u2192N, \xD3\u2192O, \u015A\u2192S, \u0179\u2192Z, \u017B\u2192Z, \u0104\u2192A, \u0118\u2192E\n- German: \xC4\u2192A, \xD6\u2192O, \xDC\u2192U, \xDF\u2192SS\n- French: \xC9\u2192E, \xC8\u2192E, \xCA\u2192E, \xC7\u2192C, \xD4\u2192O\n- Spanish: \xD1\u2192N, \xC1\u2192A, \xC9\u2192E, \xCD\u2192I, \xD3\u2192O, \xDA\u2192U\n- Nordic: \xC5\u2192A, \xC4\u2192A, \xD6\u2192O, \xD8\u2192O, \xC6\u2192AE\n\nEXAMPLES:\n- \"Vlastiv\u011Bdn\xE9 muzeum\" (Czech) \u2192 \"VM\" (not \"VM\" with h\xE1\u010Dek)\n- \"\xD6sterreichische Nationalbibliothek\" (German) \u2192 \"ON\"\n- \"Biblioth\xE8que nationale\" (French) \u2192 \"BN\"\n\nREAL-WORLD EXAMPLE:\n- \u274C WRONG: CZ-VY-TEL-L-VHSPAO\u010CRZS (contains \u010C)\n- \u2705 CORRECT: CZ-VY-TEL-L-VHSPAOCRZS (ASCII only)\n\nIMPLEMENTATION:\n```python\n\
|
\ and communicate\n\nDIACRITICS TO NORMALIZE (examples by language):\n- Czech: \u010C\u2192C, \u0158\u2192R, \u0160\u2192S, \u017D\u2192Z, \u011A\u2192E, \u016E\u2192U\n- Polish: \u0141\u2192L, \u0143\u2192N, \xD3\u2192O, \u015A\u2192S, \u0179\u2192Z, \u017B\u2192Z, \u0104\u2192A, \u0118\u2192E\n- German: \xC4\u2192A, \xD6\u2192O, \xDC\u2192U, \xDF\u2192SS\n- French: \xC9\u2192E, \xC8\u2192E, \xCA\u2192E, \xC7\u2192C, \xD4\u2192O\n- Spanish: \xD1\u2192N, \xC1\u2192A, \xC9\u2192E, \xCD\u2192I, \xD3\u2192O, \xDA\u2192U\n- Nordic: \xC5\u2192A, \xC4\u2192A, \xD6\u2192O, \xD8\u2192O, \xC6\u2192AE\n\nEXAMPLES:\n- \"Vlastiv\u011Bdn\xE9 muzeum\" (Czech) \u2192 \"VM\" (not \"VM\" with h\xE1\u010Dek)\n- \"\xD6sterreichische Nationalbibliothek\" (German) \u2192 \"ON\"\n- \"Biblioth\xE8que nationale\" (French) \u2192 \"BN\"\n\nREAL-WORLD EXAMPLE:\n- \u274C WRONG: CZ-VY-TEL-L-VHSPAO\u010CRZS (contains \u010C)\n- \u2705 CORRECT: CZ-VY-TEL-L-VHSPAOCRZS (ASCII only)\n\nIMPLEMENTATION:\n```python\n\
|
||||||
import unicodedata\nnormalized = unicodedata.normalize('NFD', text)\nascii_text = ''.join(c for c in normalized if unicodedata.category(c) != 'Mn')\n```\n\nSee: rules/ABBREVIATION_SPECIAL_CHAR_RULE.md for complete documentation\n\nCan be generated by:\n1. ReconstructionActivity (formal entity resolution) - is_or_was_generated_by link\n2. Direct extraction (simple standardization) - no is_or_was_generated_by link\n"
|
import unicodedata\nnormalized = unicodedata.normalize('NFD', text)\nascii_text = ''.join(c for c in normalized if unicodedata.category(c) != 'Mn')\n```\n\nSee: rules/ABBREVIATION_SPECIAL_CHAR_RULE.md for complete documentation\n\nCan be generated by:\n1. ReconstructionActivity (formal entity resolution) - is_or_was_generated_by link\n2. Direct extraction (simple standardization) - no is_or_was_generated_by link\n"
|
||||||
exact_mappings:
|
close_mappings:
|
||||||
- skos:prefLabel
|
- skos:prefLabel
|
||||||
- schema:name
|
- schema:name
|
||||||
- foaf:name
|
- foaf:name
|
||||||
close_mappings:
|
|
||||||
- rdfs:label
|
- rdfs:label
|
||||||
- dcterms:title
|
- dcterms:title
|
||||||
- org:legalName
|
- org:legalName
|
||||||
|
|
|
||||||
|
|
@ -58,10 +58,8 @@ classes:
|
||||||
- `unit_description` (string)
|
- `unit_description` (string)
|
||||||
- `type_description` (string)
|
- `type_description` (string)
|
||||||
|
|
||||||
exact_mappings:
|
|
||||||
- dcterms:description
|
|
||||||
|
|
||||||
close_mappings:
|
close_mappings:
|
||||||
|
- dcterms:description
|
||||||
- skos:definition
|
- skos:definition
|
||||||
- rdfs:comment
|
- rdfs:comment
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,8 +103,8 @@ classes:
|
||||||
, \"JavaScript\"]\n```\n"
|
, \"JavaScript\"]\n```\n"
|
||||||
exact_mappings:
|
exact_mappings:
|
||||||
- schema:WebSite
|
- schema:WebSite
|
||||||
- foaf:homepage
|
|
||||||
close_mappings:
|
close_mappings:
|
||||||
|
- foaf:homepage
|
||||||
- schema:WebApplication
|
- schema:WebApplication
|
||||||
- dcat:Catalog
|
- dcat:Catalog
|
||||||
- dcat:DataService
|
- dcat:DataService
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,8 @@ classes:
|
||||||
- value → identifier_value
|
- value → identifier_value
|
||||||
exact_mappings:
|
exact_mappings:
|
||||||
- schema:PropertyValue
|
- schema:PropertyValue
|
||||||
- dcterms:identifier
|
|
||||||
close_mappings:
|
close_mappings:
|
||||||
|
- dcterms:identifier
|
||||||
- adms:Identifier
|
- adms:Identifier
|
||||||
- skos:notation
|
- skos:notation
|
||||||
slots:
|
slots:
|
||||||
|
|
|
||||||
|
|
@ -60,10 +60,8 @@ classes:
|
||||||
- `feature_note` (string) → has_or_had_note with Note class
|
- `feature_note` (string) → has_or_had_note with Note class
|
||||||
- Other *_note slots per slot_fixes.yaml
|
- Other *_note slots per slot_fixes.yaml
|
||||||
|
|
||||||
exact_mappings:
|
|
||||||
- skos:note
|
|
||||||
|
|
||||||
close_mappings:
|
close_mappings:
|
||||||
|
- skos:note
|
||||||
- rdfs:comment
|
- rdfs:comment
|
||||||
- dcterms:description
|
- dcterms:description
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,7 @@ classes:
|
||||||
description: Institutional scope type instance
|
description: Institutional scope type instance
|
||||||
broad_mappings:
|
broad_mappings:
|
||||||
- skos:Concept
|
- skos:Concept
|
||||||
CollectionScope:
|
CollectionScopeType:
|
||||||
is_a: ScopeType
|
is_a: ScopeType
|
||||||
class_uri: schema:Collection
|
class_uri: schema:Collection
|
||||||
description: 'Collection-based scope dimension covering collection types and sizes.
|
description: 'Collection-based scope dimension covering collection types and sizes.
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ imports:
|
||||||
- ./TemplateSpecificityType
|
- ./TemplateSpecificityType
|
||||||
- ./TemplateSpecificityTypes
|
- ./TemplateSpecificityTypes
|
||||||
classes:
|
classes:
|
||||||
VideoPost:
|
VideoPostType:
|
||||||
is_a: SocialMediaPostType
|
is_a: SocialMediaPostType
|
||||||
class_uri: as:Video
|
class_uri: as:Video
|
||||||
description: "Standard video content with no strict duration limit.\n\n**Activity\
|
description: "Standard video content with no strict duration limit.\n\n**Activity\
|
||||||
|
|
@ -35,18 +35,18 @@ classes:
|
||||||
\n**Platforms**:\n- YouTube (primary)\n- Vimeo\n- Facebook Video\n- LinkedIn\
|
\n**Platforms**:\n- YouTube (primary)\n- Vimeo\n- Facebook Video\n- LinkedIn\
|
||||||
\ Video\n- X/Twitter Video\n\n**Duration Characteristics**:\n- YouTube: Up to\
|
\ Video\n- X/Twitter Video\n\n**Duration Characteristics**:\n- YouTube: Up to\
|
||||||
\ 12 hours (for verified accounts)\n- Vimeo: Varies by plan (500MB-unlimited)\n\
|
\ 12 hours (for verified accounts)\n- Vimeo: Varies by plan (500MB-unlimited)\n\
|
||||||
- Facebook: Up to 4 hours\n- LinkedIn: Up to 10 minutes\n\n**Heritage Use Cases**:\n\
|
\ - Facebook: Up to 4 hours\n- LinkedIn: Up to 10 minutes\n\n**Heritage Use Cases**:\n\
|
||||||
\n| Use Case | Description | Typical Duration |\n|----------|-------------|------------------|\n\
|
\ \n| Use Case | Description | Typical Duration |\n|----------|-------------|------------------|\n\
|
||||||
| Virtual tours | 360\xB0 or guided exhibition walkthroughs | 10-30 min |\n\
|
\ | Virtual tours | 360\xB0 or guided exhibition walkthroughs | 10-30 min |\n\
|
||||||
| Conservation | Restoration process documentation | 5-20 min |\n| Interviews\
|
\ | Conservation | Restoration process documentation | 5-20 min |\n| Interviews\
|
||||||
\ | Curator, artist, or expert conversations | 15-60 min |\n| Lectures | Educational\
|
\ \ | Curator, artist, or expert conversations | 15-60 min |\n| Lectures | Educational\
|
||||||
\ presentations | 30-90 min |\n| Documentaries | In-depth collection or history\
|
\ \ presentations | 30-90 min |\n| Documentaries | In-depth collection or history\
|
||||||
\ stories | 20-60 min |\n| Exhibition intro | Preview of new exhibitions | 2-5\
|
\ \ stories | 20-60 min |\n| Exhibition intro | Preview of new exhibitions | 2-5\
|
||||||
\ min |\n\n**Technical Properties**:\n- Resolution: Up to 8K on YouTube\n- Formats:\
|
\ \ min |\n\n**Technical Properties**:\n- Resolution: Up to 8K on YouTube\n- Formats:\
|
||||||
\ MP4 (H.264), WebM, MOV\n- Captions: VTT, SRT supported\n- Chapters: Timestamp-based\
|
\ \ MP4 (H.264), WebM, MOV\n- Captions: VTT, SRT supported\n- Chapters: Timestamp-based\
|
||||||
\ navigation\n\n**Metadata Captured**:\n- Duration (ISO 8601)\n- Definition\
|
\ \ navigation\n\n**Metadata Captured**:\n- Duration (ISO 8601)\n- Definition\
|
||||||
\ (SD, HD, 4K, 8K)\n- Caption availability\n- View/like/comment counts\n- Tags\
|
\ \ (SD, HD, 4K, 8K)\n- Caption availability\n- View/like/comment counts\n- Tags\
|
||||||
\ and categories\n"
|
\ \ and categories\n"
|
||||||
exact_mappings:
|
exact_mappings:
|
||||||
- as:Video
|
- as:Video
|
||||||
- schema:VideoObject
|
- schema:VideoObject
|
||||||
|
|
@ -85,12 +85,13 @@ classes:
|
||||||
custodian_types: '[''*'']'
|
custodian_types: '[''*'']'
|
||||||
broad_mappings:
|
broad_mappings:
|
||||||
- skos:Concept
|
- skos:Concept
|
||||||
ShortVideoPost:
|
ShortVideoPostType:
|
||||||
is_a: SocialMediaPostType
|
is_a: SocialMediaPostType
|
||||||
class_uri: hc:ShortVideo
|
class_uri: hc:ShortVideo
|
||||||
description: 'Short-form video content optimized for mobile viewing and discovery.
|
description: 'Short-form video content optimized for mobile viewing and discovery.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Activity Streams Mapping**: `as:Video` (with duration constraint)
|
**Activity Streams Mapping**: `as:Video` (with duration constraint)
|
||||||
|
|
||||||
**Schema.org Mapping**: `schema:VideoObject`
|
**Schema.org Mapping**: `schema:VideoObject`
|
||||||
|
|
@ -192,7 +193,7 @@ classes:
|
||||||
- has_or_had_score
|
- has_or_had_score
|
||||||
broad_mappings:
|
broad_mappings:
|
||||||
- skos:Concept
|
- skos:Concept
|
||||||
ImagePost:
|
ImagePostType:
|
||||||
is_a: SocialMediaPostType
|
is_a: SocialMediaPostType
|
||||||
class_uri: as:Image
|
class_uri: as:Image
|
||||||
description: 'Static image content including photographs, graphics, and artwork
|
description: 'Static image content including photographs, graphics, and artwork
|
||||||
|
|
@ -307,7 +308,7 @@ classes:
|
||||||
- has_or_had_score
|
- has_or_had_score
|
||||||
broad_mappings:
|
broad_mappings:
|
||||||
- skos:Concept
|
- skos:Concept
|
||||||
TextPost:
|
TextPostType:
|
||||||
is_a: SocialMediaPostType
|
is_a: SocialMediaPostType
|
||||||
class_uri: as:Note
|
class_uri: as:Note
|
||||||
description: 'Text-based social media posts, typically short-form.
|
description: 'Text-based social media posts, typically short-form.
|
||||||
|
|
@ -401,7 +402,7 @@ classes:
|
||||||
- has_or_had_score
|
- has_or_had_score
|
||||||
broad_mappings:
|
broad_mappings:
|
||||||
- skos:Concept
|
- skos:Concept
|
||||||
StoryPost:
|
StoryPostType:
|
||||||
is_a: SocialMediaPostType
|
is_a: SocialMediaPostType
|
||||||
class_uri: hc:Story
|
class_uri: hc:Story
|
||||||
description: 'Ephemeral content that auto-deletes after 24 hours (typically).
|
description: 'Ephemeral content that auto-deletes after 24 hours (typically).
|
||||||
|
|
@ -498,7 +499,7 @@ classes:
|
||||||
- has_or_had_score
|
- has_or_had_score
|
||||||
broad_mappings:
|
broad_mappings:
|
||||||
- skos:Concept
|
- skos:Concept
|
||||||
LiveStreamPost:
|
LiveStreamPostType:
|
||||||
is_a: SocialMediaPostType
|
is_a: SocialMediaPostType
|
||||||
class_uri: hc:LiveStream
|
class_uri: hc:LiveStream
|
||||||
description: 'Real-time video broadcasting with audience interaction.
|
description: 'Real-time video broadcasting with audience interaction.
|
||||||
|
|
@ -598,7 +599,7 @@ classes:
|
||||||
- has_or_had_score
|
- has_or_had_score
|
||||||
broad_mappings:
|
broad_mappings:
|
||||||
- skos:Concept
|
- skos:Concept
|
||||||
AudioPost:
|
AudioPostType:
|
||||||
is_a: SocialMediaPostType
|
is_a: SocialMediaPostType
|
||||||
class_uri: as:Audio
|
class_uri: as:Audio
|
||||||
description: 'Audio-only content including podcasts, music, and audio guides.
|
description: 'Audio-only content including podcasts, music, and audio guides.
|
||||||
|
|
@ -709,7 +710,7 @@ classes:
|
||||||
- has_or_had_score
|
- has_or_had_score
|
||||||
broad_mappings:
|
broad_mappings:
|
||||||
- skos:Concept
|
- skos:Concept
|
||||||
ArticlePost:
|
ArticlePostType:
|
||||||
is_a: SocialMediaPostType
|
is_a: SocialMediaPostType
|
||||||
class_uri: as:Article
|
class_uri: as:Article
|
||||||
description: 'Long-form written content including blog posts and newsletters.
|
description: 'Long-form written content including blog posts and newsletters.
|
||||||
|
|
@ -815,7 +816,7 @@ classes:
|
||||||
- has_or_had_score
|
- has_or_had_score
|
||||||
broad_mappings:
|
broad_mappings:
|
||||||
- skos:Concept
|
- skos:Concept
|
||||||
ThreadPost:
|
ThreadPostType:
|
||||||
is_a: SocialMediaPostType
|
is_a: SocialMediaPostType
|
||||||
class_uri: hc:Thread
|
class_uri: hc:Thread
|
||||||
description: 'Multi-post sequences forming a connected narrative.
|
description: 'Multi-post sequences forming a connected narrative.
|
||||||
|
|
@ -909,7 +910,7 @@ classes:
|
||||||
- has_or_had_score
|
- has_or_had_score
|
||||||
broad_mappings:
|
broad_mappings:
|
||||||
- skos:Concept
|
- skos:Concept
|
||||||
CarouselPost:
|
CarouselPostType:
|
||||||
is_a: SocialMediaPostType
|
is_a: SocialMediaPostType
|
||||||
class_uri: hc:Carousel
|
class_uri: hc:Carousel
|
||||||
description: 'Multi-image or multi-video posts in a swipeable format.
|
description: 'Multi-image or multi-video posts in a swipeable format.
|
||||||
|
|
@ -1008,7 +1009,7 @@ classes:
|
||||||
- has_or_had_score
|
- has_or_had_score
|
||||||
broad_mappings:
|
broad_mappings:
|
||||||
- skos:Concept
|
- skos:Concept
|
||||||
OtherPost:
|
OtherPostType:
|
||||||
is_a: SocialMediaPostType
|
is_a: SocialMediaPostType
|
||||||
class_uri: as:Object
|
class_uri: as:Object
|
||||||
description: "Fallback type for emerging or uncategorized content formats.\n\n\
|
description: "Fallback type for emerging or uncategorized content formats.\n\n\
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ classes:
|
||||||
description: A source from which something was derived or generated. Can represent manual creation, automated generation, external services, or imported data. Subclasses may specialize for specific domains.
|
description: A source from which something was derived or generated. Can represent manual creation, automated generation, external services, or imported data. Subclasses may specialize for specific domains.
|
||||||
exact_mappings:
|
exact_mappings:
|
||||||
- prov:Entity
|
- prov:Entity
|
||||||
- dcterms:source
|
|
||||||
close_mappings:
|
close_mappings:
|
||||||
|
- dcterms:source
|
||||||
- schema:CreativeWork
|
- schema:CreativeWork
|
||||||
slots:
|
slots:
|
||||||
- has_or_had_type
|
- has_or_had_type
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,9 @@ classes:
|
||||||
**Migration Note**: Created 2026-01-19 per slot_fixes.yaml (Rule 53).
|
**Migration Note**: Created 2026-01-19 per slot_fixes.yaml (Rule 53).
|
||||||
Replaces simple string cms_product_version with structured Version class.
|
Replaces simple string cms_product_version with structured Version class.
|
||||||
exact_mappings:
|
exact_mappings:
|
||||||
- schema:version
|
|
||||||
- doap:Version
|
- doap:Version
|
||||||
|
close_mappings:
|
||||||
|
- schema:version
|
||||||
slots:
|
slots:
|
||||||
- temporal_extent
|
- temporal_extent
|
||||||
slot_usage:
|
slot_usage:
|
||||||
|
|
|
||||||
|
|
@ -59,9 +59,8 @@ classes:
|
||||||
\ formats (closed caption, subtitles etc.)\n> use the MediaObject.encodingFormat property.\"\n\n**SUBTITLE vs CAPTION vs TRANSCRIPT**:\n\n| Type | Time-coded | Purpose | Audience |\n|------|------------|---------|----------|\n| Transcript | Optional | Reading, search | Everyone |\n| Subtitle | Required | Language translation | Hearing viewers |\n| Caption (CC) | Required | Accessibility | Deaf/HoH viewers |\n| SDH | Required | Full accessibility | Deaf viewers, noisy environments |\n\n**SDH (Subtitles for Deaf/Hard-of-Hearing)**:\n\nSDH differs from regular subtitles by including:\n- Speaker identification: \"(John) Hello\"\n- Sound effects: \"[door slams]\", \"[music playing]\"\n- Music descriptions: \"\u266A upbeat jazz \u266A\"\n- Emotional cues: \"[laughing]\", \"[whispering]\"\n\n**SUBTITLE FORMATS**:\n\n| Format | Extension | Features | Use Case |\n|--------|-----------|----------|----------|\n| SRT | .srt | Simple, universal | Most video players |\n| VTT | .vtt | W3C standard,\
|
\ formats (closed caption, subtitles etc.)\n> use the MediaObject.encodingFormat property.\"\n\n**SUBTITLE vs CAPTION vs TRANSCRIPT**:\n\n| Type | Time-coded | Purpose | Audience |\n|------|------------|---------|----------|\n| Transcript | Optional | Reading, search | Everyone |\n| Subtitle | Required | Language translation | Hearing viewers |\n| Caption (CC) | Required | Accessibility | Deaf/HoH viewers |\n| SDH | Required | Full accessibility | Deaf viewers, noisy environments |\n\n**SDH (Subtitles for Deaf/Hard-of-Hearing)**:\n\nSDH differs from regular subtitles by including:\n- Speaker identification: \"(John) Hello\"\n- Sound effects: \"[door slams]\", \"[music playing]\"\n- Music descriptions: \"\u266A upbeat jazz \u266A\"\n- Emotional cues: \"[laughing]\", \"[whispering]\"\n\n**SUBTITLE FORMATS**:\n\n| Format | Extension | Features | Use Case |\n|--------|-----------|----------|----------|\n| SRT | .srt | Simple, universal | Most video players |\n| VTT | .vtt | W3C standard,\
|
||||||
\ styling | HTML5 video, web |\n| TTML | .ttml/.dfxp | XML, rich styling | Broadcast, streaming |\n| SBV | .sbv | YouTube native | YouTube uploads |\n| ASS | .ass | Advanced styling | Anime, complex layouts |\n\n**SRT FORMAT EXAMPLE**:\n\n```\n1\n00:00:00,000 --> 00:00:03,500\nWelcome to the Rijksmuseum.\n\n2\n00:00:03,500 --> 00:00:08,200\nToday we'll explore the Night Watch gallery.\n```\n\n**VTT FORMAT EXAMPLE**:\n\n```\nWEBVTT\n\n00:00:00.000 --> 00:00:03.500\nWelcome to the Rijksmuseum.\n\n00:00:03.500 --> 00:00:08.200\nToday we'll explore the Night Watch gallery.\n```\n\n**HERITAGE INSTITUTION CONTEXT**:\n\nSubtitles are critical for heritage video accessibility:\n\n1. **Accessibility Compliance**: WCAG 2.1, Section 508\n2. **Multilingual Access**: Translate for international audiences\n3. **Silent Viewing**: Social media, public displays, quiet spaces\n4. **Search Discovery**: Subtitle text is indexed by platforms\n5. **Preservation**: Text outlasts video format obsolescence\n\
|
\ styling | HTML5 video, web |\n| TTML | .ttml/.dfxp | XML, rich styling | Broadcast, streaming |\n| SBV | .sbv | YouTube native | YouTube uploads |\n| ASS | .ass | Advanced styling | Anime, complex layouts |\n\n**SRT FORMAT EXAMPLE**:\n\n```\n1\n00:00:00,000 --> 00:00:03,500\nWelcome to the Rijksmuseum.\n\n2\n00:00:03,500 --> 00:00:08,200\nToday we'll explore the Night Watch gallery.\n```\n\n**VTT FORMAT EXAMPLE**:\n\n```\nWEBVTT\n\n00:00:00.000 --> 00:00:03.500\nWelcome to the Rijksmuseum.\n\n00:00:03.500 --> 00:00:08.200\nToday we'll explore the Night Watch gallery.\n```\n\n**HERITAGE INSTITUTION CONTEXT**:\n\nSubtitles are critical for heritage video accessibility:\n\n1. **Accessibility Compliance**: WCAG 2.1, Section 508\n2. **Multilingual Access**: Translate for international audiences\n3. **Silent Viewing**: Social media, public displays, quiet spaces\n4. **Search Discovery**: Subtitle text is indexed by platforms\n5. **Preservation**: Text outlasts video format obsolescence\n\
|
||||||
\n**YOUTUBE API INTEGRATION**:\n\nSubtitle tracks from YouTube API populate:\n- `has_or_had_format`: Typically VTT or SRT\n- `generation_method`: PLATFORM_PROVIDED or ASR_AUTOMATIC\n- `content_language`: From track language code\n- `is_or_was_created_through`: YouTube auto-caption flag\n\n**SEGMENTS ARE REQUIRED**:\n\nUnlike VideoTranscript where segments are optional, VideoSubtitle\nREQUIRES the `segments` slot to be populated with VideoTimeSegment\nentries that include start_seconds, end_seconds, and segment_text.\n"
|
\n**YOUTUBE API INTEGRATION**:\n\nSubtitle tracks from YouTube API populate:\n- `has_or_had_format`: Typically VTT or SRT\n- `generation_method`: PLATFORM_PROVIDED or ASR_AUTOMATIC\n- `content_language`: From track language code\n- `is_or_was_created_through`: YouTube auto-caption flag\n\n**SEGMENTS ARE REQUIRED**:\n\nUnlike VideoTranscript where segments are optional, VideoSubtitle\nREQUIRES the `segments` slot to be populated with VideoTimeSegment\nentries that include start_seconds, end_seconds, and segment_text.\n"
|
||||||
exact_mappings:
|
|
||||||
- schema:caption
|
|
||||||
close_mappings:
|
close_mappings:
|
||||||
|
- schema:caption
|
||||||
- ma:CaptioningFormat
|
- ma:CaptioningFormat
|
||||||
related_mappings:
|
related_mappings:
|
||||||
- schema:transcript
|
- schema:transcript
|
||||||
|
|
|
||||||
|
|
@ -33,13 +33,12 @@ slots:
|
||||||
'
|
'
|
||||||
range: string
|
range: string
|
||||||
multivalued: true
|
multivalued: true
|
||||||
slot_uri: dcterms:source
|
slot_uri: ore:aggregates
|
||||||
exact_mappings:
|
exact_mappings:
|
||||||
- dcterms:source
|
|
||||||
close_mappings:
|
|
||||||
- prov:wasDerivedFrom
|
|
||||||
related_mappings:
|
|
||||||
- ore:aggregates
|
- ore:aggregates
|
||||||
|
close_mappings:
|
||||||
|
- dcterms:source
|
||||||
|
- prov:wasDerivedFrom
|
||||||
annotations:
|
annotations:
|
||||||
custodian_types: '["*"]'
|
custodian_types: '["*"]'
|
||||||
custodian_types_rationale: Applicable to all heritage custodian types.
|
custodian_types_rationale: Applicable to all heritage custodian types.
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,13 @@ imports:
|
||||||
slots:
|
slots:
|
||||||
allows_or_allowed:
|
allows_or_allowed:
|
||||||
description: "Generic slot for expressing what activities, equipment, or behaviors are permitted in a heritage custodian facility (past or present).\n**SEMANTICS**:\nUses RiC-O temporal pattern (is_or_was / has_or_had / allows_or_allowed) to capture policies that may change over time. A reading room that \"allowed photography\" in 2020 may have changed policy by 2025.\n**USAGE PATTERN**:\nThe range should be a typed class representing the permitted activity: - `Laptop` - laptop use permission - `Photography` - photography permission - Future: `Food`, `Beverages`, `MobilePhone`, etc.\n**EXAMPLES**:\n```yaml ReadingRoom:\n allows_or_allowed:\n - permitted_item: Laptop\n is_permitted: true\n conditions: \"Must be silent, no external keyboards\"\n - permitted_item: Photography \n is_permitted: true\n conditions: \"Personal research use only, no flash\"\n```"
|
description: "Generic slot for expressing what activities, equipment, or behaviors are permitted in a heritage custodian facility (past or present).\n**SEMANTICS**:\nUses RiC-O temporal pattern (is_or_was / has_or_had / allows_or_allowed) to capture policies that may change over time. A reading room that \"allowed photography\" in 2020 may have changed policy by 2025.\n**USAGE PATTERN**:\nThe range should be a typed class representing the permitted activity: - `Laptop` - laptop use permission - `Photography` - photography permission - Future: `Food`, `Beverages`, `MobilePhone`, etc.\n**EXAMPLES**:\n```yaml ReadingRoom:\n allows_or_allowed:\n - permitted_item: Laptop\n is_permitted: true\n conditions: \"Must be silent, no external keyboards\"\n - permitted_item: Photography \n is_permitted: true\n conditions: \"Personal research use only, no flash\"\n```"
|
||||||
slot_uri: schema:amenityFeature
|
slot_uri: odrl:permission
|
||||||
range: uriorcurie
|
range: uriorcurie
|
||||||
multivalued: true
|
multivalued: true
|
||||||
exact_mappings:
|
exact_mappings:
|
||||||
- schema:amenityFeature
|
|
||||||
close_mappings:
|
|
||||||
- odrl:permission
|
- odrl:permission
|
||||||
|
close_mappings:
|
||||||
|
- schema:amenityFeature
|
||||||
annotations:
|
annotations:
|
||||||
custodian_types: '["*"]'
|
custodian_types: '["*"]'
|
||||||
custodian_types_rationale: All heritage custodians have visitor policies.
|
custodian_types_rationale: All heritage custodians have visitor policies.
|
||||||
|
|
|
||||||
|
|
@ -59,5 +59,5 @@ slots:
|
||||||
description: Video frame analysis at 1 fps (VideoFrame instance)
|
description: Video frame analysis at 1 fps (VideoFrame instance)
|
||||||
annotations:
|
annotations:
|
||||||
custodian_types: '["*"]'
|
custodian_types: '["*"]'
|
||||||
exact_mappings:
|
broad_mappings:
|
||||||
- schema:object
|
- schema:object
|
||||||
|
|
|
||||||
|
|
@ -30,14 +30,13 @@ slots:
|
||||||
'
|
'
|
||||||
range: string
|
range: string
|
||||||
multivalued: true
|
multivalued: true
|
||||||
slot_uri: dcterms:isPartOf
|
slot_uri: ore:isAggregatedBy
|
||||||
exact_mappings:
|
exact_mappings:
|
||||||
- dcterms:isPartOf
|
- ore:isAggregatedBy
|
||||||
close_mappings:
|
close_mappings:
|
||||||
|
- dcterms:isPartOf
|
||||||
- edm:isShownAt
|
- edm:isShownAt
|
||||||
- schema:includedInDataCatalog
|
- schema:includedInDataCatalog
|
||||||
related_mappings:
|
|
||||||
- ore:isAggregatedBy
|
|
||||||
annotations:
|
annotations:
|
||||||
custodian_types: '["*"]'
|
custodian_types: '["*"]'
|
||||||
custodian_types_rationale: Applicable to all heritage custodian types.
|
custodian_types_rationale: Applicable to all heritage custodian types.
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ slots:
|
||||||
multivalued: true
|
multivalued: true
|
||||||
inlined: true
|
inlined: true
|
||||||
inlined_as_list: true
|
inlined_as_list: true
|
||||||
exact_mappings:
|
related_mappings:
|
||||||
- as:Like
|
- as:Like
|
||||||
close_mappings:
|
close_mappings:
|
||||||
- schema:interactionStatistic
|
- schema:interactionStatistic
|
||||||
|
|
|
||||||
|
|
@ -56,12 +56,11 @@ slots:
|
||||||
description: "Maximum acceptable cumulative annual light exposure in lux-hours per year.\n\nBased on preservation standards:\n- High sensitivity (EN 16893): <15,000 lux-hours/year\n- Medium sensitivity (EN 16893): <150,000 lux-hours/year\n- Textiles (CIE 157): <12,000 lux-hours/year\n- General guidance (ASHRAE): <50,000 lux-hours/year\n\nLight damage is cumulative (reciprocity law). Annual limits mandate:\n- Rotating displays for sensitive works\n- Controlled access periods\n- Dark storage between exhibition periods\n\nExample: 50 lux \xD7 8 hours/day \xD7 250 days = 100,000 lux-hours (too high!)\n"
|
description: "Maximum acceptable cumulative annual light exposure in lux-hours per year.\n\nBased on preservation standards:\n- High sensitivity (EN 16893): <15,000 lux-hours/year\n- Medium sensitivity (EN 16893): <150,000 lux-hours/year\n- Textiles (CIE 157): <12,000 lux-hours/year\n- General guidance (ASHRAE): <50,000 lux-hours/year\n\nLight damage is cumulative (reciprocity law). Annual limits mandate:\n- Rotating displays for sensitive works\n- Controlled access periods\n- Dark storage between exhibition periods\n\nExample: 50 lux \xD7 8 hours/day \xD7 250 days = 100,000 lux-hours (too high!)\n"
|
||||||
range: float
|
range: float
|
||||||
slot_uri: hc:maxAnnualLightExposure
|
slot_uri: hc:maxAnnualLightExposure
|
||||||
exact_mappings:
|
|
||||||
- quantitykind:LuminousExposure
|
|
||||||
close_mappings:
|
close_mappings:
|
||||||
- sosa:ObservableProperty
|
- sosa:ObservableProperty
|
||||||
- crm:E54_Dimension
|
- crm:E54_Dimension
|
||||||
related_mappings:
|
related_mappings:
|
||||||
|
- quantitykind:LuminousExposure
|
||||||
- wd:Q194411
|
- wd:Q194411
|
||||||
- schema:maxValue
|
- schema:maxValue
|
||||||
minimum_value: 0.0
|
minimum_value: 0.0
|
||||||
|
|
|
||||||
|
|
@ -28,13 +28,12 @@ slots:
|
||||||
description: "Maximum acceptable light level in lux (lumens per square meter).\n\nBased on ISO/EN preservation standards:\n- Archives (ISO 11799): <50 lux for paper/parchment\n- High sensitivity (EN 16893): <50 lux (textiles, watercolors, photos)\n- Medium sensitivity (EN 16893): <200 lux (oil paintings, leather)\n- Low sensitivity (EN 16893): <300 lux (ceramics, stone, metals)\n- UK Storage (BS 4971): 0 lux for closed storage\n\nLight damage is cumulative and irreversible. Damage follows the\nreciprocity law: 50 lux \xD7 8 hours = 400 lux \xD7 1 hour (same damage).\n"
|
description: "Maximum acceptable light level in lux (lumens per square meter).\n\nBased on ISO/EN preservation standards:\n- Archives (ISO 11799): <50 lux for paper/parchment\n- High sensitivity (EN 16893): <50 lux (textiles, watercolors, photos)\n- Medium sensitivity (EN 16893): <200 lux (oil paintings, leather)\n- Low sensitivity (EN 16893): <300 lux (ceramics, stone, metals)\n- UK Storage (BS 4971): 0 lux for closed storage\n\nLight damage is cumulative and irreversible. Damage follows the\nreciprocity law: 50 lux \xD7 8 hours = 400 lux \xD7 1 hour (same damage).\n"
|
||||||
range: float
|
range: float
|
||||||
slot_uri: hc:maxLightLux
|
slot_uri: hc:maxLightLux
|
||||||
exact_mappings:
|
|
||||||
- quantitykind:Illuminance
|
|
||||||
close_mappings:
|
close_mappings:
|
||||||
- sosa:ObservableProperty
|
- sosa:ObservableProperty
|
||||||
- crm:E54_Dimension
|
- crm:E54_Dimension
|
||||||
- brick:Illuminance_Sensor
|
- brick:Illuminance_Sensor
|
||||||
related_mappings:
|
related_mappings:
|
||||||
|
- quantitykind:Illuminance
|
||||||
- wd:Q194411
|
- wd:Q194411
|
||||||
- schema:maxValue
|
- schema:maxValue
|
||||||
minimum_value: 0.0
|
minimum_value: 0.0
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue