<?xml version="1.0" encoding="UTF-8"?>
<!--
     Open Document Format for Office Applications (OpenDocument) Version 1.4
     OASIS Standard
     11 March 2024
     Copyright (c) OASIS Open 2024. All Rights Reserved.
     Source: https://docs.oasis-open.org/office/OpenDocument/v1.4/csd01/schemas/
     Latest stage of specification: https://docs.oasis-open.org/office/OpenDocument/v1.4/OpenDocument-v1.4-part1-introduction.html
     TC IPR Statement: https://www.oasis-open.org/committees/office/ipr.php 

        Open Document Format for Office Applications (OpenDocument) Version 1.4
        Manifest Relax-NG Schema
        OpenDocument-v1.4-manifest-schema.rng
-->
<!-- https://issues.oasis-open.org/browse/OFFICE-2153 -->

<rng:grammar xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" xmlns:rng="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  <rng:start>
    <rng:choice>
      <rng:ref name="manifest"/>
    </rng:choice>
  </rng:start>
  <rng:define name="algorithm">
    <rng:element name="manifest:algorithm">
      <rng:ref name="algorithm-attlist"/>
      <rng:ref name="anyElements"/>
    </rng:element>
  </rng:define>
  <rng:define name="algorithm-attlist">
    <rng:interleave>
      <rng:attribute name="manifest:algorithm-name">
        <rng:choice>
          <rng:value>Blowfish CFB</rng:value>
          <rng:ref name="anyURI"/>
        </rng:choice>
      </rng:attribute>
      <rng:attribute name="manifest:initialisation-vector">
        <rng:ref name="base64Binary"/>
      </rng:attribute>
    </rng:interleave>
  </rng:define>
  <rng:define name="anyAttListOrElements">
    <rng:zeroOrMore>
      <rng:attribute>
        <rng:anyName/>
        <rng:text/>
      </rng:attribute>
    </rng:zeroOrMore>
    <rng:ref name="anyElements"/>
  </rng:define>
  <rng:define name="anyElements">
    <rng:zeroOrMore>
      <rng:element>
        <rng:anyName/>
        <rng:mixed>
          <rng:ref name="anyAttListOrElements"/>
        </rng:mixed>
      </rng:element>
    </rng:zeroOrMore>
  </rng:define>
  <rng:define name="anyURI">
    <rng:data type="anyURI"/>
  </rng:define>
  <rng:define name="base64Binary">
    <rng:data type="base64Binary"/>
  </rng:define>
  <rng:define name="encrypted-key">
    <rng:element name="manifest:encrypted-key">
      <rng:optional>
        <rng:element name="manifest:encryption-method">
          <rng:attribute name="manifest:PGPAlgorithm">
            <rng:ref name="anyURI"/>
          </rng:attribute>
        </rng:element>
      </rng:optional>
      <rng:element name="manifest:keyinfo">
        <rng:element name="manifest:PGPData">
          <rng:element name="manifest:PGPKeyID">
            <rng:ref name="base64Binary"/>
          </rng:element>
          <rng:optional>
            <rng:element name="manifest:PGPKeyPacket">
              <rng:ref name="base64Binary"/>
            </rng:element>
          </rng:optional>
        </rng:element>
      </rng:element>
      <rng:element name="manifest:CipherData">
        <rng:element name="manifest:CipherValue">
          <rng:ref name="base64Binary"/>
        </rng:element>
      </rng:element>
    </rng:element>
  </rng:define>
  <rng:define name="encryption-data">
    <rng:element name="manifest:encryption-data">
      <rng:ref name="encryption-data-attlist"/>
      <rng:ref name="algorithm"/>
      <rng:optional>
        <rng:ref name="start-key-generation"/>
      </rng:optional>
      <rng:ref name="key-derivation"/>
    </rng:element>
  </rng:define>
  <rng:define name="encryption-data-attlist">
    <rng:interleave>
      <rng:attribute name="manifest:checksum-type">
        <rng:choice>
          <rng:value>SHA1/1K</rng:value>
          <rng:ref name="anyURI"/>
        </rng:choice>
      </rng:attribute>
      <rng:attribute name="manifest:checksum">
        <rng:ref name="base64Binary"/>
      </rng:attribute>
    </rng:interleave>
  </rng:define>
  <rng:define name="file-entry">
    <rng:element name="manifest:file-entry">
      <rng:ref name="file-entry-attlist"/>
      <rng:optional>
        <rng:ref name="encryption-data"/>
      </rng:optional>
    </rng:element>
  </rng:define>
  <rng:define name="file-entry-attlist">
    <rng:interleave>
      <rng:attribute name="manifest:full-path">
        <rng:ref name="string"/>
      </rng:attribute>
      <rng:optional>
        <rng:attribute name="manifest:size">
          <rng:ref name="nonNegativeInteger"/>
        </rng:attribute>
      </rng:optional>
      <rng:attribute name="manifest:media-type">
        <rng:ref name="string"/>
      </rng:attribute>
      <rng:optional>
        <rng:attribute name="manifest:preferred-view-mode">
          <rng:choice>
            <rng:value>edit</rng:value>
            <rng:value>presentation-slide-show</rng:value>
            <rng:value>read-only</rng:value>
            <rng:ref name="namespacedToken"/>
          </rng:choice>
        </rng:attribute>
      </rng:optional>
      <rng:optional>
        <rng:attribute name="manifest:version">
          <rng:ref name="string"/>
        </rng:attribute>
      </rng:optional>
    </rng:interleave>
  </rng:define>
  <rng:define name="key-derivation">
    <rng:element name="manifest:key-derivation">
      <rng:ref name="key-derivation-attlist"/>
      <rng:empty/>
    </rng:element>
  </rng:define>
  <rng:define name="key-derivation-attlist">
    <rng:choice>
      <rng:attribute name="manifest:key-derivation-name">
        <rng:value>PGP</rng:value>
      </rng:attribute>
      <rng:interleave>
        <rng:attribute name="manifest:key-derivation-name">
          <rng:choice>
            <rng:value>PBKDF2</rng:value>
            <rng:ref name="anyURI"/>
          </rng:choice>
        </rng:attribute>
        <rng:attribute name="manifest:salt">
          <rng:ref name="base64Binary"/>
        </rng:attribute>
        <rng:attribute name="manifest:iteration-count">
          <rng:ref name="nonNegativeInteger"/>
        </rng:attribute>
        <rng:optional>
          <rng:attribute name="manifest:key-size">
            <rng:ref name="nonNegativeInteger"/>
          </rng:attribute>
        </rng:optional>
      </rng:interleave>
    </rng:choice>
  </rng:define>
  <rng:define name="manifest">
    <rng:element name="manifest:manifest">
      <rng:ref name="manifest-attlist"/>
      <rng:zeroOrMore>
        <rng:ref name="encrypted-key"/>
      </rng:zeroOrMore>
      <!-- https://issues.oasis-open.org/browse/OFFICE-3940 -->
      <rng:oneOrMore>
        <rng:ref name="file-entry"/>
      </rng:oneOrMore>
    </rng:element>
  </rng:define>
  <rng:define name="manifest-attlist">
    <rng:attribute name="manifest:version">
      <rng:value>1.4</rng:value>
    </rng:attribute>
  </rng:define>
  <rng:define name="namespacedToken">
    <rng:data type="QName">
      <rng:param name="pattern">[^:]+:[^:]+</rng:param>
    </rng:data>
  </rng:define>
  <rng:define name="nonNegativeInteger">
    <rng:data type="nonNegativeInteger"/>
  </rng:define>
  <rng:define name="start-key-generation">
    <rng:element name="manifest:start-key-generation">
      <rng:ref name="start-key-generation-attlist"/>
      <rng:empty/>
    </rng:element>
  </rng:define>
  <rng:define name="start-key-generation-attlist">
    <rng:interleave>
      <rng:attribute name="manifest:start-key-generation-name">
        <rng:choice>
          <rng:value>SHA1</rng:value>
          <rng:ref name="anyURI"/>
        </rng:choice>
      </rng:attribute>
      <rng:optional>
        <rng:attribute name="manifest:key-size">
          <rng:ref name="nonNegativeInteger"/>
        </rng:attribute>
      </rng:optional>
    </rng:interleave>
  </rng:define>
  <rng:define name="string">
    <rng:data type="string"/>
  </rng:define>
</rng:grammar>
