From 22398ce651901d0b72a92d29e17f559e075c33a2 Mon Sep 17 00:00:00 2001 From: Dave Kuhlman <dkuhlman@davekuhlman.org> Date: Fri, 28 Apr 2017 15:02:28 -0700 Subject: [PATCH] New command line options for process_includes.py --- README | 11 +++ generateDS.html | 158 +++++++++++++++++++----------- generateDS.py | 62 +++++++++--- generateDS.txt | 147 +++++++++++++++++---------- generateds_gui_notes.html | 6 +- generateds_gui_notes.txt | 2 +- gui/generateds_gui.py | 2 +- librarytemplate_howto.html | 6 +- librarytemplate_howto.txt | 2 +- process_includes.py | 36 +++++-- setup.py | 2 +- tutorial/generateds_tutorial.html | 6 +- tutorial/generateds_tutorial.txt | 2 +- tutorial/generateds_tutorial.zip | Bin 48769 -> 48769 bytes 14 files changed, 302 insertions(+), 140 deletions(-) diff --git a/README b/README index e70ab60..67cd5db 100644 --- a/README +++ b/README @@ -141,6 +141,17 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Change history -------------- +Version 2.26a (05/01/2017) + +- Added command line options --no-collect-includes and + --no-redefine-groups. These options selectively turn off tasks + performed in process_includes.py. These options were added + because the use of --no-process-includes (which omits all + processing done in process_includes.py) was reported to cause + errors. See the documentation and the usage message (run + `generateDS.py --help`) for more information. Thanks to + Florian Wilmshoever for reporting and working with me on this. + Version 2.25a (03/21/2017) - Fixes to the Django support for Python 3. Thanks to Shane Rigby diff --git a/generateDS.html b/generateDS.html index 3605073..2c82042 100644 --- a/generateDS.html +++ b/generateDS.html @@ -220,7 +220,7 @@ They are used by updateversion.py. --> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.25a</td> +<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.26a</td> </tr> </tbody> </table> @@ -229,7 +229,7 @@ They are used by updateversion.py. --> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">date:</th><td class="field-body">March 21, 2017</td> +<tr class="field"><th class="field-name">date:</th><td class="field-body">April 28, 2017</td> </tr> </tbody> </table> @@ -380,12 +380,12 @@ to process the contents of an XML document.</td> </li> <li><a class="reference internal" href="#limitations-of-generateds" id="id92">17 Limitations of generateDS</a><ul class="auto-toc"> <li><a class="reference internal" href="#xml-schema-limitations" id="id93">17.1 XML Schema limitations</a></li> -<li><a class="reference internal" href="#large-documents" id="id94">17.2 Large documents</a></li> </ul> </li> -<li><a class="reference internal" href="#includes-the-xml-schema-include-element" id="id95">18 Includes -- The XML schema include element</a></li> -<li><a class="reference internal" href="#acknowledgments" id="id96">19 Acknowledgments</a></li> -<li><a class="reference internal" href="#see-also" id="id97">20 See also</a></li> +<li><a class="reference internal" href="#includes-the-xml-schema-xs-include-and-xs-import-elements" id="id94">18 Includes -- The XML schema xs:include and xs:import elements</a></li> +<li><a class="reference internal" href="#processing-relaxng-schemas" id="id95">19 Processing RelaxNG schemas</a></li> +<li><a class="reference internal" href="#acknowledgments" id="id96">20 Acknowledgments</a></li> +<li><a class="reference internal" href="#see-also" id="id97">21 See also</a></li> </ul> </div> <div class="section" id="introduction"> @@ -586,10 +586,19 @@ Options: generated files. This is useful if you want to minimize the amount of (no-operation) changes to the generated python code. - --no-process-includes Do not process included XML schema files. By - default, generateDS.py will insert content - from files referenced by <include ... /> - elements into the XML schema to be processed. + --no-process-includes Do not use process_includes.py to pre-process + included XML schema files. By default, + generateDS.py will insert content from files + referenced by xs:include and xs:import elements + into the XML schema to be processed and perform + several other pre-procesing tasks. You likely do + not want to use this option; its use has been + reported to result in errors in generated modules. + Consider using --no-collect-includes and/or + --no-redefine-groups instead. + --no-collect-includes Do not (recursively) collect and insert schemas + referenced by xs:include and xs:import elements. + --no-redefine-groups Do not pre-process and redefine group definitions. --silence Normally, the code generated with generateDS echoes the information being parsed. To prevent the echo from occurring, use the --silence switch. @@ -802,15 +811,30 @@ changes to the generated python code.</dd> useful if you want to minimize the amount of (no-operation) changes to the generated python code.</dd> <dt>no-process-includes</dt> -<dd>Do not process included XML Schema files. By default, -generateDS.py will insert content from files referenced by -<tt class="docutils literal"><include ... /></tt> elements into the XML Schema to be processed. -See section <a class="reference internal" href="#include-file-processing">Include file processing</a>. Note that include -processing, which is performed in <tt class="docutils literal">process_includes.py</tt> is -required for generating validator bodies from the XML schema, -because the Lxml ElementTree produced in <tt class="docutils literal">process_includes.py</tt> -is needed to generate the validator code. So, using this option -also turns off automatic generation of validator code.</dd> +<dd>Do not use <tt class="docutils literal">process_includes.py</tt> to pre-process included XML +Schema files. By default, generateDS.py will insert content +from files referenced by <tt class="docutils literal">xs:include</tt> and <tt class="docutils literal">xs:import</tt> +elements into the XML Schema to be processed. See section +<a class="reference internal" href="#include-file-processing">Include file processing</a>. Note that include processing, which +is performed in <tt class="docutils literal">process_includes.py</tt> is required for +generating validator bodies from the XML schema, because the +Lxml ElementTree produced in <tt class="docutils literal">process_includes.py</tt> is needed +to generate the validator code. So, using this option also +turns off automatic generation of validator code. Also note +that process_includes(.py) performs additional tasks; it also +(1) assigns names to each anonymous complexType, (2) processes +(replaces) group definitions, and (3) possibly fixes complexType +names (see command line option --fix-type-names). You likely do +not want to use this option; its use has been reported to result +in errors in generated modules. Consider using +--no-collect-includes and/or --no-redefine-groups instead.</dd> +<dt>no-collect-includes</dt> +<dd>Do not (recursively) collect and insert schemas referenced by +<tt class="docutils literal">xs:include</tt> and <tt class="docutils literal">xs:import</tt> elements. This task is +performed in <tt class="docutils literal">process_includes.py</tt>.</dd> +<dt>no-redefine-groups</dt> +<dd>Do not pre-process and redefine group definitions. This task is +performed in <tt class="docutils literal">process_includes.py</tt>.</dd> <dt>silence</dt> <dd>Normally, the code generated with generateDS echoes the information being parsed. To prevent the echo from occurring, @@ -3111,41 +3135,24 @@ people.xml for examples.</p> <p>And, then, try it on your XML Schema, and let me know about what does not work.</p> </div> -<div class="section" id="large-documents"> -<h2><a class="toc-backref" href="#id94">17.2 Large documents</a></h2> -<p><strong>Warning</strong> -- This section describes an optional generated SAX -parser which, I believe, is currently broken for all but the -simplest schemas. Generation of a SAX parser has not been updated -for the latest changes to <tt class="docutils literal">generateDS.py</tt>. In particular, when -names of elements are reused (in different parent elements), the -SAX parser becomes confused. Until I've been able to figure out -how to fix this, you are advised not to use the SAX parser.</p> -<p><tt class="docutils literal">generateDS.py</tt> generates two kinds of parsers: one kind is -based on SAX and the other is build on minidom. See the generated -functions saxParse, parse(), and parseString(). Using the SAX -parser instead of the minidom parser should reduce memory -requirements for large documents, since the minidom parser, but -not the SAX parser, constructs a DOM tree for the entire document -in memory.</p> -<p>However, both styles of parsers construct instances of the data -structures generated by <tt class="docutils literal">generateDS.py</tt>. This means that, even -when the SAX parser is used, <tt class="docutils literal">generateDS.py</tt> may not be -well-suited for applications that read large XML documents, -although what "large" means depends on your hardware. Notice that -the minidom parsing functions (parse() and parseString()) -over-write the variable doc so as to enable Python to reclaim the -space occupied by the DOM tree, which may help alleviate the -memory problem to some extent when the minidom parser is used.</p> -</div> -</div> -<div class="section" id="includes-the-xml-schema-include-element"> -<h1><a class="toc-backref" href="#id95">18 Includes -- The XML schema include element</a></h1> +</div> +<div class="section" id="includes-the-xml-schema-xs-include-and-xs-import-elements"> +<h1><a class="toc-backref" href="#id94">18 Includes -- The XML schema xs:include and xs:import elements</a></h1> <p>While <tt class="docutils literal">generateDS.py</tt> itself does not process XML Schema <tt class="docutils literal">include</tt> elements, the distribution provides a script -<tt class="docutils literal">process_includes.py</tt> that can be used as a preprocessor. This -script scans your XML Schema document and, recursively, documents -that are included looking for <tt class="docutils literal">include</tt> elements; it inserts all -content into a single document, which it writes out.</p> +<tt class="docutils literal">process_includes.py</tt> that can be used as a preprocessor. +<tt class="docutils literal">process_includes.py</tt> is called automatically and by default by +<tt class="docutils literal">generateDS.py</tt>. This behavior can be turned off with the +<tt class="docutils literal"><span class="pre">--no-process-includes</span></tt> command line option. <strong>However</strong>, doing +so is not advised, because unexpected and undesirable behavior has +been detected this is done. Instead consider using the +<tt class="docutils literal"><span class="pre">--no-collect-includes</span></tt> and <tt class="docutils literal"><span class="pre">--no-redefine-groups</span></tt> command line +options to selectively turn of specific processing done in +<tt class="docutils literal">process_includes.py</tt>.</p> +<p>The <tt class="docutils literal">process_includes.py</tt> script scans your XML Schema document +and, recursively, documents that are included looking for +<tt class="docutils literal">include</tt> elements; it inserts all content into a single document, +which it writes out.</p> <p>Here are samples of how you might use <tt class="docutils literal">process_includes.py</tt>, if your schema contains <tt class="docutils literal">include</tt> elements.</p> <p>Example 1:</p> @@ -3163,8 +3170,49 @@ $ python generateDS.py -f --super=task1sup -o task1sup.py -s task1sub.py tmp.xsd $ python process_includes.py --help </pre> </div> +<div class="section" id="processing-relaxng-schemas"> +<h1><a class="toc-backref" href="#id95">19 Processing RelaxNG schemas</a></h1> +<p>RelaxNG is a schema definition language and is an alternative to XML +Schema. For more information on RelaxNG, see: <a class="reference external" href="http://relaxng.org/">http://relaxng.org/</a>.</p> +<p><tt class="docutils literal">generateDS.py</tt> does not understand or process RelaxNG schemas. +However, the <tt class="docutils literal">trang</tt> application is able to convert RelaxNG into +XML Schemas. I've tried it, and was able to convert a relatively +small RelaxNG schema into an XML Schema, and then use +<tt class="docutils literal">generateDS.py</tt> to generate a bindings module from that. I have +not done any serious testing to determine how complete or accurate +this conversion is. <tt class="docutils literal">trang</tt> is written in Java, so you will need +Java and the JDK installed in order to compile and use it. For what +it's worth, here are the steps I followed in order to use <tt class="docutils literal">trang</tt>:</p> +<ol class="arabic"> +<li><p class="first">Clone trang from <a class="reference external" href="https://github.com/relaxng/jing-trang.git">https://github.com/relaxng/jing-trang.git</a>, +and, then built it with:</p> +<pre class="literal-block"> +$ git clone https://github.com/relaxng/jing-trang.git +$ cd jing-trang +# set JAVA_HOME to location of JDK +$ export JAVA_HOME=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt +$ ./ant +</pre> +</li> +<li><p class="first">Run <tt class="docutils literal">trang</tt> with the following:</p> +<pre class="literal-block"> +$ cd jing-trang/build +$ java -jar trang.jar -I rng -O xsd test01.rng test01.xsd +</pre> +<p>The above command produced test01.xsd.</p> +</li> +<li><p class="first">Run the resulting XML Schema (<tt class="docutils literal">test01.xsd</tt>, in the above case) +through <tt class="docutils literal">generateDS.py</tt>:</p> +<blockquote> +<p>$ generateDS.py -o test01sup.py -s test01sub.py test01.xsd</p> +</blockquote> +</li> +</ol> +<p>You can learn more about <tt class="docutils literal">trang</tt> at the RelaxNG web site and here: +<a class="reference external" href="https://github.com/relaxng/jing-trang">https://github.com/relaxng/jing-trang</a></p> +</div> <div class="section" id="acknowledgments"> -<h1><a class="toc-backref" href="#id96">19 Acknowledgments</a></h1> +<h1><a class="toc-backref" href="#id96">20 Acknowledgments</a></h1> <p>Many thanks to those who have used <tt class="docutils literal">generateDS.py</tt> and have contributed their comments and suggestions. These comments have been valuable both in teaching me about things I needed to know in @@ -3178,7 +3226,7 @@ following among others:</p> </ul> </div> <div class="section" id="see-also"> -<h1><a class="toc-backref" href="#id97">20 See also</a></h1> +<h1><a class="toc-backref" href="#id97">21 See also</a></h1> <p><a class="reference external" href="http://www.python.org">Python</a>: The Python home page.</p> <p><a class="reference external" href="http://www.davekuhlman.org">Dave's Page</a>: My home page, which contains more Python stuff.</p> <!-- vim:ft=rst: --> @@ -3187,7 +3235,7 @@ following among others:</p> <div class="footer"> <hr class="footer" /> <a class="reference external" href="generateDS.txt">View document source</a>. -Generated on: 2017-03-21 19:50 UTC. +Generated on: 2017-04-28 21:54 UTC. Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source. </div> diff --git a/generateDS.py b/generateDS.py index c26a271..693cef9 100755 --- a/generateDS.py +++ b/generateDS.py @@ -56,10 +56,19 @@ Options: generated files. This is useful if you want to minimize the amount of (no-operation) changes to the generated python code. - --no-process-includes Do not process included XML schema files. By - default, generateDS.py will insert content - from files referenced by <include ... /> - elements into the XML schema to be processed. + --no-process-includes Do not use process_includes.py to pre-process + included XML schema files. By default, + generateDS.py will insert content from files + referenced by xs:include and xs:import elements + into the XML schema to be processed and perform + several other pre-procesing tasks. You likely do + not want to use this option; its use has been + reported to result in errors in generated modules. + Consider using --no-collect-includes and/or + --no-redefine-groups instead. + --no-collect-includes Do not (recursively) collect and insert schemas + referenced by xs:include and xs:import elements. + --no-redefine-groups Do not pre-process and redefine group definitions. --silence Normally, the code generated with generateDS echoes the information being parsed. To prevent the echo from occurring, use the --silence switch. @@ -204,7 +213,7 @@ logging.disable(logging.INFO) # Do not modify the following VERSION comments. # Used by updateversion.py. ##VERSION## -VERSION = '2.25a' +VERSION = '2.26a' ##VERSION## if sys.version_info.major == 2: @@ -508,6 +517,7 @@ def set_type_constants(nameSpace): # For debugging. # + # Print only if DEBUG is true. DEBUG = 0 @@ -6681,9 +6691,18 @@ def is_builtin_simple_type(type_val): def parseAndGenerate( - outfileName, subclassFilename, prefix, - xschemaFileName, behaviorFilename, catalogFilename, - processIncludes, options, args, superModule='???'): + outfileName, + subclassFilename, + prefix, + xschemaFileName, + behaviorFilename, + catalogFilename, + processIncludes, + options, + noCollectIncludes, + noRedefineGroups, + args, + superModule='???'): global DelayedElements, DelayedElements_subclass, \ AlreadyGenerated, SaxDelayedElements, \ AlreadyGenerated_subclass, UserMethodsPath, UserMethodsModule, \ @@ -6718,7 +6737,10 @@ def parseAndGenerate( infile, outfile, inpath=xschemaFileName, catalogpath=catalogFilename, - fixtypenames=FixTypeNames) + fixtypenames=FixTypeNames, + no_collect_includes=noCollectIncludes, + no_redefine_groups=noRedefineGroups, + ) outfile.seek(0) infile = outfile SchemaLxmlTree = doc.getroot() @@ -6963,6 +6985,7 @@ def main(): 'module-suffix=', 'use-old-simpletype-validators', 'preserve-cdata-tags', 'cleanup-name-list=', 'no-warnings', + 'no-collect-includes', 'no-redefine-groups', ]) except getopt.GetoptError: usage() @@ -6981,6 +7004,8 @@ def main(): showVersion = False xschemaFileName = None catalogFilename = None + noCollectIncludes = False + noRedefineGroups = False for option in options: if option[0] == '--session': sessionFilename = option[1] @@ -7149,6 +7174,10 @@ def main(): CleanupNameList = capture_cleanup_name_list(option[1]) elif option[0] == '--no-warnings': NoWarnings = True + elif option[0] == '--no-collect-includes': + noCollectIncludes = True + elif option[0] == '--no-redefine-groups': + noRedefineGroups = True if showVersion: print('generateDS.py version %s' % VERSION) sys.exit(0) @@ -7169,9 +7198,18 @@ def main(): TEMPLATE_SUBCLASS_FOOTER = fixSilence(TEMPLATE_SUBCLASS_FOOTER, silent) load_config() parseAndGenerate( - outFilename, subclassFilename, prefix, - xschemaFileName, behaviorFilename, catalogFilename, - processIncludes, options, args, superModule=superModule) + outFilename, + subclassFilename, + prefix, + xschemaFileName, + behaviorFilename, + catalogFilename, + processIncludes, + options, + noCollectIncludes, + noRedefineGroups, + args, + superModule=superModule) if __name__ == '__main__': diff --git a/generateDS.txt b/generateDS.txt index f07e88d..bd38a49 100644 --- a/generateDS.txt +++ b/generateDS.txt @@ -12,7 +12,7 @@ generateDS -- Generate Data Structures from XML Schema .. version -:revision: 2.25a +:revision: 2.26a .. version @@ -278,10 +278,19 @@ Here is the usage message displayed by ``generateDS.py``:: generated files. This is useful if you want to minimize the amount of (no-operation) changes to the generated python code. - --no-process-includes Do not process included XML schema files. By - default, generateDS.py will insert content - from files referenced by <include ... /> - elements into the XML schema to be processed. + --no-process-includes Do not use process_includes.py to pre-process + included XML schema files. By default, + generateDS.py will insert content from files + referenced by xs:include and xs:import elements + into the XML schema to be processed and perform + several other pre-procesing tasks. You likely do + not want to use this option; its use has been + reported to result in errors in generated modules. + Consider using --no-collect-includes and/or + --no-redefine-groups instead. + --no-collect-includes Do not (recursively) collect and insert schemas + referenced by xs:include and xs:import elements. + --no-redefine-groups Do not pre-process and redefine group definitions. --silence Normally, the code generated with generateDS echoes the information being parsed. To prevent the echo from occurring, use the --silence switch. @@ -511,15 +520,32 @@ no-versions changes to the generated python code. no-process-includes - Do not process included XML Schema files. By default, - generateDS.py will insert content from files referenced by - ``<include ... />`` elements into the XML Schema to be processed. - See section `Include file processing`_. Note that include - processing, which is performed in ``process_includes.py`` is - required for generating validator bodies from the XML schema, - because the Lxml ElementTree produced in ``process_includes.py`` - is needed to generate the validator code. So, using this option - also turns off automatic generation of validator code. + Do not use ``process_includes.py`` to pre-process included XML + Schema files. By default, generateDS.py will insert content + from files referenced by ``xs:include`` and ``xs:import`` + elements into the XML Schema to be processed. See section + `Include file processing`_. Note that include processing, which + is performed in ``process_includes.py`` is required for + generating validator bodies from the XML schema, because the + Lxml ElementTree produced in ``process_includes.py`` is needed + to generate the validator code. So, using this option also + turns off automatic generation of validator code. Also note + that process_includes(.py) performs additional tasks; it also + (1) assigns names to each anonymous complexType, (2) processes + (replaces) group definitions, and (3) possibly fixes complexType + names (see command line option --fix-type-names). You likely do + not want to use this option; its use has been reported to result + in errors in generated modules. Consider using + --no-collect-includes and/or --no-redefine-groups instead. + +no-collect-includes + Do not (recursively) collect and insert schemas referenced by + ``xs:include`` and ``xs:import`` elements. This task is + performed in ``process_includes.py``. + +no-redefine-groups + Do not pre-process and redefine group definitions. This task is + performed in ``process_includes.py``. silence Normally, the code generated with generateDS echoes the @@ -3057,45 +3083,25 @@ And, then, try it on your XML Schema, and let me know about what does not work. -Large documents ---------------- - -**Warning** -- This section describes an optional generated SAX -parser which, I believe, is currently broken for all but the -simplest schemas. Generation of a SAX parser has not been updated -for the latest changes to ``generateDS.py``. In particular, when -names of elements are reused (in different parent elements), the -SAX parser becomes confused. Until I've been able to figure out -how to fix this, you are advised not to use the SAX parser. - -``generateDS.py`` generates two kinds of parsers: one kind is -based on SAX and the other is build on minidom. See the generated -functions saxParse, parse(), and parseString(). Using the SAX -parser instead of the minidom parser should reduce memory -requirements for large documents, since the minidom parser, but -not the SAX parser, constructs a DOM tree for the entire document -in memory. - -However, both styles of parsers construct instances of the data -structures generated by ``generateDS.py``. This means that, even -when the SAX parser is used, ``generateDS.py`` may not be -well-suited for applications that read large XML documents, -although what "large" means depends on your hardware. Notice that -the minidom parsing functions (parse() and parseString()) -over-write the variable doc so as to enable Python to reclaim the -space occupied by the DOM tree, which may help alleviate the -memory problem to some extent when the minidom parser is used. - - -Includes -- The XML schema include element -========================================== +Includes -- The XML schema xs:include and xs:import elements +============================================================== While ``generateDS.py`` itself does not process XML Schema ``include`` elements, the distribution provides a script -``process_includes.py`` that can be used as a preprocessor. This -script scans your XML Schema document and, recursively, documents -that are included looking for ``include`` elements; it inserts all -content into a single document, which it writes out. +``process_includes.py`` that can be used as a preprocessor. +``process_includes.py`` is called automatically and by default by +``generateDS.py``. This behavior can be turned off with the +``--no-process-includes`` command line option. **However**, doing +so is not advised, because unexpected and undesirable behavior has +been detected this is done. Instead consider using the +``--no-collect-includes`` and ``--no-redefine-groups`` command line +options to selectively turn of specific processing done in +``process_includes.py``. + +The ``process_includes.py`` script scans your XML Schema document +and, recursively, documents that are included looking for +``include`` elements; it inserts all content into a single document, +which it writes out. Here are samples of how you might use ``process_includes.py``, if your schema contains ``include`` elements. @@ -3115,6 +3121,47 @@ For help and usage information, run the following:: $ python process_includes.py --help +Processing RelaxNG schemas +============================ + +RelaxNG is a schema definition language and is an alternative to XML +Schema. For more information on RelaxNG, see: http://relaxng.org/. + +``generateDS.py`` does not understand or process RelaxNG schemas. +However, the ``trang`` application is able to convert RelaxNG into +XML Schemas. I've tried it, and was able to convert a relatively +small RelaxNG schema into an XML Schema, and then use +``generateDS.py`` to generate a bindings module from that. I have +not done any serious testing to determine how complete or accurate +this conversion is. ``trang`` is written in Java, so you will need +Java and the JDK installed in order to compile and use it. For what +it's worth, here are the steps I followed in order to use ``trang``: + +1. Clone trang from https://github.com/relaxng/jing-trang.git, + and, then built it with:: + + $ git clone https://github.com/relaxng/jing-trang.git + $ cd jing-trang + # set JAVA_HOME to location of JDK + $ export JAVA_HOME=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt + $ ./ant + +2. Run ``trang`` with the following:: + + $ cd jing-trang/build + $ java -jar trang.jar -I rng -O xsd test01.rng test01.xsd + + The above command produced test01.xsd. + +3. Run the resulting XML Schema (``test01.xsd``, in the above case) + through ``generateDS.py``: + + $ generateDS.py -o test01sup.py -s test01sub.py test01.xsd + +You can learn more about ``trang`` at the RelaxNG web site and here: +https://github.com/relaxng/jing-trang + + Acknowledgments ================= diff --git a/generateds_gui_notes.html b/generateds_gui_notes.html index fd42cbb..58e6b4e 100644 --- a/generateds_gui_notes.html +++ b/generateds_gui_notes.html @@ -220,7 +220,7 @@ They are used by updateversion.py. --> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.25a</td> +<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.26a</td> </tr> </tbody> </table> @@ -229,7 +229,7 @@ They are used by updateversion.py. --> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">date:</th><td class="field-body">March 21, 2017</td> +<tr class="field"><th class="field-name">date:</th><td class="field-body">April 28, 2017</td> </tr> </tbody> </table> @@ -401,7 +401,7 @@ $ mv generateds_gui.mo locale/ru/LC_MESSAGES/ <div class="footer"> <hr class="footer" /> <a class="reference external" href="generateds_gui_notes.txt">View document source</a>. -Generated on: 2017-03-21 19:50 UTC. +Generated on: 2017-04-28 21:54 UTC. Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source. </div> diff --git a/generateds_gui_notes.txt b/generateds_gui_notes.txt index ca2d1d2..49d17c2 100644 --- a/generateds_gui_notes.txt +++ b/generateds_gui_notes.txt @@ -12,7 +12,7 @@ GenerateDS GUI Notes .. version -:revision: 2.25a +:revision: 2.26a .. version diff --git a/gui/generateds_gui.py b/gui/generateds_gui.py index d5cf4cd..5a7e6a4 100755 --- a/gui/generateds_gui.py +++ b/gui/generateds_gui.py @@ -41,7 +41,7 @@ from libgenerateDS.gui import generateds_gui_session # Do not modify the following VERSION comments. # Used by updateversion.py. ##VERSION## -VERSION = '2.25a' +VERSION = '2.26a' ##VERSION## diff --git a/librarytemplate_howto.html b/librarytemplate_howto.html index 1790efe..b5fa212 100644 --- a/librarytemplate_howto.html +++ b/librarytemplate_howto.html @@ -217,7 +217,7 @@ dkuhlman (at) davekuhlman (dot) org <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.25a</td> +<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.26a</td> </tr> </tbody> </table> @@ -226,7 +226,7 @@ dkuhlman (at) davekuhlman (dot) org <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">date:</th><td class="field-body">March 21, 2017</td> +<tr class="field"><th class="field-name">date:</th><td class="field-body">April 28, 2017</td> </tr> </tbody> </table> @@ -380,7 +380,7 @@ this command for your needs. For example, you may need to use <div class="footer"> <hr class="footer" /> <a class="reference external" href="librarytemplate_howto.txt">View document source</a>. -Generated on: 2017-03-21 19:50 UTC. +Generated on: 2017-04-28 21:54 UTC. Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source. </div> diff --git a/librarytemplate_howto.txt b/librarytemplate_howto.txt index a2a52cb..28383c0 100644 --- a/librarytemplate_howto.txt +++ b/librarytemplate_howto.txt @@ -8,7 +8,7 @@ How to package a generateDS.py generated library .. version -:revision: 2.25a +:revision: 2.26a .. version diff --git a/process_includes.py b/process_includes.py index bbdc026..17539a0 100755 --- a/process_includes.py +++ b/process_includes.py @@ -40,7 +40,7 @@ except ImportError: # Do not modify the following VERSION comments. # Used by updateversion.py. ##VERSION## -VERSION = '2.25a' +VERSION = '2.26a' ##VERSION## CatalogDict = {} @@ -73,12 +73,17 @@ def load_catalog(catalogpath): def process_include_files( - infile, outfile, inpath='', catalogpath=None, - fixtypenames=None): + infile, outfile, inpath='', + catalogpath=None, + fixtypenames=None, + no_collect_includes=False, + no_redefine_groups=False): load_catalog(catalogpath) options = Values({ 'force': False, 'fixtypenames': fixtypenames, + 'no_collect_includes': no_collect_includes, + 'no_redefine_groups': no_redefine_groups, }) doc = prep_schema_doc(infile, outfile, inpath, options) return doc @@ -301,12 +306,16 @@ def prep_schema_doc(infile, outfile, inpath, options): params.parent_url = infile params.base_url = os.path.split(inpath)[0] inserts = [] - collect_inserts(root1, params, inserts, options) - root2 = copy.copy(root1) - clear_includes_and_imports(root2) - for insert_node in inserts: - root2.append(insert_node) - process_groups(root2) + if not options.no_collect_includes: + collect_inserts(root1, params, inserts, options) + root2 = copy.copy(root1) + clear_includes_and_imports(root2) + for insert_node in inserts: + root2.append(insert_node) + else: + root2 = root1 + if not options.no_redefine_groups: + process_groups(root2) raise_anon_complextypes(root2) fix_type_names(root2, options) doc2 = etree.ElementTree(root2) @@ -600,6 +609,15 @@ def main(): "--fix-type-names", action="store", dest="fixtypenames", default=None, help="Fix up (replace) complex type names.") + parser.add_option( + "--no-collect-includes", action="store_true", + dest="no_collect_includes", default=False, + help="do not process and insert schemas referenced by " + "xs:include and xs:import elements") + parser.add_option( + "--no-redefine-groups", action="store_true", + dest="no_redefine_groups", default=False, + help="do not pre-process and redefine xs:group elements") (options, args) = parser.parse_args() if len(args) == 2: inpath = args[0] diff --git a/setup.py b/setup.py index adfdbd1..6be7d96 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup(name="generateDS", # Do not modify the following VERSION comments. # Used by updateversion.py. ##VERSION## - version="2.25a", + version="2.26a", ##VERSION## author="Dave Kuhlman", author_email="dkuhlman@davekuhlman.org", diff --git a/tutorial/generateds_tutorial.html b/tutorial/generateds_tutorial.html index fc814ab..1aa0341 100644 --- a/tutorial/generateds_tutorial.html +++ b/tutorial/generateds_tutorial.html @@ -219,7 +219,7 @@ They are used by updateversion.py. --> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.25a</td> +<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.26a</td> </tr> </tbody> </table> @@ -228,7 +228,7 @@ They are used by updateversion.py. --> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">date:</th><td class="field-body">March 21, 2017</td> +<tr class="field"><th class="field-name">date:</th><td class="field-body">April 28, 2017</td> </tr> </tbody> </table> @@ -1210,7 +1210,7 @@ named <tt class="docutils literal">garden_api.py</tt>, you can create an instanc <div class="footer"> <hr class="footer" /> <a class="reference external" href="generateds_tutorial.txt">View document source</a>. -Generated on: 2017-03-21 19:50 UTC. +Generated on: 2017-04-28 21:54 UTC. Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source. </div> diff --git a/tutorial/generateds_tutorial.txt b/tutorial/generateds_tutorial.txt index 579236f..ec5b5db 100644 --- a/tutorial/generateds_tutorial.txt +++ b/tutorial/generateds_tutorial.txt @@ -11,7 +11,7 @@ generateDS -- Introduction and Tutorial .. version -:revision: 2.25a +:revision: 2.26a .. version diff --git a/tutorial/generateds_tutorial.zip b/tutorial/generateds_tutorial.zip index d8a4a2e108e95ab0d368063584e83ff7d400323a..5ac7b6ccf4e3a8b441ef4d6e00a77c913ecfe37a 100644 GIT binary patch delta 12816 zcmV+rGVjfS{Q`mg0v%9G0|XQR000O8(srCm`VO3<TLJ(84g~-J7XTcSk+~Xw2>=5e zx&v7zx&v8tcnbgl1n2_*00ig*005m+J#X7E5Z(1FZV3<rF&!8|2LV}HFF_NaKr^&c zO_L{!D8&;<Dvp5s_})=gJ~VU)7g5K%$9L}@Z*M=dsv`!BI^*sqtk-ZCawI#L>?nW^ z79NL8(P>|O3jMaKYCYtZVhuZg{e<v+Xnm&xN3D&RQVsU+6oN~gS715mHDHM&6pt0~ zYIE-E&E|AEsdq_Ajw_{LM-V7ON7gkX<QAbJ@9E^i5uPw6>BmslVaQ1d;A4v;=!h^R zv~U<<=q<}|&Q<-W3hw!z`-u4DWLv{lZNKQnsnpi+BA=IXG;N{8Yq<D-3K#YYE`C>> zYp5TiJGQxoZ}S!|%?h^H*Eb(@QcTk&uw({du4ODm4H=CznW)Jp>B42Om`rpBOu!|E znA_ACcM1=8k8tk{hJ^J}PU<;KLo_IAZv2#%Hl54s^N*4_9#W3lFzFAR<T4(XTN)>y zjRTnqQ<k}0ObzV!Z>D2^q4#?@wa&CKM-%)Q*)u`J)4;bf?7(h;%Z6eB!Drp|9<RW7 zotO(YE;zY5t)Pk238P;R_mE7Boqpx2%Gl3Dmf#V4{zykc7d;lQaAPyrj51Z9#V!g< z!P|8T?lNef=v_m-j)}d(nR=@Cr0o(|L=>?o;gTI=G7oD@lUI{}1t1~AGCVZSBTt+S z!ZNVo({L!lh-4`b2UdlrM7<Pi@5fR<le4Nggy$2%=yD5m$SiD{XZH?|<)CPB8Ur8q zkqp1%k|qp_W<29XYtv&&XmS|3da__`vCnM{H&wNkRZ?b*|K+$~{9xr-z4nm)%zo1< zKj*6Y2T)4`1QY-a000O8*LIvr&mg$JlfD8ee<r#ESxPDXSao;{009K(0{{R7=mP)% z)I4i*+s1a^@hi4W?~QbaAVtY`Y+0tqwbR5?C-F3L@6B{No+Ysqw*s&T7SJQ@{qH@G zU0?x%6sb5fy`GUo61!*5p7)Esczu_p;zpHLoBY*iHaQsyl`l=A^Q%{*x?080N8<H7 zf4camcR#(o{N>}fVqL+8kDvbK!~3^l6i=srJ$pNyzPo%U{`URl4<7_T5SOLQt*!u~ zOsCUte;kR?x~huv>GbyYc5-_*G3C|t^53U-2y2F$-OIQNc21Hi8NtbPAYhr>R|8;X zFJ8Rh-6LFdo=QYq<s;F&LKsRW@F!E1e-sEKR=?Kz=GEw}$t#st@#TG?Mq<hDUX3bs zS4|P-OR-$b(yHo}BgNE1$z`TqjjmL#N?DmQ*!<2c>q@6qoJ?kClT&#v9M*|@FtMgC zmudy*t4Xe^DTA$am8!XesNVf7;#j=TtI{O(5-B2No`}mD4%0HdnDX)tHnOhPe_d4M zjS~M>uhUHCe2A^?Qza_6uDj*ZS|Cs~{fmHC;xE%ETA1Ws{7)pr3c#F;7bkxbUw^2V zI+5Z#U{9jH9*h4_Wg>Gq7T*E7H}IDijKv#7ZY;i6>5Z!N5<aoO(b%d|uU-Pog<M`= zm8Q;<bMe)R{^7?<lbZ5eEK+!kfA2F{Ug`W?oT?1p7BWGBbnpKjMe;w_rCR+Lq3QO1 z_2lf?i*KHF4~gAFlB+_NKo#CUsmwCQbpVE-ATi=ZEe#MKh<z?{lPg-go{8|dEel&b zR?Efg<YZqwEHF5~YUmx`Dt)yEvM)@U&=Q^TQ%@3xY|2EH^ahp`-361Ue<~9vVurtQ zajJ6_uN~YOKE+*yki+)@bXAFa+^X{%4JxUUkl00C7OC3njtD`50D~k307{kYwOgLA z4Opk$EGmR2Qb3mu#fXh#u|9>LGx&J|KTqN3Sx16SPR``B#U6Nh-2gs+N#*FU*vWic znZohZOJgG|R{y2|iDxH&e`<Hf3sY4lYqofrG@s9kJ7G<#lU7py9<5I|pgwslR4FBa zJlg<ywj1PbNnAhKfHz}!gL<=my0QFZ*Yaom<<EDlj_OnZ_e{E%4n;||UBBVk78s2I zN?7%V)OdrKGbbjg0!PC8wwT<;rna&L9x3bF8u&O$(#g=H0ER!-f3I{mzST*!J{OMf ztJFw9Jyok}o3z6_Z@>6=BNsB&SFpIm>$6?Vi@FN@)ECypzDL@$2)ApniuefZ6GBKm zj+su9lvyVii*hXF5^Vf^HWm|gSEN$sq1D-OLf>2bI)>F|dHri`Dzv8X5kzWgEQ(UK z61I|=PVWH?lN;E*e^f7fdN6TbHPIHZxj$#1U4EVvccGsN)cg6_^V##WVT8X@s^bbz z*bkxw2j<_N3y4rmhxf$gMtbzkL?(bYMSx>L?<)*tnzu`U(7XZ8Ua68_tFkoZm_V#` zUh#)ID@<8Q|27A*@vBM~{Nh%Yxz4*D7RV#Q%V#RlbtX(*e?cH9`f@Ke5En)8CZ;%z z4@1O;9!4Epw{A!Dw{C|U4LlpRJK|+uR$AF_uH)&x6&=Tltr#(Pwr(eeZQbnovgJx` z6w%)0kQ-Lj#7E;j8`+3*LjRn#pP=A^D_%NFY(beYl8!NwW>bw|FQ)V<#Mx7qabPeF zf8a`DnMw;Oe+-_R0cl4<CrtvO5*zCv){nt_#g&WoDS?^!{X~S({&~WBhPj1Y0OeW? zbiOhpu_`HTxG_2ziLy==JjAQufk1}d`WTZ8&LRdLx}3wMGL%EykUa#9O@R=ra(+>* z2Z7GtQ08(DS<M<(Ci5_Jflre;{3;&;k|d?FHh^-0e}>VmmHZSiNv;{LIFi+|NZ_RA zgT%lmke5Xl((i-c6$si&ff-&Z0lr9;ke!YMrUadgG=PMu>1e+F*~L_%kN|r4r@h{^ zaso3Yj$z&n+<j+2!YVN6iC*1{YOO%DQ?RF~ATD(WjmS`{>?FEet9t=XL(~@3V{tF) zA^|~he+wtY{RAY&LH4`pgT9ckdaSfclNd#QZ-L=0gW|%E@RB<vrL%k#vOIu2FBPUH z5GxVKf#CzE%ugq$&m_?}+DYVpY*HYHcaq^vQR-BjJ|BzIli4>9(BmKO`b$&XQ)sx8 z25<c;akM-JI-EQap`DqC%eA(`8)yo{BQ&O{e{t5Vs$0}5U5P~5WvLg+3Ru3x=!O*y zG*A5S{!)C<OO;!79$1mR42UUU8`XxWw3RX#JI!<zyEh%9vd4NfG?Nau_a&)ZScpHD zyD8cs7*Yd_sP6kB@5e-Ch?HQLBC`?~Rka~vDTLG|dc4-Xfx!X{syW8n%eC+itoV2j ze?B7z`&~%^sKS9Y7<h362}q>wWL99LK?eZCR+?i7dkms$GQ{(5KYS2&xmKBMZZHwZ zLqM+&v{YcKE#46?pi)J)7Ov_6c?gl04H5`k+#WL#?;+VstqCqsV0E#yuu@hL<VQ&# zAd(ZwW~}O872v`75Q$Pm9Kj<6-~cRWe=4dkcx1>m&`H>OL4-i^*s5Lt6@XW!;6iJ9 zA2ngfgoGG41X3aiI)uM)dSX5I0$6Z;3XvmtRFq~3?v<9fSO88~^{+E|!1AoizD%%n z2m+`EI@k!k<S@#AhBl*UA|-t8g2t6D!EDW4z1M>4g_U(<jGFMyYLpuUlj`}9fBFJD zI_mpXDDI4mPG+O|?9cha7B9o!VUUJ;c>x-Gz(I~jR1;dO7&AYA-YK}b&GWu%HaM;% z>Ji7*)}Po237rk(ib;AYR)xeCvKM$6-(_jsjd68yHkzMp;`hmV)EdZyBuW}VChNhF z`*QS%i&&E()v^rnrD6&zfQ|1>e;sG&7vfvUzwlz$xw-YoKN-!RY$E?NKobrcm1dke zSpm=lK@$iKFN4q?fiTg$l*O8g3t+YYH<c$IucxE=(@nfkeVa|9+4P9xUHwrO1^5zj zhOsTwQm;U%7HTbTH1--8muI8-vrSyy5Cky<L3jv+*rp;Lq=BfiC=`h9f3mif$>P>Z zc@)0^6emMk8SECkJFszINMU55k%1YCS{ahmWA_}f8_?k)9r-iXe_p=%_?};|LqotJ zr60p^)Q$y+GU5yNTrSrhy%&hyfC|46ev9y1f`g}ZioXxjQWOvncdM&fvU;Mv)&VDH zC!_f{0~*OYMZ1&iNA0=zfBS@t$dB#>5`IY469utXf~`a6_<&6feqjE;84|Vc7{*xi zfru8!7eLiks)%Qe^pPk6k5Cs|8lDo4Ls<R{+r<p43LXN<pNH@m%Zmt|#$Zr}tx4$0 zW@n7pfG!YXr-&GaC4*Mwkv@(PJd1Bj2tQ*PLts|LNvR>QkJqxyf3a-f(R;$^4d?=) zcZTQ@93ch5nKB&V;5-(&CvjQl#7RPKz=F)4GG;@*3Nd?vm;n%CCIZ=FEkdPzlmerh z#Y$&OGw=@2w|G!m_yuHsxz=d{&teMo!GhiDY8_|t&McR8X~B;w5abdl2qDU>!3><j z^C2C0>%a*IP9Qh|f8c&1aKeGZuss*EM=*65UyeTG96}s#Yg#HkM_dQgVi;EjB^)TS zIFAuNk~p+hW`)6>%Y0%R<6Hz}hd|P%^5^h;fp`w+2Sz3c%4G!()Yn!tpnT%+7<z)a zr^LvV>@WavT_Sa5omTOUOzW1ErzeQwfTFw&pa_@w>ryx<e}bXx))h!p_Df@|3R8wK ziJ)?CaP44Jp^bU=&M~O|Tg)$b&;X01ZoWof>9owa+lZBGdhRnLNBbt3atYM?6~(tj z3LJ#U_STfwK%~;tS8MnSNu^Kr#~cUCdq};2kh&6Ul@_Zy#bhxx=2}QjrY&XaF7Sse zSjZ*B6ot&Sf3jVWke&Zx>Im~v4^y)_OEh4w7u=7a-s?HvBdGtn(n3tlE}*f8I&ELQ z1stYrS+)_tJ`n&5(O@A52`c2m)YZW?jy1@)L%r?vG5-!LCH3mf)8H(cmD*98?yqGr zLX@UGoGy`FopKqKfUv@$^JQ8mV2lPhG;z=ZwSoH`e@Lml>OjKRfucj}KvV`In9*a( zKq4#yMg20+!D6waXe6*`6g{?RB-)};bZF5?3>1x`{fkCoOVKDAEE*L~;KDq}F`g`k z!`q(sD?6Qn&YO*TpdcxMw8e9?@uE&}TfRjBI^HzA0Sl+O%IV^~Rh@I?lbD0#Sh!9M zk^;jne}Ecw3mzSS%v|1ntJ4&OZlEg2#ZU`MXIE?}3Dw96GRZct!6y#pt+ainxhG4C zXDn5_3scl7$r(hjrBbc%pyvh}R}zd5756%MY2^9Aj1DgKgA)dz6p@;l0Q7LR9R%ay zQY#jF?f4vTbi|^xTW1&$Da$cC?qT5YvGlv5e@2^qialsaghL?O1A!0xmhqVMEZny; zC||p3dLy^puHJ)E+{P(R)5Ou|&nVKLKOc`>u&S~JaP~%mYg?o$B7v8w{tYb00B>jy zR{rfn)~Wh@cmJESOZfwQvEk}Q)flzNqvi@4u+9}UOgR>srK@)fv_N5)yPGK&7QzVs ze;9Z@nl};rD?X~u7ufVy3BQFX2zJZ~-Em{X9z&Y(Zp=cujCVr?YZ@$lkm4Xqs%(LS zvpM<^{PnqTksCH&kgx|5F2)K>Y|<o#TVm92=}(tn05_*Y$Zo;H4hbVBVXChmI2|_r z?GOp`izmmS9o@NWQA5teCpi5XGS}V`e{xsLnGiO6E}-BTLgeUzI12cd-N+>xPLTHx zI9`udG_>*g-o~th9Z{8Q3mv0&ghZ10y~x46fE@;B8#iY9m~9?8ceD6!NIC>~0rVv} zR(CK~p@lmLxrmVydm!h`usa!|55#oCoOWXYA7FG^U*My1zyOat?mPadu|{O>e;Z%G zVJxklpw5KR3j+regaR^-NZhLpC%Wk(!$=ArqC+>Uh}NU;8Q4&$(rr0*ZE2OG0kpn@ zit$r~34rfUw`Y*OVuMEh`&Opc&aygv9E&hG=H}zJ2A&Us@b3NYU>KH0+^ivlGRT%S zW_2CPSr?Ji*x3<S?4%B@$ueL^e|u$Gi%8W#%CI;uv6_M20I*8*in5@lbPB<X$$dhp zy1^1w9fBCL)3SE?a+k1&2k3BVBr`#Y7>dh^El%D*a_Fe-qISDBw*r5vmV#kGOVo7F zkzTZEBWf(#io>?b!cf<6zXHR7O~qcFft*fLRUo->nLdjG4<{*zcX(DQf2WiHh_{pU z-Bg`vpXgFyBy``f_>)z=DJh~dmmnUl4E(d`a9G4K?rZ7-#r*x(VC!Hjh!8X8P;t?m zGq$LMq2dlsA*=Ny0=tu&ic2UUDRm0zg#qp1F)rMmD-?POJK<`Xyr#JnxuhlnMtiJ` z3UEQI(NN}lRgwXdzCJjRfBbp^fk#NjRFS|PD2r`pvk_TubMU;t1bK^cqZ5~b`t|`h z1TW`rKE6LDLqr9FHZ|we3ji=;k6;+MZe`$lpJk!x1M5Ek9PtBwH@UM(z*f4i<}k^( zZm|}P6`dtzyg2F;w@$8~ic$&<#<h0xcW8{Y3d5;xb9t3Yl42kif5sp!9%$?#TZ*K; zZWD(?XtnxX<N}n|vc&RrsRn$dHLM_5s-yX4HnYI_C<C*LcK)%%ipgW_pcwfp@hzL( zFCat#5jNJ^c5RW)*k}-buUZ(xRQw6&*Ns>h@Y!ue6iA{oX6|5S_+^ygU}TBqsIg?L zz|WYx(};Tnb{%9+e-A;%B{UTpKglI!2&6QXk+FDJ-5M7K1sM94IV-BqRU)f+*o1`? zl7B#u;seT74&;CX^7{2_jArRFnHj)*4PhY8^>VuL2dDto>cDTPJi6-o?FR_cWO7S# zKF#DY8s&yIC<IoeE1sJBqp(km>jOki@ET|4%kUJ2HfH4ae@xcQcTCTqsRMam=_{&) z@vsm1S&K8I05W5zZqWy0WzmJPK*=V83!m*#z!(S}01NJR-?I`9jUWL-{<R%~d`!UO z@O*^@%ahr}y$wXz)81D!`y*V7d+aq+9a+;@B}6LN83sneN2pcN!FH|SuwmFLXK8?) z*`xon3C|hBe?f?UUEjBoNNumzLg0r;gj>}#)_Y`-7;3rT02=~D^_sq}!3H2~gLOBe zPq@t?%99)&VNwMdBasY62X<o&$_=R9nui7IqhnWr>lLTd6!G()Qi0}yato!p4%|L^ zPwRV!J34N1za0*jrCjLVH0DPHWm)PmY;8&m19kaNf6dC4t`Kyf_E71^m$nBA+EK4W z+o@!KvJUk<N+q7?SzG-kvTq(toe(fm5thA=c=s{aXmCSQo7lLL0~Ix(nj(pDHRrpf zDk^f>sC`1yxDnSlj`US-N~)^TR~hNMg2!W)a7IEU5hVzmf-F=Uo=7GGBx6?^Tc4eF zjSxQ@e^*tw(l^Wrfi)Is4OTJGlNi@CM*Cq_{fh<ptq(L^ve}SvZ!v8JFGPmEiw6fo zUK6!>4GRY$gZj61#)wg<ois#UAv@y6+h(K67j*VY+<({H?S2{lA2pWiN&!D&`2y+0 z!OqPFz$TKU3=x71<;DiQXNe$h=y(z`s2#qbf3Vd>VZ4WJ&XRdFXeAyH95VhhwEoWD zlG|?jY#jJ<9~ZxAl{fe@X*k>2I5VIaT;hnd9bTcrAG>*-j&nRb=-=TSXFXpQ=D9?w zKR5s#BiG(X%#{V?u45NV<yi1#igvQbChcj9g3%FI3)+~fjZW*Ka!+D{Tx$JDB6cEz ze=Zpx(B6ZG&G*yTFFA|uwDcD@rsEf65Hy2@w%0miSK#hN+6tQ;`BR#IqZm7)mMv`6 z73CW2YS^3F78fk@HD62Q?K+S86FzSsm>&aN*Z6C68dVHScpEb|QD(|5xA$LwJT%6} zZ|>X|hsn$XB}2pwEt!&ux30}shW<Z{fA%D4pF${+Ni{bh=@q_A=HG?mz(Kv9D>)Pm zYWhkXHE!uc4gxw&?xv*AJOnWbW&--t7!j53Ii6@718DO#ix*Zhw?Rd}%t>vh{@Apb zeIbg@41HMB^}w?u-)&ypw~?o_|3I09iDb7DY0)FmFO5QC>z-a<2_RPxYLU9Ye;St^ zVAjf$3|#3Wt=bxqjH69m$1wqob#-t@C8hq}vVvOLYoKw}h9#8B;^<EQn*=`K0m%%n z%$DC@n^^BMc5Xp4UofTE>}q-GpfM$I)Vn*{S=$b6iw|x*r|US5+5m%+Yi4%rn10;S z7Omhe{J7DVM>4rVN8Sn_`<nKye>i7Cjk!&1aM00}f`)J3sV%p-CG>6YsCQCZtRi8d zgA>iuL_INME)yHEb4u$#+K|7&SI8N)pq$ero0Ta7MwiA^e(u*zP53EbB%U9f@Pe>0 zEct1ZVwIxtfY4xaXV5Xi57tG&ES6I~->h&}hEGQnonE`GE;Ypmkss`Ge_Oz1s4~tB z<Q+$F(>PT(Dm`w-zjWS7E~C~e1eSpPqMzn_p9{5GftPf-6JC!a#UL?Y*7z2vKh1Ub zoDoBGn@3c&!=RE{pH2LT?;4zZiqv=~i4;G$d0Bx36!e8kaaH>saEJ_6>1+C;C|4kW zu|xB6eFG^(kNMFpx6EbLf6P>4FUwTa+iDswO@ib^kYfR|clH&2|NMUwy{uZ9^9exM zxCv}#o3Oe04)<Lix)2#Ur%!&Kv(sO`2FGC`EB743LHgF+fY}Cl@IBrOmCc)-7gKoG zANaxnOjL9XazJ}s)~O;l9L@cd8!BjPOHKl>iW8SuK;yz6j|?<ne^A7u#=&G2=TmV1 ztUGe&U35@cjfgIbW|))v?EY*So_^GX<-sWtoszqfz_q$RZjS8T91jml^>Szs60e_v z8S>-PR62Z5xfPhnI+f*k%kBYcQ8Bg+D{w$2WFq@JEFHTFTrd>s>=19>sZO7NAX?ye z&q$d9ltO#zA!5AYe`0}Fyxspi(aQ51dwp=s>dh+Y0P@uTe-_w!vu$wJNZM^PtmRvs za4M5s;!p+nw5&5H0(6QxRRN1LVWkzI>N+J3L`VC^vK9hV+_CweVbZ7c8)bajKaIoN zM{mc7_jnxfyawOfm($rYd$LiLh_V$>3D2x)l0KaJZEY^>f0f}q;#<8gk-PM*dKPL? z7znSZNVJ4d?i%h(!va{T-cz`ImG?b3Q8#_`f9+lAa~sF8|Gt04CMpMjf`g=_*kOuR z(G(@CLP;qRvYe7#s3oza)&X~!U4SIshy3kt`kHG`fRtWdDy*_a?lIHT(>v40uX`}! zW_X4hDqCBif0k@zZv_ICiL5bV%;q9G7ju6z%1zM-Py@*yXM!VKhQW^`LHo(lb&a4N zuvoOY#XX)4jR}eCl<`bJev4zQZW5iD7qiP1ICgAj&IKn<VPFcn;BgwAmE%(u4{&W{ z?U-XbR{U?sp91fekYFGdyJFr6tiKwr)6ABasx_Kof3@tc$PG=txj8l~oFM!N%B{9p zR^o;fEq>%uT4C`Uk1@1_<<ho;=PV(t2^u>=7NW3{grF*1i5+@h%RL0wOquqCu-OMG z*BpGD8;_a(fC9ZpbaOX%%J%QJgx#|kfJTztHzNo&3KV6A#HSe<K-~Y3V*kdcjSEe+ zV>|Tye*jv={V}@*?GHb<0Co)U-!5>el^y0XQzKkwDM4jPrMUuq#7b4y)*ZhTXpBEB z7*v+PHp)>PH1^S`-o{=rA5djnr8X6@xtaoqz+S5e+^5)rY94_xDQ2E1vM<+YyIDZV z$g}%7<3qd`K||aolR2n%)S%(6zb4mzP)1~Je}#9sS}XEuQB@E$fpIi@ds;E7(g|-z zPE91<-?Vl^?f^;Hqp=cgJZ>Af**;`qBsBna)lXMveF4FY>GEJd2-T1Jrb0<u>BEvc z)Me}r-exHjHdWeKmdYP_rj|E#Kc@@W2K<l<cIMv?e~WG+|0;J4KORxz8d8J`n}A`t ze@{aW{CHgt^ms3#^nA?$V(Ld}+`w6jFupQI8@As&74IFs%L`O*pdW{Al}Lnr9T7Q@ zib9wAR=db6ygIhY5CQ_9A^NL0aHlhPgn)#Ki4OGaLoXGx50~p_|0Y(1!`8_Yc#*G? zCI60Pk@<JEPSG!zk?lzX*23rKK#7bCe`(?z7LzPr^PkZrxU{rvT`7IRmn=%-#2vUn zdXS@aL*Y^I0DyKT+Z7m~+7N7LWikzgLz}33$<<2~Czc%E_C_P5WIz0-=!M@n6l%eO z2l|6y=m-q*z!4Zr0z84S?{ti(ZB|sL+a~peYVPp<^*ZGM1=q!~VsRLoL@;!1f2_AA z^{=y|+{aUtkSs@-tm30zz(y!PdjbI$x~ZRcT?0^xn>ZtdEtpS?$b_8UfGSxJ(Xpg< zILOU`AP9u-94t%}(v!w##{r~3JX05(Ed;qi7!9J{bao$i?pEm#4<*CO2VOqWt60ZJ zy}9R41AI4U;8ud2cv%vWz@Sq~f1w0)zeG^$LL<1`NQG_ZWOdqxHg7&6jEKu9TxhUc zjm(@_D6=TPWbKd>v+YdMezT{G*EdeG6;EBjNh&72)XtW(g~%d<Mo5{2GFdQGu}JOf zeZfzmld&yv@b2!849+fzgYxju_#JsP94GOzPYZuI=vS09xDMz!CHB%Mf4)oYvu#JV zL%}6{;X}-FwHI7xq}<B0PL-E?roX0DX|K27M+(yL50{GjyEQXNKq;P@{jSNDEvc^f zpp>&Q39rrJL44_ON!2C5hS12wBIZO?ID3R5s(yVAK!0(dlx!{ZTxWLfF;%g|Ms(4d z33;@=733{|BgE;#k-rKIf1)HlaB(tl(7NUx#Ob0m;oMVR>A=zy|6Z!sUDDq%VXVBM zRI2hFQ)&bVzb@og3yu#Utm`Cz@EpRl`k2|viUvKWGyudPY2~m_stQQ`dA5RW0KaDl z7GRAcMY+=q{3LVLOz)ey(nP{Oz7_s4+y%wM)n;{PqF7){2dq-fe-Dzm{RXPGkX6kJ zGApGP@ng}W*2TD3&Xu4H!<|78;8;KPqJ<KRWp5bv&f;aUhF_qB(ISa^zYZ)@?)^$s zfOKx{{*Y_%KxnV!71(&e9~Lsp_|f7>=o)edSU}UiOaJJH<UtJNs*5x-xH6GTy0Hnh z*4)8fO9#lXd$j+gf2Dn%hxQ)$Z~QXg?~ZC{Rf)uI%I3xu6j_a|$)|Km5b4xXiCbw+ z#DZ^;W>Qd{mkwsUn`*hbK97nRRsRA+uKq5<=3E~&E?f~Oh~;Vxy}=_n$QKtoiG$5L zNL4?ik91zq++|EB=XCK}z~${c7hKe`(VKBEFGk-Xe2BK%f54ceWmkqnQJZJOCqY(V z;DS9R$O((IZ5$I$dnK0y4Dd_2C7P%AKCX#}a7mP05zuXV8PE6+%)E!#1jM#ybwXkd zza%6bJQiDeDTGv?%C2&Rl2eH1!Sh2XiGi^VO5TXFtZe3yxW+ZNrJ@vT>b!d0!a`T8 zh*kTMIdo-?f9<eVL$#jEuWVQ{!m9&@9hNvQMML2{r}|Tgwo0p0ht<RcfH-uPF4j&Q zMHl%JM4?^ni%ecAI2H)B@-_=?yROA<au)?s@eNV0Jt$xY=I~sbx;0^!DpM6?1Pqsk z;t!aX4Z%aD{KJ`1m><v9%=YA3qWJ*i{<bQXVD8*#e}pD}*_e-{F0fgsaeZO|15OP- zvk+SJ?H;j9aH6dc6^Bu~Z|R%w=9Ya@(hbN=xn7W+Ld98TH2rl33n&zh2Joeg7VOa8 zleRTn@_4z*C3AsBOo@L)7?oZ+2%C);mmO6cqbD$XrS}7%ZsPr3i{Z5ESXSQlZZ$XR zg^$B$e>?Ui#5Q#4AfT~symU8zKQ06OWHPDt(~^E!UT+MxloEdgJGj|0V7W}$$C@nt z4-*r8G|np*bM#7W__n*;6#397Ote%XD}DoG)He}WJ}hI-wNN**QoCBJb=G8UXH^!f z-&u{-x^Z7s)~nxFtp!`xn{UaEHvS3dJNq&de|32B!}0s+SDL6Fj;E)8|4I{e^yA_C zlh?=FPn73!XiF$-I2WNCEN9DO69|seSYE2-ScGm4lKY>UATARELZZJRxkAXjAYCzC zkUVag!EjqC@L`q*enCJrjd-SQb{*%;An+e!R3KiiL3I*OG2p)=fMu$G30V!G$b!nA zf0w<_7G%3r)I!QtiK4DnXBVZ-)gR_@DS$Mx@$wC7Jrpot&iKhD8<(ZP6B(*;<5o#w z@QVXp9N{R|;C1c`f}f}zt8_-yxG)cZZV;R|aau6_yX8<x5hAF1VY;Yf-2pU0H_8RH zj1L}<-wZixo*_23RCNz$MG#pNQ-wC?e{wUdh=<W)0az!jx=eMsD9u3B?ts<qQV}mo zhH2KY(L+b$n&G$ranx1MhDGZ+)Uae+w5<H&9s1?D_NLwy`%I2{JT3O`B*<i?Bi=s2 zEX2K?o!!aLZ%$6}d26i=Xq8k=2~r>RVU8?=9Gx#mX5x`c?p?SEY7##%@tTFofAWj? z4xXrJ+I`tsxM6hhKUaWfw-)+(VlD4SnO0~FXWOCD-a8sOP&;^Q;4Ou2tuAp}su~{C z5lLvxrbJ0cw9NAELz7;t3D{_A9%x!Hb;-(GYao5nsX@rNddT*~wbstr?lasdQtZI1 z><@^!jB}s<tt2Lyw|C)5WnELse>%+aWLZr!9x}gCb9mr0mezOxan`({rOnp!YBjs2 z<C;KsdeW{t-Sadj)dk{8jPugfEUeNB+vYClYJ<Nh_KgJ2KpT>jtH4`@dkgnJeUnSW z`7iU$l74{K{jF~^FM-VyEB8&%xS}x^qWx%=F{1)IIbh@Z8l@50Pz}qce`r&w8mX)9 zX6FZQQ}3gwE%gx?oic{XQ~(I`^T=HUbJCLbT`2|5xSbPs8o#c#v&TAqWe;>T8Gmg~ zdDV(s_AR+Hv><641Rw?og5pR)%t@$o0E9#BgeBIiHhHw-K*l5nTp-Z`G=L_@UmQxf zI&f<@NFF?@vTTOdiEin%e+dIqY*~XI{cf@<@`+mUCUJVh-l`yY6g;Y4Y1AFO`AWx1 zrmHx7o85%rpTpf}`_G>4Km8U?(cZBvGG5;#dvI^O7mcAI%TF!8mliK44jqGWFbfYt zh~Nc3#rauQ#4~yoF29Tx%3SHIJxwXlSQ0IlyD0_&OP3c)A1ADFf9V!01kfcuFi;&} zsILEH5R@BA&T=s5n6_oUCZExx5V{~wIlyA!FTp>>Wa||4%dDCV({Ls6_>wa3JZ2b| zJGzVeTnm6}MWN`!+hgpRD?kJ>6-0ZDO&sTW#(pn77#h&IUB({=#W_WL<7a;~u6`P$ z?quw|<_>z(f%{X_f5wAGJ~(u#QCNc!#=!e^%qcO5nAC|!m3(Su(?hVT3%eRw){SFr zT&v_9aW4gD(88S>&NeMQ%?xZ2uZQGaSN=8f(5BbtS{KgMa?jyl7Y15Pv_{-P4j-DQ zoA9-fw=Jyg%3k=%qoj!K$GE?jQL>=Q7|goT2M^mn0OnITe-Q9o6N2GKOsiC%{H*^t z$}fvy`1tWZZs9i$Nh&V%>$zI96(Af~=<d<E8$B!_lBA*2Jc)>$1c2|_<l_;8ODL5u zr+09v@?jW{FULcxjS%!9td$vSkk?q>r%pc!Ex#&(ATb&rPmiz@JrIs}DrL?*M1?AS z4%s1H^*HMze~au)ZT_HD9CJm5<5cNnAQA^*FDlNHq(_f_P|Bh*kio6(<mT6v=72T{ zgrn3Dk>8@9o&Cn#gb29Q6H!;ktiwPBkQrPrED=sF@KJ>5-~&s9|H7R1v_0K(MG?d5 z2T=Acy6)?@3E<-j_D!_dRZjv`Nqu2JA_e6K{?eZmf8uZL!#hJX&j#f$0EafeLx|I! z8`_8WD&7z>KB?DWzTrhdA-U_DQq{_@7e49O^{&A&;ZzVSaAX|9k8hbv@Xt7p@ssQK zMi9cE^&FYuX9JRk7j*~R#3)Q;b9gRL2OsC%s|U%kTd)?f#tl`Y)5;W-AZpyc2QK3m zT{IcAf9S!;Jn6=}4ptGtIu2BkoA$Aa_@JKhIzHLpv-02^1X{&yZ(`~urFlZcRi^pB z$nqK3aXwlR9iuY~rwEQs`|l>)V%=2MO`}j{6GSjWLxx2`HQ;cY$*y8v#Vj?<keMCm z8AJr?WX+b*WgiX!V*=Elsx{r)G`gH!LzS&Of1Qo5qUHH#e0Z!L8;mdWY;|4q2cJf} z1i*m?kC-4dw0J@L92K~3NV7xe#u~Bxo-B{<v-T39{vMiF0&CCiCn?nJu$CU$vCM{U zJ)kLm3(kQ9coaSyxY9Q_r%q=?pJAN5K9G@`CzAqM;0|(%-0j)%pk5^x>OM?O*SoXd ze_+><SH>3+p2lNQuAUfUhLK05vVN%S9~%akM6_5yL0fd?KrL-ue-y5~c=u*(F;h>h zK{82NZd=GL#F*PJY0ssyDrbfEm)U{Lf#wp1L4ig!>$8JiZ%{=VOA2>ji^wVN;YtqZ z7f}*GC8R5_--*sBe^&~U+%zrySD^lre*~&tg7_T4|E@Lvx1#X~zuA&UlE2-@zoc3! z%I`L~GqIHWtnqEb5_(wpHUq}>YlKmxrcx%Ic=61j1nMXlm`;2#{cw8t>UcIi{&}kC z<FK>!|KLLrUB>$Ye0=`=Irx6zGfUD7mR7<=lwTz~3*Hx{lEAK}OHFQkmn{2$e{L<o zdBI2onNts`UvEC`?*A(Cta|UG4H^FKAl$X|A?lJI(^LWo8O+xmqk72K*EdfA2?^+y z$mkhba<dr_G@G#@_ej#K=4XF_|6#huG6xHV`rHPg`w>GB6o6!aRtsF-)%rRfA&aJ# zRqg*4zowwhST<2NHH1WcdY`#se}D#&ZA>Da#A3J692>JJ2FMv?WKgwHEDQy88YB>N zi+>URtc7>lHm}I9@EBnosft)9nI(PdJF-y#P-;0ckSB=jtnCzrw)6ljGfgE2==78* zEdWSYAW_YHa)(5z4x2|0pU_czqi6&Pz#}^7ee^lX)41pyp?^xT!-@=0e~cYIf!HC{ ztc@_Idcx<)b2m=p&;Y>j_!NF}gMcBtrjsqu^o3Y$AA#WmyLwi8guiQajl1+>VqHRF zRnHJAj`aybf!3)KCM#@vokBMGig;m#<^FHI<9`8VunwNrsvUCMw(G1+Fy@8)X{YY? z*P*mpL3nfes!~7rB{*HDf7x}B6eNhJTtC;sLU7>*&XV&^Pc;jzA7Ez9gY*WHjjFHA z+Tl0XLDZ<qD#+K;K+MN%DIYDm$Cj$ad3L?tVBdC+lmfN6d}I}t#*OovI6zDTYPNcL z?br=7pp@lEg<kD~@bjd&UPNoDL{xd&5pK_*UIg7T2JuUj1S78we^Q5Z#qw%MX@?Lt z$mf(uD0)HY=mmOTCtYKcZGD*qNO(CnvCHoMbd;}B1l{58?w1kku(dy<t-b1C9@yHS z!qzV51LB5VE*Ylrcjk<VI?$aIl=aY68zgE~t{Bcm2-}nnK#cW4hhEn%ib<`w*Q@21 zA*b8sg^$^bypBthe*o!ue0Qg|@T<wc=6p;}1<2UOa;xia*18HAcTyng(|b(6&JP)1 zJaw@%-g&m8el#RYP^f%A*GS&h@+}ss8B*hNwQy1bnR~-|#{ichNlWP#DZb%cc3#lP zWOYM*tT*ujV6pIyeaCr4gNrXAeG4A7uV@BM1lO($vp75Se|AZ2R(e~DIQ%%B{!NL) z$B!S!?~i}}d3^Nl&E#J%{`%p^lQ)NNJBY*I!;{yi)9~HP@aWy!>EY4z^h=1t`{Nhe ziNoRhljFC?n~B4TdSwG~n7%*!>G<UJ+gD#p95&ALrA3KOpM&EpZwoqc`wVkbM`W48 z20Ic2Uv?3ge*;%wUBmr<-hA??v+H!s>w|;h;4sS0X?%bB{rBJ1oB@aJ_=f^m`v~60 z%(x5>DVcL>dwLV62|)P`R1>s|b0}y4MaZx8QH_|<uhapx;;W6iNR%z#P!q9By=keC zFyg{?BY?MzuA;jPvl~WS#Bl^g97nrdlL^07OsayzVoP;7w~U_7rSM8dx&=L<3><}s zts{l3<8MR><20!D<DJ_J^m$1g4*VMP>~!^pmNS64S+10B4Kmo}EV$_W9FP9tx{wqK zhb>*sW`M7+TP^wODW#8cgy;&+80}h4eD^z(a4(yGpFzkf9CTAY3lIxI>Kc%}BGf&F z+>;|@KY;7uR@kiNjEbVT;<o83k=(_i1T6DaT)jAe>s5LM{12E+=W@IeY<Qn-5$dye z@Jxf;kdOqei6SUL?=EI;T?$<_HT;|{<^``R9>WmNhbI(;(c(5*BSC1|(fQGEBhiP1 zaoRzD-0?^YtF|pA%PSI+e8eY@jgaiFE70B!2uFp9cVu-Uhe#y3KHiKvapd9<(qj}K zltIp^5?&!*tou}|-Ha(2fwXHHpjxLnDl(@0C{-shxj=Bhn<UKX`XeX@=2Wb+HF^qU z7q?3T%kddjw~~$g(v*Q7(vc}pca<|pTr<{xY>xl05|6JJa8Pe`+VS7u-if)@G2s|r z`?pRtR!e-hywJ`~DuokZss9sKqz%8+_r6{Za{@IapaA99NMo)V;Js%30dtNw5umS` z1-wm?EvMC4>yUM5jGz9veOBvu;^nnw;boL7fs#~K`pZi<RqJ$0b@OeFphNvTy<F6P zcxGu}L5G$cDp}_$?-_azj|yf|hk~&%5AvTNNKAL`ZCp|Tn`6k)W9$zqn}Tp*xs94q z%^)GV!AV28ow5pXkwN`RR10$NS~&T>(_!7#d2RY+^W~k=Lw`!*TXUoo9bE{z!8kC< zhFQ7~$%WsJcAk#*z6<wu_n$otKTMB3>}TMNz3zvGixia3O8ouzFZdP^K|zg&Xg61e zA{|AZ15{9{5G!R_OjR@34?R8(%p{y;^ELbnFMS{UFSA54EQbivcAQH34xFQtc)2zN i9J&Kpli<7?2-kL;O3xs;zmwIuHv}fS16i{Wx^V>GXieAv delta 12816 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 -- GitLab