]> git.sesse.net Git - casparcg/blobdiff - core/producer/scene/scene.xsd
[scene] Updated XML Schema with examples.
[casparcg] / core / producer / scene / scene.xsd
index 7e9a2297466a55c5bb0f87c44da0f9a7d04d67db..bd43ff0e1d05dc4f2c54835c5a3d905507a00013 100644 (file)
@@ -1,7 +1,7 @@
-<xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
   <xs:element name="scene">
     <xs:complexType>
-      <xs:sequence>
+      <xs:all>
         <xs:element name="variables">
           <xs:annotation>
             <xs:documentation>
@@ -10,8 +10,9 @@
               Public variables are accessible as CG parameters and by the parent scene when nested inside another.
               There are some variables that are always defined like
               "frame" which stores the number of frames that have gone by since the scene producer started,
-              "mouse_x" and "mouse_y" which reflect the X and Y position of the mouse at all times relative to the scene coordinate system (requires interaction aware consumer like screen_consumer) and
-              "timeline_frame" which differs from "frame" in that it can rewind and jump, depending on where the timeline is at the moment.
+              "mouse_x" and "mouse_y" which reflect the X and Y position of the mouse at all times relative to the scene coordinate system (requires interaction aware consumer like screen_consumer),
+              "timeline_frame" which differs from "frame" in that it can rewind and jump, depending on where the timeline is at the moment and
+              "scene_width" and "scene_height" which contains the dimensions of the scene coordinate system.
             </xs:documentation>
           </xs:annotation>
           <xs:complexType>
                         Must be parseable/resolved as the type specified.
                       </xs:documentation>
                     </xs:annotation>
-                    <xs:extension base="expression">
-                      <xs:attribute type="type" name="type" use="required"><xs:annotation><xs:documentation>The variable type. The value/expression of the variable must be parseable/resolvable as/to this type.</xs:documentation></xs:annotation></xs:attribute>
+                    <xs:extension base="any_expression">
                       <xs:attribute type="identifier" name="id" use="required"><xs:annotation><xs:documentation>The unique variable name. Will be exposed as [id] if the variable is public or variable.[id] otherwise.</xs:documentation></xs:annotation></xs:attribute>
-                      <xs:attribute type="boolean" name="public" use="required"><xs:annotation><xs:documentation>Whether the variable should be accessible from outside the scene or not. Public variables can be accessed via CG UPDATE, CG ADD and as layer.[layerid].parameter.[id] when nested inside another scene.</xs:documentation></xs:annotation></xs:attribute>
+                      <xs:attribute type="type" name="type" use="required"><xs:annotation><xs:documentation>The variable type. The value/expression of the variable must be parseable/resolvable as/to this type.</xs:documentation></xs:annotation></xs:attribute>
+                      <xs:attribute type="boolean" name="public" default="false"><xs:annotation><xs:documentation>Whether the variable should be accessible from outside the scene or not. Public variables can be accessed via CG UPDATE, CG ADD and as layer.[layerid].parameter.[id] when nested inside another scene.</xs:documentation></xs:annotation></xs:attribute>
                     </xs:extension>
                   </xs:simpleContent>
                 </xs:complexType>
@@ -60,7 +61,7 @@
               <xs:element name="layer" minOccurs="0" maxOccurs="unbounded">
                 <xs:complexType>
                   <xs:all>
-                    <xs:element type="xs:string" name="producer">                                                   <xs:annotation><xs:documentation>The same syntax as in AMCP after for example PLAY 1-10. Cannot be an expression.</xs:documentation></xs:annotation></xs:element>
+                    <xs:element type="producer_string" name="producer">                                             <xs:annotation><xs:documentation>The same syntax as in AMCP after for example PLAY 1-10. Cannot be an expression.</xs:documentation></xs:annotation></xs:element>
                     <xs:element type="bool_expression" name="hidden" minOccurs="0" default="false">                 <xs:annotation><xs:documentation>Hides the layer if true. Can be an expression.</xs:documentation></xs:annotation></xs:element>
                     <xs:element type="number_expression" name="x">                                                  <xs:annotation><xs:documentation>The X coordinate of the layer in the scene coordinate system. Can be an expression.</xs:documentation></xs:annotation></xs:element>
                     <xs:element type="number_expression" name="y">                                                  <xs:annotation><xs:documentation>The Y coordinate of the layer in the scene coordinate system. Can be an expression.</xs:documentation></xs:annotation></xs:element>
