@prefix dct: <http://purl.org/dc/terms/> .
@prefix ga: <https://ekgf.org/ontology/grapharch#> .
@prefix artgov: <https://ekgf.org/ontology/artifact-governance#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

ga:ProjectShape a sh:NodeShape ; sh:targetClass ga:Project ; sh:nodeKind sh:IRI ;
    sh:property [ sh:path ga:scope ; sh:nodeKind sh:IRI ; sh:class ga:Scope ] ;
    sh:property [ sh:path ga:target ; sh:nodeKind sh:IRI ; sh:class ga:Target ] ;
    sh:property [ sh:path ga:collector ; sh:nodeKind sh:IRI ; sh:class ga:Collector ] .

ga:CollectorShape a sh:NodeShape ; sh:targetClass ga:Collector ; sh:nodeKind sh:IRI ;
    sh:property [ sh:path ga:kind ; sh:nodeKind sh:Literal ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:source ; sh:nodeKind sh:Literal ; sh:minCount 1 ; sh:maxCount 1 ] .

ga:ScopeShape a sh:NodeShape ; sh:targetClass ga:Scope ; sh:nodeKind sh:IRI ;
    sh:property [ sh:path ga:include ; sh:nodeKind sh:IRI ] ;
    sh:property [ sh:path ga:exclude ; sh:nodeKind sh:IRI ] ;
    sh:property [ sh:path ga:compose ; sh:nodeKind sh:IRI ; sh:class ga:Scope ] ;
    sh:property [ sh:path ga:traverse ; sh:nodeKind sh:IRI ] ;
    sh:property [ sh:path ga:maxDepth ; sh:maxCount 1 ; sh:datatype xsd:integer ; sh:minInclusive 0 ; sh:maxInclusive 4294967295 ] ;
    sh:or ( [ sh:property [ sh:path ga:traverse ; sh:maxCount 0 ] ] [ sh:property [ sh:path ga:maxDepth ; sh:minCount 1 ] ] ) .

ga:TargetShape a sh:NodeShape ; sh:targetClass ga:Target ; sh:nodeKind sh:IRI ;
    sh:property [ sh:path ga:scope ; sh:nodeKind sh:IRI ; sh:class ga:Scope ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:profile ; sh:nodeKind sh:IRI ; sh:class ga:Profile ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:renderer ; sh:nodeKind sh:Literal ; sh:minCount 1 ; sh:maxCount 1 ; sh:in ("html" "website" "specification" "specification-pages" "bookshelf" "typst") ] ;
    sh:property [ sh:path ga:destination ; sh:nodeKind sh:Literal ; sh:minLength 1 ; sh:minCount 1 ; sh:maxCount 1 ] .

ga:ProfileShape a sh:NodeShape ; sh:targetClass ga:Profile ; sh:nodeKind sh:IRI ;
    sh:property [ sh:path ga:placement ; sh:nodeKind sh:IRI ; sh:class ga:Placement ] .

ga:PlacementShape a sh:NodeShape ; sh:targetClass ga:Placement ; sh:nodeKind sh:IRI ;
    sh:property [sh:path ga:parentPlacement; sh:nodeKind sh:IRI; sh:class ga:Placement; sh:maxCount 1] ;
    sh:property [ sh:path ga:component ; sh:nodeKind sh:IRI ; sh:class ga:Component ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:order ; sh:nodeKind sh:Literal ; sh:datatype xsd:integer ; sh:minInclusive 0 ; sh:maxInclusive 4294967295 ; sh:minCount 1 ; sh:maxCount 1 ] .

ga:ComponentShape a sh:NodeShape ; sh:targetClass ga:Component ; sh:nodeKind sh:IRI ;
    sh:property [ sh:path ga:fragment ; sh:nodeKind sh:IRI ; sh:class ga:Fragment ] .

ga:FragmentShape a sh:NodeShape ; sh:targetClass ga:Fragment ; sh:nodeKind sh:IRI ;
    sh:property [ sh:path ga:headingDepth ; sh:datatype xsd:integer ; sh:minInclusive 1 ; sh:maxInclusive 4 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:order ; sh:datatype xsd:integer ; sh:minInclusive 0 ; sh:maxInclusive 4294967295 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:subject ; sh:nodeKind sh:IRI ; sh:minCount 1 ] ;
    sh:property [ sh:path ga:body ; sh:nodeKind sh:Literal ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:format ; sh:nodeKind sh:Literal ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:contribution ; sh:nodeKind sh:IRI ; sh:class ga:Contribution ; sh:minCount 1 ; sh:maxCount 1 ] .