@@ -81,7 +82,7 @@
                     <xs:element type="number_expression" name="perspective_lower_right_y" minOccurs="0">            <xs:annotation><xs:documentation>The Y position within the layer coordinate system to corner pin the lower right corner. Can be an expression.</xs:documentation></xs:annotation></xs:element>
                     <xs:element type="number_expression" name="perspective_lower_left_x" minOccurs="0" default="0"> <xs:annotation><xs:documentation>The X position within the layer coordinate system to corner pin the lower left corner. Can be an expression.</xs:documentation></xs:annotation></xs:element>
                     <xs:element type="number_expression" name="perspective_lower_left_y" minOccurs="0">             <xs:annotation><xs:documentation>The Y position within the layer coordinate system to corner pin the lower left corner. Can be an expression.</xs:documentation></xs:annotation></xs:element>
-                    <xs:element name="adjustment" minOccurs="0">
+                    <xs:element name="adjustments" minOccurs="0">
                       <xs:annotation>
                         <xs:documentation>
                           Properties regarding image adjustments. They are addressable from expressions as layer.[id].adjustment.[property].
@@ -95,7 +96,7 @@
                     </xs:element>
                     <xs:element type="bool_expression" name="is_key" minOccurs="0" default="false">                 <xs:annotation><xs:documentation>If true causes the layer to key the layer above. Can be an expression.</xs:documentation></xs:annotation></xs:element>
                     <xs:element type="bool_expression" name="use_mipmap" minOccurs="0" default="false">             <xs:annotation><xs:documentation>Whether to enable mipmapping on the layer or not. Can be an expression.</xs:documentation></xs:annotation></xs:element>
-                    <xs:element type="string_expression" name="blend_mode" minOccurs="0" default="normal">          <xs:annotation><xs:documentation>The blend mode to use. Can be an expression.</xs:documentation></xs:annotation></xs:element>
+                    <xs:element type="blend_mode" name="blend_mode" minOccurs="0" default="normal">                 <xs:annotation><xs:documentation>The blend mode to use. Can be an expression.</xs:documentation></xs:annotation></xs:element>
                     <xs:element name="chroma_key" minOccurs="0">
                       <xs:complexType>
                         <xs:all>
           </xs:complexType>
         </xs:element>
         <xs:element name="timelines" minOccurs="0">
+          <xs:annotation>
+            <xs:documentation>
+              Each variable/layer property may be manipulated by a timeline to animate the value based on keyframes.
+              The timelines are collectively moved forward in time based on the marks section and the CG command interaction from the outside.
+            </xs:documentation>
+          </xs:annotation>
           <xs:complexType>
             <xs:sequence>
               <xs:element name="timeline" minOccurs="0" maxOccurs="unbounded">
-
+                <xs:annotation>
+                  <xs:documentation>
+                    A timeline manipulates only one variable/layer property.
+                    The position on the timeline at any given time is globally controlled via the marks of the scene, so all timelines are always at the same frame as each other.
+                    If the variable/layer property is already bound to an expression it will be overridden by the timeline.
+                    Currently only number variables/layer properties are supported on timelines.
+                  </xs:documentation>
+                </xs:annotation>
+                <xs:complexType>
+                  <xs:sequence>
+                    <xs:element name="keyframe" minOccurs="0" maxOccurs="unbounded">
+                      <xs:annotation>
+                        <xs:documentation>
+                          Each keyframe specifies a value that the variable should have at a specific timeline frame.
+                          The value can be either immediately changed if no easing is specified, otherwise it is animated to the value with the given easing curve.
+                          The actual value to animate to can itself be an expression.
+                        </xs:documentation>
+                      </xs:annotation>
+                      <xs:complexType>
+                        <xs:simpleContent>
+                          <xs:extension base="number_expression">
+                            <xs:attribute name="at" type="xs:nonNegativeInteger" use="required"><xs:annotation><xs:documentation>The frame to place the keyframe at.</xs:documentation></xs:annotation></xs:attribute>
+                            <xs:attribute name="easing" type="easing" use="optional"><xs:annotation><xs:documentation>If omitted there will be no animation but an immediate value change instead.</xs:documentation></xs:annotation></xs:attribute>
+                          </xs:extension>
+                        </xs:simpleContent>
+                      </xs:complexType>
+                    </xs:element>
+                  </xs:sequence>
+                  <xs:attribute name="variable" type="variable_reference" use="required"><xs:annotation><xs:documentation>The variable/layer property to manipulate. If it already has an expression the expression will be overridden.</xs:documentation></xs:annotation></xs:attribute>
+                </xs:complexType>
               </xs:element>
             </xs:sequence>
           </xs:complexType>
+          <xs:unique name="oneTimelinePerVariable">
+            <xs:selector xpath="timeline" />
+            <xs:field xpath="@variable" />
+          </xs:unique>
         </xs:element>
-      </xs:sequence>
-      <xs:attribute type="xs:positiveInteger" name="width" />
-      <xs:attribute type="xs:positiveInteger" name="height" />
+        <xs:element name="tasks" minOccurs="0">
+          <xs:annotation>
+            <xs:documentation>
+              Tasks are scheduled to happen whenever a certain condition arises.
+              Use the at attribute to let the condition be that the timeline arrives at a specific frame
+              or the when attribute to specify a custom bool expression that when becomes true triggers the task.
+            </xs:documentation>
+          </xs:annotation>
+          <xs:complexType>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+              <xs:element name="call">
+                <xs:annotation><xs:documentation>Performs the equivalent of an AMCP CALL on the specified layer.</xs:documentation></xs:annotation>
+                <xs:complexType>
+                  <xs:sequence maxOccurs="unbounded">
+                    <xs:element name="arg" type="xs:string"><xs:annotation><xs:documentation>See the producer documentation for the possible arguments.</xs:documentation></xs:annotation></xs:element>
+                  </xs:sequence>
+                  <xs:attribute name="at" use="optional" type="xs:nonNegativeInteger"><xs:annotation><xs:documentation>Trigger the CALL when the timeline gets to this specific frame.</xs:documentation></xs:annotation></xs:attribute>
+                  <xs:attribute name="when" use="optional" type="bool_expression"><xs:annotation><xs:documentation>Trigger the CALL when the specified bool expression becomes true.</xs:documentation></xs:annotation></xs:attribute>
+                  <xs:attribute name="to_layer" use="required" type="identifier"><xs:annotation><xs:documentation>The producer on this layer will receive the CALL.</xs:documentation></xs:annotation></xs:attribute>
+                </xs:complexType>
+              </xs:element>
+              <xs:element name="cg_play">
+                <xs:annotation><xs:documentation>Performs the equivalent of a CG PLAY on the specified layer.</xs:documentation></xs:annotation>
+                <xs:complexType>
+                  <xs:attribute name="at" use="optional" type="xs:nonNegativeInteger"><xs:annotation><xs:documentation>Trigger the CG PLAY when the timeline gets to this specific frame.</xs:documentation></xs:annotation></xs:attribute>
+                  <xs:attribute name="when" use="optional" type="bool_expression"><xs:annotation><xs:documentation>Trigger the CG PLAY when the specified bool expression becomes true.</xs:documentation></xs:annotation></xs:attribute>
+                  <xs:attribute name="to_layer" use="required" type="identifier"><xs:annotation><xs:documentation>The CG producer on this layer will receive the CG PLAY.</xs:documentation></xs:annotation></xs:attribute>
+                </xs:complexType>
+              </xs:element>
+              <xs:element name="cg_stop">
+                <xs:annotation><xs:documentation>Performs the equivalent of a CG STOP on the specified layer.</xs:documentation></xs:annotation>
+                <xs:complexType>
+                  <xs:attribute name="at" use="optional" type="xs:nonNegativeInteger"><xs:annotation><xs:documentation>Trigger the CG STOP when the timeline gets to this specific frame.</xs:documentation></xs:annotation></xs:attribute>
+                  <xs:attribute name="when" use="optional" type="bool_expression"><xs:annotation><xs:documentation>Trigger the CG STOP when the specified bool expression becomes true.</xs:documentation></xs:annotation></xs:attribute>
+                  <xs:attribute name="to_layer" use="required" type="identifier"><xs:annotation><xs:documentation>The CG producer on this layer will receive the CG STOP.</xs:documentation></xs:annotation></xs:attribute>
+                </xs:complexType>
+              </xs:element>
+              <xs:element name="cg_next">
+                <xs:annotation><xs:documentation>Performs the equivalent of a CG NEXT on the specified layer.</xs:documentation></xs:annotation>
+                <xs:complexType>
+                  <xs:attribute name="at" use="optional" type="xs:nonNegativeInteger"><xs:annotation><xs:documentation>Trigger the CG NEXT when the timeline gets to this specific frame.</xs:documentation></xs:annotation></xs:attribute>
+                  <xs:attribute name="when" use="optional" type="bool_expression"><xs:annotation><xs:documentation>Trigger the CG NEXT when the specified bool expression becomes true.</xs:documentation></xs:annotation></xs:attribute>
+                  <xs:attribute name="to_layer" use="required" type="identifier"><xs:annotation><xs:documentation>The CG producer on this layer will receive the CG NEXT.</xs:documentation></xs:annotation></xs:attribute>
+                </xs:complexType>
+              </xs:element>
+              <xs:element name="cg_invoke">
+                <xs:annotation><xs:documentation>Performs the equivalent of a CG INVOKE on the specified layer with the specified label.</xs:documentation></xs:annotation>
+                <xs:complexType>
+                  <xs:attribute name="at" use="optional" type="xs:nonNegativeInteger"><xs:annotation><xs:documentation>Trigger the CG INVOKE when the timeline gets to this specific frame.</xs:documentation></xs:annotation></xs:attribute>
+                  <xs:attribute name="when" use="optional" type="bool_expression"><xs:annotation><xs:documentation>Trigger the CG INVOKE when the specified bool expression becomes true.</xs:documentation></xs:annotation></xs:attribute>
+                  <xs:attribute name="to_layer" use="required" type="identifier"><xs:annotation><xs:documentation>The CG producer on this layer will receive the CG INVOKE.</xs:documentation></xs:annotation></xs:attribute>
+                  <xs:attribute name="label" use="required" type="nonEmptyString"><xs:annotation><xs:documentation>The label that will be invoked.</xs:documentation></xs:annotation></xs:attribute>
+                </xs:complexType>
+              </xs:element>
+              <xs:element name="goto_mark">
+                <xs:annotation><xs:documentation>Makes the scene go to a specific start mark given a specific condition becoming true.</xs:documentation></xs:annotation>
+                <xs:complexType>
+                  <xs:attribute name="when" use="required" type="bool_expression"><xs:annotation><xs:documentation>Go to the start mark when the specified bool expression becomes true.</xs:documentation></xs:annotation></xs:attribute>
+                  <xs:attribute name="label" use="required" type="nonEmptyString"><xs:annotation><xs:documentation>The label of the start mark that the scene should go to.</xs:documentation></xs:annotation></xs:attribute>
+                </xs:complexType>
+              </xs:element>
+            </xs:choice>
+          </xs:complexType>
+        </xs:element>
+      </xs:all>
+      <xs:attribute type="xs:positiveInteger" name="width" use="required" />
+      <xs:attribute type="xs:positiveInteger" name="height" use="required" />
     </xs:complexType>
   </xs:element>
   <xs:simpleType name="type">
       <xs:pattern value="[a-zA-Z_][a-zA-Z0-9_]*" />
     </xs:restriction>
   </xs:simpleType>