ga:ContributionShape a sh:NodeShape ; sh:targetClass ga:Contribution ; sh:nodeKind sh:IRI ;
    sh:property [ sh:path ga:processor ; sh:nodeKind sh:IRI ; sh:or ( [ sh:class ga:Collector ] [ sh:class ga:Documentor ] [ sh:class ga:Processor ] ) ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:project ; sh:nodeKind sh:IRI ; sh:class ga:Project ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:source ; sh:nodeKind sh:Literal ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:revision ; sh:nodeKind sh:Literal ; sh:minCount 1 ; sh:maxCount 1 ] .


# Conditional specification requirements. Runtime rendering additionally checks
# HTTP(S) schemes, calendar dates, front-matter placement, and metadata budgets.
ga:SpecificationTargetShape a sh:NodeShape ; sh:targetClass ga:Target ;
    sh:or (
        [ sh:not [ sh:property [ sh:path ga:renderer ; sh:in ("specification" "specification-pages" "bookshelf") ] ] ]
        [ sh:node ga:SpecificationMetadataShape ]
    ) .

ga:SpecificationMetadataShape a sh:NodeShape ;
    sh:property [ sh:path <http://purl.org/dc/terms/title> ; sh:nodeKind sh:Literal ; sh:minLength 1 ; sh:maxLength 4096 ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:publisher ; sh:nodeKind sh:IRI ; sh:or ( [ sh:class ga:Authority ] [ sh:class artgov:Authority ] ) ; sh:node ga:AuthorityShape ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:publicationStatus ; sh:nodeKind sh:Literal ; sh:minLength 1 ; sh:maxLength 4096 ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:publicationDate ; sh:datatype xsd:date ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:thisVersion ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:latestVersion ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:previousVersion ; sh:nodeKind sh:IRI ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:editorDraft ; sh:nodeKind sh:IRI ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:editor ; sh:nodeKind sh:IRI ; sh:node ga:SpecificationIdentityShape ; sh:maxCount 64 ] ;
    sh:property [ sh:path ga:author ; sh:nodeKind sh:IRI ; sh:node ga:SpecificationIdentityShape ; sh:maxCount 64 ] ;
    sh:property [ sh:path ga:formerEditor ; sh:nodeKind sh:IRI ; sh:node ga:SpecificationIdentityShape ; sh:maxCount 64 ] ;
    sh:property [ sh:path ga:license ; sh:nodeKind sh:IRI ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:copyright ; sh:nodeKind sh:Literal ; sh:minLength 1 ; sh:maxLength 4096 ; sh:maxCount 1 ] .

ga:SpecificationIdentityShape a sh:NodeShape ;
    sh:property [ sh:path <http://purl.org/dc/terms/title> ; sh:nodeKind sh:Literal ; sh:minLength 1 ; sh:maxLength 4096 ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:url ; sh:nodeKind sh:Literal ; sh:minLength 1 ; sh:maxLength 4096 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:affiliation ; sh:nodeKind sh:Literal ; sh:minLength 1 ; sh:maxLength 4096 ; sh:maxCount 1 ] .

ga:AuthorityShape a sh:NodeShape ; sh:targetClass ga:Authority, artgov:Authority ;
    sh:property [ sh:path rdfs:label ; sh:nodeKind sh:Literal ; sh:minCount 1 ] ;
    sh:property [ sh:path <https://www.omg.org/spec/Commons/RolesAndCompositions/isPlayedBy> ; sh:nodeKind sh:IRI ] ;
    sh:or ( [ sh:property [ sh:path ga:shortName ; sh:minCount 1 ] ] [ sh:property [ sh:path artgov:authorityAcronym ; sh:minCount 1 ] ] ) ;
    sh:property [ sh:path ga:shortName ; sh:nodeKind sh:Literal ; sh:minLength 1 ; sh:maxLength 4096 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:accentColor ; sh:nodeKind sh:Literal ; sh:pattern "^#[0-9A-Fa-f]{6}$" ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:logo ; sh:nodeKind sh:Literal ; sh:pattern "^data:image/png;base64," ; sh:maxLength 350000 ; sh:maxCount 1 ] .

# Diagnostics are output resources, linked to reusable Markdown fragments.
ga:DiagnosticShape a sh:NodeShape ; sh:targetClass ga:Diagnostic ; sh:nodeKind sh:IRI ;
    sh:property [ sh:path ga:severity ; sh:minCount 1 ; sh:maxCount 1 ; sh:in ( "info" "warning" "error" ) ] ;
    sh:property [ sh:path ga:code ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:message ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:fragment ; sh:class ga:Fragment ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:about ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:inputRevision ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:sourceFragment ; sh:nodeKind sh:IRI ; sh:maxCount 1 ] .

ga:PageShape a sh:NodeShape ; sh:targetClass ga:Page ; sh:nodeKind sh:IRI ;
    sh:property [ sh:path ga:sourcePath ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:route ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:topic ; sh:class ga:Topic ; sh:minCount 1 ] ;
    sh:property [ sh:path ga:navigationHidden ; sh:datatype xsd:boolean ; sh:minCount 1 ; sh:maxCount 1 ] .
ga:TopicShape a sh:NodeShape ; sh:targetClass ga:Topic ; sh:nodeKind sh:IRI ;
    sh:property [ sh:path ga:fragment ; sh:class ga:Fragment ; sh:minCount 1 ] ;
    sh:property [ sh:path ga:partOf ; sh:class ga:Page ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:parentTopic ; sh:class ga:Topic ; sh:maxCount 1 ] .

ga:BinaryAssetShape a sh:NodeShape ; sh:targetClass ga:BinaryAsset ; sh:nodeKind sh:IRI ;
    sh:property [ sh:path ga:route ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:contentDigest ; sh:datatype xsd:string ; sh:pattern "^[a-f0-9]{64}$" ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:contentSize ; sh:datatype xsd:integer ; sh:minInclusive 0 ; sh:minCount 1 ; sh:maxCount 1 ] .
ga:ShowcaseShape a sh:NodeShape ; sh:targetClass ga:Showcase ; sh:nodeKind sh:IRI ;
    sh:property [ sh:path ga:previewArtifact ; sh:class ga:BinaryAsset ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:pdfArtifact ; sh:class ga:BinaryAsset ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:datasetArtifact ; sh:class ga:BinaryAsset ; sh:minCount 1 ; sh:maxCount 1 ] .

# Asset references also occur on authored fragments and collected references.
ga:AssetReferenceShape a sh:NodeShape ;
    rdfs:label "Retained asset reference"@en ;
    rdfs:comment "Requires asset links on authored fragments, collected references and publication plans to identify retained binary assets with IRIs."@en ;
    sh:targetSubjectsOf ga:asset ;
    sh:property [ sh:path ga:asset ; sh:nodeKind sh:IRI ; sh:class ga:BinaryAsset ] .


ga:ReferenceSectionShape a sh:NodeShape ; sh:targetObjectsOf ga:referenceSection ; sh:nodeKind sh:IRI ;
    sh:property [ sh:path ga:sectionKind ; sh:minCount 1 ; sh:maxCount 1 ; sh:in ("classes" "properties" "individuals" "shapes" "schemes" "concepts" "collections" "other") ] ;
    sh:property [ sh:path dct:title ; sh:nodeKind sh:Literal ; sh:minCount 1 ; sh:uniqueLang true ; sh:minLength 1 ; sh:maxLength 160 ] ;
    sh:property [ sh:path ga:order ; sh:datatype xsd:integer ; sh:minCount 1 ; sh:maxCount 1 ; sh:minInclusive 0 ; sh:maxInclusive 1000 ] .


ga:OntologyModuleShape a sh:NodeShape ; sh:targetClass ga:OntologyModule ; sh:nodeKind sh:IRI ;
    sh:property [ sh:path ga:moduleMember ; sh:nodeKind sh:IRI ] .


ga:ContentsDepthShape a sh:NodeShape ; sh:targetSubjectsOf ga:tocDepth ;
    sh:property [sh:path ga:tocDepth; sh:datatype xsd:integer; sh:minInclusive 1; sh:maxInclusive 8; sh:maxCount 1] .

ga:BookPlanShape a sh:NodeShape ; sh:targetClass ga:BookPlan ;
    sh:property [ sh:path ga:bookRoot ; sh:class ga:Placement ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:bookSubject ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ] ;
    sh:property [ sh:path ga:bookPlacement ; sh:class ga:Placement ; sh:minCount 1 ] .