+  <xs:simpleType name="variable_reference">
+    <xs:restriction base="xs:string">
+      <xs:whiteSpace value="collapse" />
+      <xs:pattern value="[a-zA-Z_][a-z\.A-Z0-9_]*" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="nonEmptyString">
+    <xs:restriction base="xs:string">
+      <xs:whiteSpace value="collapse" />
+      <xs:minLength value="1" />
+    </xs:restriction>
+  </xs:simpleType>
   <xs:simpleType name="boolean">
     <xs:restriction base="xs:string">
       <xs:whiteSpace value="collapse" />
       <xs:enumeration value="false" />
     </xs:restriction>
   </xs:simpleType>
+
   <xs:simpleType name="expression">
     <xs:restriction base="xs:string">
       <xs:annotation>
         <xs:documentation>
         </xs:documentation>
       </xs:annotation>
+      <xs:whiteSpace value="collapse" />
+      <xs:pattern value="$\{.+\}" />
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="string_expression_examples">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="A string constant" />
+      <xs:enumeration value="${&quot;A string constant&quot;}" />
+      <xs:enumeration value="${variable.some_string + &quot; will be concatenated&quot;}" />
+      <xs:enumeration value="${to_lower(variable.some_string)}" />
+      <xs:enumeration value="${to_upper(variable.some_string)}" />
+      <xs:enumeration value="${&quot;Concatenate string with number: &quot; + variable.some_number}" />
+      <xs:enumeration value="${&quot;Concatenate string with different strings based on bool: &quot; + (variable.some_bool ? &quot;Enabled&quot; : &quot;Disabled&quot;)}" />
+      <xs:enumeration value="${mouse_x &lt; 640 ? &quot;Left of middle&quot; : variable.message_when_right_of_middle}" />
     </xs:restriction>
   </xs:simpleType>
   <xs:simpleType name="string_expression">
-    <xs:restriction base="expression">
-      <xs:annotation>
-        <xs:documentation>
-        </xs:documentation>
-      </xs:annotation>
+    <xs:union memberTypes="xs:string expression string_expression_examples" />
+  </xs:simpleType>
+
+  <xs:simpleType name="available_blend_modes">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="normal" />
+      <xs:enumeration value="lighten" />
+      <xs:enumeration value="darken" />
+      <xs:enumeration value="multiply" />
+      <xs:enumeration value="average" />
+      <xs:enumeration value="add" />
+      <xs:enumeration value="subtract" />
+      <xs:enumeration value="difference" />
+      <xs:enumeration value="negation" />
+      <xs:enumeration value="exclusion" />
+      <xs:enumeration value="screen" />
+      <xs:enumeration value="overlay" />
+      <xs:enumeration value="soft_light" />
+      <xs:enumeration value="hard_light" />
+      <xs:enumeration value="color_dodge" />
+      <xs:enumeration value="color_burn" />
+      <xs:enumeration value="linear_dodge" />
+      <xs:enumeration value="linear_burn" />
+      <xs:enumeration value="linear_light" />
+      <xs:enumeration value="vivid_light" />
+      <xs:enumeration value="pin_light" />
+      <xs:enumeration value="hard_mix" />
+      <xs:enumeration value="reflect" />
+      <xs:enumeration value="glow" />
+      <xs:enumeration value="phoenix" />
+      <xs:enumeration value="contrast" />
+      <xs:enumeration value="saturation" />
+      <xs:enumeration value="color" />
+      <xs:enumeration value="luminosity" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="blend_mode_expression_examples">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="${should_lighten ? &quot;lighten&quot; : &quot;normal&quot;}" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="blend_mode">
+    <xs:union memberTypes="available_blend_modes expression blend_mode_expression_examples" />
+  </xs:simpleType>
+
+  <xs:simpleType name="number_expression_examples">
+    <xs:restriction base="xs:string">
+      <xs:whiteSpace value="collapse" />
+      <xs:enumeration value="0" />
+      <xs:enumeration value="0.0" />
+      <xs:enumeration value="${0.0}" />
+      <xs:enumeration value="${variable.foo + variable.bar}" />
+      <xs:enumeration value="${layer.foo.x + layer.foo.width + variable.bar_offset_x}" />
+      <xs:enumeration value="${variable.foo + 640.0}" />
+      <xs:enumeration value="${variable.foo - variable.bar}" />
+      <xs:enumeration value="${1.0 - variable.bar}" />
+      <xs:enumeration value="${variable.foo * variable.bar}" />
+      <xs:enumeration value="${variable.foo / variable.bar}" />
+      <xs:enumeration value="${variable.foo % variable.bar}" />
+      <xs:enumeration value="${(variable.a + variable.b) * variable.c}" />
+      <xs:enumeration value="${frame &lt; 50 ? variable.initial_value : variable.value_after_a_while}" />
+      <xs:enumeration value="${sin(angle)}" />
+      <xs:enumeration value="${cos(angle)}" />
+      <xs:enumeration value="${abs(value)}" />
+      <xs:enumeration value="${floor(value)}" />
+      <xs:enumeration value="${length(str)}" />
+      <xs:enumeration value="${animate(expression_to_animate, duration, tweener)}" />
+      <xs:enumeration value="${animate(layer.to_follow.x, 200, &quot;easeoutelastic&quot;)}" />
     </xs:restriction>
   </xs:simpleType>
   <xs:simpleType name="number_expression">
-    <xs:restriction base="expression">
-      <xs:annotation>
-        <xs:documentation>
-        </xs:documentation>
-      </xs:annotation>
+    <xs:union memberTypes="xs:decimal expression number_expression_examples" />
+  </xs:simpleType>
+
+  <xs:simpleType name="bool_expression_examples">
+    <xs:restriction base="xs:string">
       <xs:whiteSpace value="collapse" />
-      <xs:pattern value="[+-]?\d+(\.\d+)?|\$\{.+\}" />
+      <xs:enumeration value="${variable.some_number == 50}" />
+      <xs:enumeration value="${variable.some_number != 50}" />
+      <xs:enumeration value="${variable.some_string == &quot;true when strings are equal&quot;}" />
+      <xs:enumeration value="${variable.some_string != &quot;false when strings are equal&quot;}" />
+      <xs:enumeration value="${frame &gt; 50}" />
+      <xs:enumeration value="${frame &lt; 50}" />
+      <xs:enumeration value="${frame &gt;= 50}" />
+      <xs:enumeration value="${frame &lt;= 50}" />
+      <xs:enumeration value="${!variable.some_bool}" />
     </xs:restriction>
   </xs:simpleType>
   <xs:simpleType name="bool_expression">
-    <xs:restriction base="expression">
-      <xs:annotation>
-        <xs:documentation>
-        </xs:documentation>
-      </xs:annotation>
+    <xs:union memberTypes="boolean expression bool_expression_examples" />
+  </xs:simpleType>
+
+  <xs:simpleType name="any_expression">
+    <xs:union memberTypes="string_expression number_expression bool_expression" />
+  </xs:simpleType>
+
+  <xs:simpleType name="producer_examples">
+    <xs:restriction base="xs:string">
       <xs:whiteSpace value="collapse" />
-      <xs:pattern value="true|false|\$\{.+\}" />
+      <xs:enumeration value="RED" />
+      <xs:enumeration value="#AA0000AA" />
+      <xs:enumeration value="amb LOOP" />
+      <xs:enumeration value="rtmp://example.com/stream" />
+      <xs:enumeration value="[HTML] http://casparcg.com" />
+      <xs:enumeration value="[TEXT] &quot;&quot; 0 0 size 30 color #1b698d font ArialMT" />
+      <xs:enumeration value="[TEXT] &quot;Initial text before bound via layer.text_layer.param.text&quot; 0 0 size 30 color #1b698d font ArialMT" />
+      <xs:enumeration value="route://1" />
+      <xs:enumeration value="route://1-10" />
+      <xs:enumeration value="child_scene" />
+      <xs:enumeration value="DECKLINK 8 FORMAT 1080i5000 FILTER DEINTERLACE_BOB" />
     </xs:restriction>
   </xs:simpleType>
+
+  <xs:simpleType name="producer_string">
+    <xs:union memberTypes="nonEmptyString producer_examples" />
+  </xs:simpleType>
+
   <xs:simpleType name="mark_action">
     <xs:restriction base="xs:string">
       <xs:whiteSpace value="collapse" />
       <xs:enumeration value="remove" />
     </xs:restriction>
   </xs:simpleType>
+  <xs:simpleType name="easing">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="linear" />
+      <xs:enumeration value="easeinquad" />
+      <xs:enumeration value="easeoutquad" />
+      <xs:enumeration value="easeinoutquad" />
+      <xs:enumeration value="easeoutinquad" />
+      <xs:enumeration value="easeincubic" />
+      <xs:enumeration value="easeoutcubic" />
+      <xs:enumeration value="easeinoutcubic" />
+      <xs:enumeration value="easeoutincubic" />
+      <xs:enumeration value="easeinquart" />
+      <xs:enumeration value="easeoutquart" />
+      <xs:enumeration value="easeinoutquart" />
+      <xs:enumeration value="easeoutinquart" />
+      <xs:enumeration value="easeinquint" />
+      <xs:enumeration value="easeoutquint" />
+      <xs:enumeration value="easeinoutquint" />
+      <xs:enumeration value="easeoutinquint" />
+      <xs:enumeration value="easeinsine" />
+      <xs:enumeration value="easeoutsine" />
+      <xs:enumeration value="easeinoutsine" />
+      <xs:enumeration value="easeoutinsine" />
+      <xs:enumeration value="easeinexpo" />
+      <xs:enumeration value="easeoutexpo" />
+      <xs:enumeration value="easeinoutexpo" />
+      <xs:enumeration value="easeoutinexpo" />
+      <xs:enumeration value="easeincirc" />
+      <xs:enumeration value="easeoutcirc" />
+      <xs:enumeration value="easeinoutcirc" />
+      <xs:enumeration value="easeoutincirc" />
+      <xs:enumeration value="easeinelastic" />
+      <xs:enumeration value="easeoutelastic" />
+      <xs:enumeration value="easeinoutelastic" />
+      <xs:enumeration value="easeoutinelastic" />
+      <xs:enumeration value="easeinback" />
+      <xs:enumeration value="easeoutback" />
+      <xs:enumeration value="easeinoutback" />
+      <xs:enumeration value="easeoutintback" />
+      <xs:enumeration value="easeoutbounce" />
+      <xs:enumeration value="easeinbounce" />
+      <xs:enumeration value="easeinoutbounce" />
+      <xs:enumeration value="easeoutinbounce" />
+    </xs:restriction>
+  </xs:simpleType>
 </xs:schema>