From 0ca52c7c80f1d9eb2a9366f0934f0d8c609b9e74 Mon Sep 17 00:00:00 2001
From: Dave Kuhlman <dkuhlman@davekuhlman.org>
Date: Fri, 16 Mar 2018 13:54:04 -0700
Subject: [PATCH] v. 2.29.11  Fix for --no-namespace-defs

---
 MANIFEST.in                       |  14 +
 README.rst                        |   7 +
 generateDS.html                   |   6 +-
 generateDS.py                     |  12 +-
 generateDS.txt                    |   2 +-
 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               |   2 +-
 setup.py                          |   2 +-
 tests/no_namespace_defs.xsd       |  36 ++
 tests/no_namespace_defs1_sub.py   |  67 +++
 tests/no_namespace_defs1_sup.py   | 849 ++++++++++++++++++++++++++++++
 tests/test.py                     |  25 +
 tutorial/generateds_tutorial.html |   6 +-
 tutorial/generateds_tutorial.txt  |   2 +-
 tutorial/generateds_tutorial.zip  | Bin 48771 -> 48770 bytes
 19 files changed, 1025 insertions(+), 23 deletions(-)
 create mode 100644 tests/no_namespace_defs.xsd
 create mode 100644 tests/no_namespace_defs1_sub.py
 create mode 100644 tests/no_namespace_defs1_sup.py

diff --git a/MANIFEST.in b/MANIFEST.in
index 99fe7ea..6203fff 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -132,6 +132,20 @@ include tests/rem_dup_elems1_sub.py
 include tests/reference_simpletype.xsd
 include tests/reference_simpletype1_sup.py
 include tests/reference_simpletype1_sub.py
+include tests/defaults_cases_always.xsd
+include tests/defaults_cases_always1_out.xml
+include tests/defaults_cases_always1_sub.py
+include tests/defaults_cases_always1_sup.py
+include tests/defaults_cases_always.xml
+include tests/no_namespace_defs.xsd
+include tests/no_namespace_defs1_sub.py
+include tests/no_namespace_defs1_sup.py
+include tests/mixedcontent.xsd
+include tests/mixedcontent.xml
+include tests/mixedcontent1_out.xml
+include tests/mixedcontent1_sub.py
+include tests/mixedcontent1_sup.py
+include tests/check_results.rb
 
 include gui/generateds_gui.py
 include gui/generateds_gui.glade
diff --git a/README.rst b/README.rst
index 1e04616..61b2ca8 100644
--- a/README.rst
+++ b/README.rst
@@ -141,6 +141,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 Change history
 --------------
 
+Version 2.29.11 (03/16/2018)
+
+- Fix for the --no-namespace-defs command line option.  The work on
+  namespaces in v. 2.29.6 appears to have conflicted with and
+  deactivated this.  Thanks to Olof Kindgren for reporting this.
+- Added unit test for --no-namespace-defs.
+
 Version 2.29.10 (03/14/2018)
 
 - Fix to resolution of child types -- Formerly, we were adding some
diff --git a/generateDS.html b/generateDS.html
index da8d74c..f03cee6 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.29.10</td>
+<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.11</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 14, 2018</td>
+<tr class="field"><th class="field-name">date:</th><td class="field-body">March 16, 2018</td>
 </tr>
 </tbody>
 </table>
@@ -3386,7 +3386,7 @@ following among others:</p>
 <div class="footer">
 <hr class="footer" />
 <a class="reference external" href="generateDS.txt">View document source</a>.
-Generated on: 2018-03-14 18:27 UTC.
+Generated on: 2018-03-16 20:52 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 0d183a9..539392a 100755
--- a/generateDS.py
+++ b/generateDS.py
@@ -232,7 +232,7 @@ logging.disable(logging.INFO)
 # Do not modify the following VERSION comments.
 # Used by updateversion.py.
 ##VERSION##
-VERSION = '2.29.10'
+VERSION = '2.29.11'
 ##VERSION##
 
 BaseStrTypes = six.string_types
@@ -2836,9 +2836,13 @@ def generateExportFn(wrt, prefix, element, namespace, nameSpacesDef):
     ns_prefix = SchemaNamespaceDict.get(name)
     if ns_prefix is not None and ns_prefix[0] is not None:
         namespace = ns_prefix[0] + ':'
-        ns_def = 'xmlns:{}'.format(ns_prefix[0])
-        if ns_def not in nameSpacesDef:
-            nameSpacesDef += ' {}="{}"'.format(ns_def, ns_prefix[1])
+    # Was the --no-namespace-defs command line option used?
+    if nameSpacesDef:
+        if ns_prefix is not None and ns_prefix[0] is not None:
+            namespace = ns_prefix[0] + ':'
+            ns_def = 'xmlns:{}'.format(ns_prefix[0])
+            if ns_def not in nameSpacesDef:
+                nameSpacesDef += ' {}="{}"'.format(ns_def, ns_prefix[1])
     wrt("    def export(self, outfile, level, namespace_='%s', "
         "name_='%s', namespacedef_='%s', pretty_print=True):\n" %
         (namespace, encodedname, nameSpacesDef))
diff --git a/generateDS.txt b/generateDS.txt
index 7f7d311..e9c12dd 100644
--- a/generateDS.txt
+++ b/generateDS.txt
@@ -12,7 +12,7 @@ generateDS -- Generate Data Structures from XML Schema
 
 .. version
 
-:revision: 2.29.10
+:revision: 2.29.11
 
 .. version
 
diff --git a/generateds_gui_notes.html b/generateds_gui_notes.html
index 7432d82..f566ce5 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.29.10</td>
+<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.11</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 14, 2018</td>
+<tr class="field"><th class="field-name">date:</th><td class="field-body">March 16, 2018</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: 2018-03-14 18:27 UTC.
+Generated on: 2018-03-16 20:52 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 f8efa78..0cd90f1 100644
--- a/generateds_gui_notes.txt
+++ b/generateds_gui_notes.txt
@@ -12,7 +12,7 @@ GenerateDS GUI Notes
 
 .. version
 
-:revision: 2.29.10
+:revision: 2.29.11
 
 .. version
 
diff --git a/gui/generateds_gui.py b/gui/generateds_gui.py
index 1a34eb2..9193a24 100644
--- 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.29.10'
+VERSION = '2.29.11'
 ##VERSION##
 
 
diff --git a/librarytemplate_howto.html b/librarytemplate_howto.html
index a5724e3..bf62a12 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.29.10</td>
+<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.11</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 14, 2018</td>
+<tr class="field"><th class="field-name">date:</th><td class="field-body">March 16, 2018</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: 2018-03-14 18:27 UTC.
+Generated on: 2018-03-16 20:52 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 72b3f8b..a726e0e 100644
--- a/librarytemplate_howto.txt
+++ b/librarytemplate_howto.txt
@@ -8,7 +8,7 @@ How to package a generateDS.py generated library
 
 .. version
 
-:revision: 2.29.10
+:revision: 2.29.11
 
 .. version
 
diff --git a/process_includes.py b/process_includes.py
index abbc7da..f7ffb58 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.29.10'
+VERSION = '2.29.11'
 ##VERSION##
 
 CatalogDict = {}
diff --git a/setup.py b/setup.py
index ef25b06..4e91566 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.29.10",
+    version="2.29.11",
 ##VERSION##
     author="Dave Kuhlman",
     author_email="dkuhlman@davekuhlman.org",
diff --git a/tests/no_namespace_defs.xsd b/tests/no_namespace_defs.xsd
new file mode 100644
index 0000000..6d84a4d
--- /dev/null
+++ b/tests/no_namespace_defs.xsd
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+    <xs:element name="people" type="peopleType">
+        <xs:annotation><xs:documentation>
+          A list of people.
+        </xs:documentation></xs:annotation>
+    </xs:element>
+    <xs:complexType name="peopleType">
+        <xs:sequence>
+            <xs:element name="person" maxOccurs="unbounded" type="personType"/>
+            <xs:element name="specialperson" maxOccurs="unbounded" type="specialperson"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:element name="person" type="personType">
+        <xs:annotation><xs:documentation>
+          A generic person.  This is the base for a number of different
+          kinds of people.  They are each an extension of this base
+          type of person.
+        </xs:documentation></xs:annotation>
+    </xs:element>
+
+    <xs:complexType name="personType" mixed="0">
+        <xs:sequence>
+            <xs:element name="name" type="xs:string"/>
+            <xs:element name="interest" type="xs:string" maxOccurs="unbounded" />
+            <xs:element name="category" type="xs:integer" minOccurs="0" />
+            <xs:element name="description" type="xs:string"/>
+        </xs:sequence>
+        <xs:attribute name="value" type="xs:ID" />
+        <xs:attribute name="id" type="xs:integer" />
+        <xs:attribute name="ratio" type="xs:float" />
+    </xs:complexType>
+
+</xs:schema>
diff --git a/tests/no_namespace_defs1_sub.py b/tests/no_namespace_defs1_sub.py
new file mode 100644
index 0000000..b54fcb2
--- /dev/null
+++ b/tests/no_namespace_defs1_sub.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+
+#
+# Generated  by generateDS.py.
+# Python 2.7.14 (default, Sep 23 2017, 22:06:14)  [GCC 7.2.0]
+#
+# Command line options:
+#   ('--no-dates', '')
+#   ('--no-versions', '')
+#   ('--disable-xml', '')
+#   ('--disable-generatedssuper-lookup', '')
+#   ('--member-specs', 'list')
+#   ('-f', '')
+#   ('-a', 'xsd:')
+#   ('-o', 'tests/no_namespace_defs2_sup.py')
+#   ('-s', 'tests/no_namespace_defs2_sub.py')
+#   ('--super', 'no_namespace_defs2_sup')
+#   ('--no-warnings', '')
+#
+# Command line arguments:
+#   tests/no_namespace_defs.xsd
+#
+# Command line:
+#   generateDS.py --no-dates --no-versions --disable-xml --disable-generatedssuper-lookup --member-specs="list" -f -a "xsd:" -o "tests/no_namespace_defs2_sup.py" -s "tests/no_namespace_defs2_sub.py" --super="no_namespace_defs2_sup" --no-warnings tests/no_namespace_defs.xsd
+#
+# Current working directory (os.getcwd()):
+#   generateds
+#
+
+import sys
+## from lxml import etree as etree_
+
+import no_namespace_defs2_sup as supermod
+
+## def parsexml_(infile, parser=None, **kwargs):
+##     if parser is None:
+##         # Use the lxml ElementTree compatible parser so that, e.g.,
+##         #   we ignore comments.
+##         parser = etree_.ETCompatXMLParser()
+##     doc = etree_.parse(infile, parser=parser, **kwargs)
+##     return doc
+
+#
+# Globals
+#
+
+ExternalEncoding = 'ascii'
+
+#
+# Data representation classes
+#
+
+
+class peopleTypeSub(supermod.peopleType):
+    def __init__(self, person=None, specialperson=None):
+        super(peopleTypeSub, self).__init__(person, specialperson, )
+supermod.peopleType.subclass = peopleTypeSub
+# end class peopleTypeSub
+
+
+class personTypeSub(supermod.personType):
+    def __init__(self, value=None, id=None, ratio=None, name=None, interest=None, category=None, description=None):
+        super(personTypeSub, self).__init__(value, id, ratio, name, interest, category, description, )
+supermod.personType.subclass = personTypeSub
+# end class personTypeSub
+
+
diff --git a/tests/no_namespace_defs1_sup.py b/tests/no_namespace_defs1_sup.py
new file mode 100644
index 0000000..ca8cbc7
--- /dev/null
+++ b/tests/no_namespace_defs1_sup.py
@@ -0,0 +1,849 @@
+## #!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#
+# Generated  by generateDS.py.
+# Python 2.7.14 (default, Sep 23 2017, 22:06:14)  [GCC 7.2.0]
+#
+# Command line options:
+#   ('--no-dates', '')
+#   ('--no-versions', '')
+#   ('--disable-xml', '')
+#   ('--disable-generatedssuper-lookup', '')
+#   ('--member-specs', 'list')
+#   ('-f', '')
+#   ('-a', 'xsd:')
+#   ('-o', 'tests/no_namespace_defs2_sup.py')
+#   ('-s', 'tests/no_namespace_defs2_sub.py')
+#   ('--super', 'no_namespace_defs2_sup')
+#   ('--no-warnings', '')
+#
+# Command line arguments:
+#   tests/no_namespace_defs.xsd
+#
+# Command line:
+#   generateDS.py --no-dates --no-versions --disable-xml --disable-generatedssuper-lookup --member-specs="list" -f -a "xsd:" -o "tests/no_namespace_defs2_sup.py" -s "tests/no_namespace_defs2_sub.py" --super="no_namespace_defs2_sup" --no-warnings tests/no_namespace_defs.xsd
+#
+# Current working directory (os.getcwd()):
+#   generateds
+#
+
+import sys
+import re as re_
+import base64
+import datetime as datetime_
+import warnings as warnings_
+## try:
+##     from lxml import etree as etree_
+## except ImportError:
+##     from xml.etree import ElementTree as etree_
+
+
+Validate_simpletypes_ = True
+if sys.version_info.major == 2:
+    BaseStrType_ = basestring
+else:
+    BaseStrType_ = str
+
+
+## def parsexml_(infile, parser=None, **kwargs):
+##     if parser is None:
+##         # Use the lxml ElementTree compatible parser so that, e.g.,
+##         #   we ignore comments.
+##         try:
+##             parser = etree_.ETCompatXMLParser()
+##         except AttributeError:
+##             # fallback to xml.etree
+##             parser = etree_.XMLParser()
+##     doc = etree_.parse(infile, parser=parser, **kwargs)
+##     return doc
+
+## def parsexmlstring_(instring, parser=None, **kwargs):
+##     if parser is None:
+##         # Use the lxml ElementTree compatible parser so that, e.g.,
+##         #   we ignore comments.
+##         try:
+##             parser = etree_.ETCompatXMLParser()
+##         except AttributeError:
+##             # fallback to xml.etree
+##             parser = etree_.XMLParser()
+##     element = etree_.fromstring(instring, parser=parser, **kwargs)
+##     return element
+
+#
+# Namespace prefix definition table (and other attributes, too)
+#
+# The module generatedsnamespaces, if it is importable, must contain
+# a dictionary named GeneratedsNamespaceDefs.  This Python dictionary
+# should map element type names (strings) to XML schema namespace prefix
+# definitions.  The export method for any class for which there is
+# a namespace prefix definition, will export that definition in the
+# XML representation of that element.  See the export method of
+# any generated element type class for a example of the use of this
+# table.
+# A sample table is:
+#
+#     # File: generatedsnamespaces.py
+#
+#     GenerateDSNamespaceDefs = {
+#         "ElementtypeA": "http://www.xxx.com/namespaceA",
+#         "ElementtypeB": "http://www.xxx.com/namespaceB",
+#     }
+#
+
+try:
+    from generatedsnamespaces import GenerateDSNamespaceDefs as GenerateDSNamespaceDefs_
+except ImportError:
+    GenerateDSNamespaceDefs_ = {}
+
+#
+# The root super-class for element type classes
+#
+# Calls to the methods in these classes are generated by generateDS.py.
+# You can replace these methods by re-implementing the following class
+#   in a module named generatedssuper.py.
+
+
+class GeneratedsSuper(object):
+    tzoff_pattern = re_.compile(r'(\+|-)((0\d|1[0-3]):[0-5]\d|14:00)$')
+    class _FixedOffsetTZ(datetime_.tzinfo):
+        def __init__(self, offset, name):
+            self.__offset = datetime_.timedelta(minutes=offset)
+            self.__name = name
+        def utcoffset(self, dt):
+            return self.__offset
+        def tzname(self, dt):
+            return self.__name
+        def dst(self, dt):
+            return None
+    def gds_format_string(self, input_data, input_name=''):
+        return input_data
+    def gds_validate_string(self, input_data, node=None, input_name=''):
+        if not input_data:
+            return ''
+        else:
+            return input_data
+    def gds_format_base64(self, input_data, input_name=''):
+        return base64.b64encode(input_data)
+    def gds_validate_base64(self, input_data, node=None, input_name=''):
+        return input_data
+    def gds_format_integer(self, input_data, input_name=''):
+        return '%d' % input_data
+    def gds_validate_integer(self, input_data, node=None, input_name=''):
+        return input_data
+    def gds_format_integer_list(self, input_data, input_name=''):
+        return '%s' % ' '.join(input_data)
+    def gds_validate_integer_list(
+            self, input_data, node=None, input_name=''):
+        values = input_data.split()
+        for value in values:
+            try:
+                int(value)
+            except (TypeError, ValueError):
+                raise_parse_error(node, 'Requires sequence of integers')
+        return values
+    def gds_format_float(self, input_data, input_name=''):
+        return ('%.15f' % input_data).rstrip('0')
+    def gds_validate_float(self, input_data, node=None, input_name=''):
+        return input_data
+    def gds_format_float_list(self, input_data, input_name=''):
+        return '%s' % ' '.join(input_data)
+    def gds_validate_float_list(
+            self, input_data, node=None, input_name=''):
+        values = input_data.split()
+        for value in values:
+            try:
+                float(value)
+            except (TypeError, ValueError):
+                raise_parse_error(node, 'Requires sequence of floats')
+        return values
+    def gds_format_double(self, input_data, input_name=''):
+        return '%e' % input_data
+    def gds_validate_double(self, input_data, node=None, input_name=''):
+        return input_data
+    def gds_format_double_list(self, input_data, input_name=''):
+        return '%s' % ' '.join(input_data)
+    def gds_validate_double_list(
+            self, input_data, node=None, input_name=''):
+        values = input_data.split()
+        for value in values:
+            try:
+                float(value)
+            except (TypeError, ValueError):
+                raise_parse_error(node, 'Requires sequence of doubles')
+        return values
+    def gds_format_boolean(self, input_data, input_name=''):
+        return ('%s' % input_data).lower()
+    def gds_validate_boolean(self, input_data, node=None, input_name=''):
+        return input_data
+    def gds_format_boolean_list(self, input_data, input_name=''):
+        return '%s' % ' '.join(input_data)
+    def gds_validate_boolean_list(
+            self, input_data, node=None, input_name=''):
+        values = input_data.split()
+        for value in values:
+            if value not in ('true', '1', 'false', '0', ):
+                raise_parse_error(
+                    node,
+                    'Requires sequence of booleans '
+                    '("true", "1", "false", "0")')
+        return values
+    def gds_validate_datetime(self, input_data, node=None, input_name=''):
+        return input_data
+    def gds_format_datetime(self, input_data, input_name=''):
+        if input_data.microsecond == 0:
+            _svalue = '%04d-%02d-%02dT%02d:%02d:%02d' % (
+                input_data.year,
+                input_data.month,
+                input_data.day,
+                input_data.hour,
+                input_data.minute,
+                input_data.second,
+            )
+        else:
+            _svalue = '%04d-%02d-%02dT%02d:%02d:%02d.%s' % (
+                input_data.year,
+                input_data.month,
+                input_data.day,
+                input_data.hour,
+                input_data.minute,
+                input_data.second,
+                ('%f' % (float(input_data.microsecond) / 1000000))[2:],
+            )
+        if input_data.tzinfo is not None:
+            tzoff = input_data.tzinfo.utcoffset(input_data)
+            if tzoff is not None:
+                total_seconds = tzoff.seconds + (86400 * tzoff.days)
+                if total_seconds == 0:
+                    _svalue += 'Z'
+                else:
+                    if total_seconds < 0:
+                        _svalue += '-'
+                        total_seconds *= -1
+                    else:
+                        _svalue += '+'
+                    hours = total_seconds // 3600
+                    minutes = (total_seconds - (hours * 3600)) // 60
+                    _svalue += '{0:02d}:{1:02d}'.format(hours, minutes)
+        return _svalue
+    @classmethod
+    def gds_parse_datetime(cls, input_data):
+        tz = None
+        if input_data[-1] == 'Z':
+            tz = GeneratedsSuper._FixedOffsetTZ(0, 'UTC')
+            input_data = input_data[:-1]
+        else:
+            results = GeneratedsSuper.tzoff_pattern.search(input_data)
+            if results is not None:
+                tzoff_parts = results.group(2).split(':')
+                tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1])
+                if results.group(1) == '-':
+                    tzoff *= -1
+                tz = GeneratedsSuper._FixedOffsetTZ(
+                    tzoff, results.group(0))
+                input_data = input_data[:-6]
+        time_parts = input_data.split('.')
+        if len(time_parts) > 1:
+            micro_seconds = int(float('0.' + time_parts[1]) * 1000000)
+            input_data = '%s.%s' % (time_parts[0], micro_seconds, )
+            dt = datetime_.datetime.strptime(
+                input_data, '%Y-%m-%dT%H:%M:%S.%f')
+        else:
+            dt = datetime_.datetime.strptime(
+                input_data, '%Y-%m-%dT%H:%M:%S')
+        dt = dt.replace(tzinfo=tz)
+        return dt
+    def gds_validate_date(self, input_data, node=None, input_name=''):
+        return input_data
+    def gds_format_date(self, input_data, input_name=''):
+        _svalue = '%04d-%02d-%02d' % (
+            input_data.year,
+            input_data.month,
+            input_data.day,
+        )
+        try:
+            if input_data.tzinfo is not None:
+                tzoff = input_data.tzinfo.utcoffset(input_data)
+                if tzoff is not None:
+                    total_seconds = tzoff.seconds + (86400 * tzoff.days)
+                    if total_seconds == 0:
+                        _svalue += 'Z'
+                    else:
+                        if total_seconds < 0:
+                            _svalue += '-'
+                            total_seconds *= -1
+                        else:
+                            _svalue += '+'
+                        hours = total_seconds // 3600
+                        minutes = (total_seconds - (hours * 3600)) // 60
+                        _svalue += '{0:02d}:{1:02d}'.format(
+                            hours, minutes)
+        except AttributeError:
+            pass
+        return _svalue
+    @classmethod
+    def gds_parse_date(cls, input_data):
+        tz = None
+        if input_data[-1] == 'Z':
+            tz = GeneratedsSuper._FixedOffsetTZ(0, 'UTC')
+            input_data = input_data[:-1]
+        else:
+            results = GeneratedsSuper.tzoff_pattern.search(input_data)
+            if results is not None:
+                tzoff_parts = results.group(2).split(':')
+                tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1])
+                if results.group(1) == '-':
+                    tzoff *= -1
+                tz = GeneratedsSuper._FixedOffsetTZ(
+                    tzoff, results.group(0))
+                input_data = input_data[:-6]
+        dt = datetime_.datetime.strptime(input_data, '%Y-%m-%d')
+        dt = dt.replace(tzinfo=tz)
+        return dt.date()
+    def gds_validate_time(self, input_data, node=None, input_name=''):
+        return input_data
+    def gds_format_time(self, input_data, input_name=''):
+        if input_data.microsecond == 0:
+            _svalue = '%02d:%02d:%02d' % (
+                input_data.hour,
+                input_data.minute,
+                input_data.second,
+            )
+        else:
+            _svalue = '%02d:%02d:%02d.%s' % (
+                input_data.hour,
+                input_data.minute,
+                input_data.second,
+                ('%f' % (float(input_data.microsecond) / 1000000))[2:],
+            )
+        if input_data.tzinfo is not None:
+            tzoff = input_data.tzinfo.utcoffset(input_data)
+            if tzoff is not None:
+                total_seconds = tzoff.seconds + (86400 * tzoff.days)
+                if total_seconds == 0:
+                    _svalue += 'Z'
+                else:
+                    if total_seconds < 0:
+                        _svalue += '-'
+                        total_seconds *= -1
+                    else:
+                        _svalue += '+'
+                    hours = total_seconds // 3600
+                    minutes = (total_seconds - (hours * 3600)) // 60
+                    _svalue += '{0:02d}:{1:02d}'.format(hours, minutes)
+        return _svalue
+    def gds_validate_simple_patterns(self, patterns, target):
+        # pat is a list of lists of strings/patterns.  We should:
+        # - AND the outer elements
+        # - OR the inner elements
+        found1 = True
+        for patterns1 in patterns:
+            found2 = False
+            for patterns2 in patterns1:
+                if re_.search(patterns2, target) is not None:
+                    found2 = True
+                    break
+            if not found2:
+                found1 = False
+                break
+        return found1
+    @classmethod
+    def gds_parse_time(cls, input_data):
+        tz = None
+        if input_data[-1] == 'Z':
+            tz = GeneratedsSuper._FixedOffsetTZ(0, 'UTC')
+            input_data = input_data[:-1]
+        else:
+            results = GeneratedsSuper.tzoff_pattern.search(input_data)
+            if results is not None:
+                tzoff_parts = results.group(2).split(':')
+                tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1])
+                if results.group(1) == '-':
+                    tzoff *= -1
+                tz = GeneratedsSuper._FixedOffsetTZ(
+                    tzoff, results.group(0))
+                input_data = input_data[:-6]
+        if len(input_data.split('.')) > 1:
+            dt = datetime_.datetime.strptime(input_data, '%H:%M:%S.%f')
+        else:
+            dt = datetime_.datetime.strptime(input_data, '%H:%M:%S')
+        dt = dt.replace(tzinfo=tz)
+        return dt.time()
+    def gds_str_lower(self, instring):
+        return instring.lower()
+    def get_path_(self, node):
+        path_list = []
+        self.get_path_list_(node, path_list)
+        path_list.reverse()
+        path = '/'.join(path_list)
+        return path
+    Tag_strip_pattern_ = re_.compile(r'\{.*\}')
+    def get_path_list_(self, node, path_list):
+        if node is None:
+            return
+        tag = GeneratedsSuper.Tag_strip_pattern_.sub('', node.tag)
+        if tag:
+            path_list.append(tag)
+        self.get_path_list_(node.getparent(), path_list)
+    def get_class_obj_(self, node, default_class=None):
+        class_obj1 = default_class
+        if 'xsi' in node.nsmap:
+            classname = node.get('{%s}type' % node.nsmap['xsi'])
+            if classname is not None:
+                names = classname.split(':')
+                if len(names) == 2:
+                    classname = names[1]
+                class_obj2 = globals().get(classname)
+                if class_obj2 is not None:
+                    class_obj1 = class_obj2
+        return class_obj1
+    def gds_build_any(self, node, type_name=None):
+        return None
+    @classmethod
+    def gds_reverse_node_mapping(cls, mapping):
+        return dict(((v, k) for k, v in mapping.iteritems()))
+    @staticmethod
+    def gds_encode(instring):
+        if sys.version_info.major == 2:
+            return instring.encode(ExternalEncoding)
+        else:
+            return instring
+    @staticmethod
+    def convert_unicode(instring):
+        if isinstance(instring, str):
+            result = quote_xml(instring)
+        elif sys.version_info.major == 2 and isinstance(instring, unicode):
+            result = quote_xml(instring).encode('utf8')
+        else:
+            result = GeneratedsSuper.gds_encode(str(instring))
+        return result
+    def __eq__(self, other):
+        if type(self) != type(other):
+            return False
+        return self.__dict__ == other.__dict__
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+def getSubclassFromModule_(module, class_):
+    '''Get the subclass of a class from a specific module.'''
+    name = class_.__name__ + 'Sub'
+    if hasattr(module, name):
+        return getattr(module, name)
+    else:
+        return None
+
+
+#
+# If you have installed IPython you can uncomment and use the following.
+# IPython is available from http://ipython.scipy.org/.
+#
+
+## from IPython.Shell import IPShellEmbed
+## args = ''
+## ipshell = IPShellEmbed(args,
+##     banner = 'Dropping into IPython',
+##     exit_msg = 'Leaving Interpreter, back to program.')
+
+# Then use the following line where and when you want to drop into the
+# IPython shell:
+#    ipshell('<some message> -- Entering ipshell.\nHit Ctrl-D to exit')
+
+#
+# Globals
+#
+
+ExternalEncoding = 'ascii'
+Tag_pattern_ = re_.compile(r'({.*})?(.*)')
+String_cleanup_pat_ = re_.compile(r"[\n\r\s]+")
+Namespace_extract_pat_ = re_.compile(r'{(.*)}(.*)')
+CDATA_pattern_ = re_.compile(r"<!\[CDATA\[.*?\]\]>", re_.DOTALL)
+
+# Change this to redirect the generated superclass module to use a
+# specific subclass module.
+CurrentSubclassModule_ = None
+
+#
+# Support/utility functions.
+#
+
+
+def showIndent(outfile, level, pretty_print=True):
+    if pretty_print:
+        for idx in range(level):
+            outfile.write('    ')
+
+
+def quote_xml(inStr):
+    "Escape markup chars, but do not modify CDATA sections."
+    if not inStr:
+        return ''
+    s1 = (isinstance(inStr, BaseStrType_) and inStr or '%s' % inStr)
+    s2 = ''
+    pos = 0
+    matchobjects = CDATA_pattern_.finditer(s1)
+    for mo in matchobjects:
+        s3 = s1[pos:mo.start()]
+        s2 += quote_xml_aux(s3)
+        s2 += s1[mo.start():mo.end()]
+        pos = mo.end()
+    s3 = s1[pos:]
+    s2 += quote_xml_aux(s3)
+    return s2
+
+
+def quote_xml_aux(inStr):
+    s1 = inStr.replace('&', '&amp;')
+    s1 = s1.replace('<', '&lt;')
+    s1 = s1.replace('>', '&gt;')
+    return s1
+
+
+def quote_attrib(inStr):
+    s1 = (isinstance(inStr, BaseStrType_) and inStr or '%s' % inStr)
+    s1 = s1.replace('&', '&amp;')
+    s1 = s1.replace('<', '&lt;')
+    s1 = s1.replace('>', '&gt;')
+    if '"' in s1:
+        if "'" in s1:
+            s1 = '"%s"' % s1.replace('"', "&quot;")
+        else:
+            s1 = "'%s'" % s1
+    else:
+        s1 = '"%s"' % s1
+    return s1
+
+
+def quote_python(inStr):
+    s1 = inStr
+    if s1.find("'") == -1:
+        if s1.find('\n') == -1:
+            return "'%s'" % s1
+        else:
+            return "'''%s'''" % s1
+    else:
+        if s1.find('"') != -1:
+            s1 = s1.replace('"', '\\"')
+        if s1.find('\n') == -1:
+            return '"%s"' % s1
+        else:
+            return '"""%s"""' % s1
+
+
+def get_all_text_(node):
+    if node.text is not None:
+        text = node.text
+    else:
+        text = ''
+    for child in node:
+        if child.tail is not None:
+            text += child.tail
+    return text
+
+
+def find_attr_value_(attr_name, node):
+    attrs = node.attrib
+    attr_parts = attr_name.split(':')
+    value = None
+    if len(attr_parts) == 1:
+        value = attrs.get(attr_name)
+    elif len(attr_parts) == 2:
+        prefix, name = attr_parts
+        namespace = node.nsmap.get(prefix)
+        if namespace is not None:
+            value = attrs.get('{%s}%s' % (namespace, name, ))
+    return value
+
+
+class GDSParseError(Exception):
+    pass
+
+
+def raise_parse_error(node, msg):
+    msg = '%s (element %s/line %d)' % (msg, node.tag, node.sourceline, )
+    raise GDSParseError(msg)
+
+
+class MixedContainer:
+    # Constants for category:
+    CategoryNone = 0
+    CategoryText = 1
+    CategorySimple = 2
+    CategoryComplex = 3
+    # Constants for content_type:
+    TypeNone = 0
+    TypeText = 1
+    TypeString = 2
+    TypeInteger = 3
+    TypeFloat = 4
+    TypeDecimal = 5
+    TypeDouble = 6
+    TypeBoolean = 7
+    TypeBase64 = 8
+    def __init__(self, category, content_type, name, value):
+        self.category = category
+        self.content_type = content_type
+        self.name = name
+        self.value = value
+    def getCategory(self):
+        return self.category
+    def getContenttype(self, content_type):
+        return self.content_type
+    def getValue(self):
+        return self.value
+    def getName(self):
+        return self.name
+##     def export(self, outfile, level, name, namespace,
+##                pretty_print=True):
+##         if self.category == MixedContainer.CategoryText:
+##             # Prevent exporting empty content as empty lines.
+##             if self.value.strip():
+##                 outfile.write(self.value)
+##         elif self.category == MixedContainer.CategorySimple:
+##             self.exportSimple(outfile, level, name)
+##         else:    # category == MixedContainer.CategoryComplex
+##             self.value.export(
+##                 outfile, level, namespace, name,
+##                 pretty_print=pretty_print)
+##     def exportSimple(self, outfile, level, name):
+##         if self.content_type == MixedContainer.TypeString:
+##             outfile.write('<%s>%s</%s>' % (
+##                 self.name, self.value, self.name))
+##         elif self.content_type == MixedContainer.TypeInteger or \
+##                 self.content_type == MixedContainer.TypeBoolean:
+##             outfile.write('<%s>%d</%s>' % (
+##                 self.name, self.value, self.name))
+##         elif self.content_type == MixedContainer.TypeFloat or \
+##                 self.content_type == MixedContainer.TypeDecimal:
+##             outfile.write('<%s>%f</%s>' % (
+##                 self.name, self.value, self.name))
+##         elif self.content_type == MixedContainer.TypeDouble:
+##             outfile.write('<%s>%g</%s>' % (
+##                 self.name, self.value, self.name))
+##         elif self.content_type == MixedContainer.TypeBase64:
+##             outfile.write('<%s>%s</%s>' % (
+##                 self.name,
+##                 base64.b64encode(self.value),
+##                 self.name))
+##     def to_etree(self, element):
+##         if self.category == MixedContainer.CategoryText:
+##             # Prevent exporting empty content as empty lines.
+##             if self.value.strip():
+##                 if len(element) > 0:
+##                     if element[-1].tail is None:
+##                         element[-1].tail = self.value
+##                     else:
+##                         element[-1].tail += self.value
+##                 else:
+##                     if element.text is None:
+##                         element.text = self.value
+##                     else:
+##                         element.text += self.value
+##         elif self.category == MixedContainer.CategorySimple:
+##             subelement = etree_.SubElement(
+##                 element, '%s' % self.name)
+##             subelement.text = self.to_etree_simple()
+##         else:    # category == MixedContainer.CategoryComplex
+##             self.value.to_etree(element)
+##     def to_etree_simple(self):
+##         if self.content_type == MixedContainer.TypeString:
+##             text = self.value
+##         elif (self.content_type == MixedContainer.TypeInteger or
+##                 self.content_type == MixedContainer.TypeBoolean):
+##             text = '%d' % self.value
+##         elif (self.content_type == MixedContainer.TypeFloat or
+##                 self.content_type == MixedContainer.TypeDecimal):
+##             text = '%f' % self.value
+##         elif self.content_type == MixedContainer.TypeDouble:
+##             text = '%g' % self.value
+##         elif self.content_type == MixedContainer.TypeBase64:
+##             text = '%s' % base64.b64encode(self.value)
+##         return text
+##     def exportLiteral(self, outfile, level, name):
+##         if self.category == MixedContainer.CategoryText:
+##             showIndent(outfile, level)
+##             outfile.write(
+##                 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' % (
+##                     self.category, self.content_type,
+##                     self.name, self.value))
+##         elif self.category == MixedContainer.CategorySimple:
+##             showIndent(outfile, level)
+##             outfile.write(
+##                 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' % (
+##                     self.category, self.content_type,
+##                     self.name, self.value))
+##         else:    # category == MixedContainer.CategoryComplex
+##             showIndent(outfile, level)
+##             outfile.write(
+##                 'model_.MixedContainer(%d, %d, "%s",\n' % (
+##                     self.category, self.content_type, self.name,))
+##             self.value.exportLiteral(outfile, level + 1)
+##             showIndent(outfile, level)
+##             outfile.write(')\n')
+
+
+class MemberSpec_(object):
+    def __init__(self, name='', data_type='', container=0,
+            optional=0, child_attrs=None, choice=None):
+        self.name = name
+        self.data_type = data_type
+        self.container = container
+        self.child_attrs = child_attrs
+        self.choice = choice
+        self.optional = optional
+    def set_name(self, name): self.name = name
+    def get_name(self): return self.name
+    def set_data_type(self, data_type): self.data_type = data_type
+    def get_data_type_chain(self): return self.data_type
+    def get_data_type(self):
+        if isinstance(self.data_type, list):
+            if len(self.data_type) > 0:
+                return self.data_type[-1]
+            else:
+                return 'xs:string'
+        else:
+            return self.data_type
+    def set_container(self, container): self.container = container
+    def get_container(self): return self.container
+    def set_child_attrs(self, child_attrs): self.child_attrs = child_attrs
+    def get_child_attrs(self): return self.child_attrs
+    def set_choice(self, choice): self.choice = choice
+    def get_choice(self): return self.choice
+    def set_optional(self, optional): self.optional = optional
+    def get_optional(self): return self.optional
+
+
+def _cast(typ, value):
+    if typ is None or value is None:
+        return value
+    return typ(value)
+
+#
+# Data representation classes.
+#
+
+
+class peopleType(GeneratedsSuper):
+    member_data_items_ = [
+        MemberSpec_('person', 'personType', 1, 0, {u'maxOccurs': u'unbounded', u'type': u'personType', u'name': u'person'}, None),
+        MemberSpec_('specialperson', 'xs:string', 1, 0, {u'maxOccurs': u'unbounded', u'type': u'xs:string', u'name': u'specialperson'}, None),
+    ]
+    subclass = None
+    superclass = None
+    def __init__(self, person=None, specialperson=None):
+        self.original_tagname_ = None
+        if person is None:
+            self.person = []
+        else:
+            self.person = person
+        if specialperson is None:
+            self.specialperson = []
+        else:
+            self.specialperson = specialperson
+    def factory(*args_, **kwargs_):
+        if CurrentSubclassModule_ is not None:
+            subclass = getSubclassFromModule_(
+                CurrentSubclassModule_, peopleType)
+            if subclass is not None:
+                return subclass(*args_, **kwargs_)
+        if peopleType.subclass:
+            return peopleType.subclass(*args_, **kwargs_)
+        else:
+            return peopleType(*args_, **kwargs_)
+    factory = staticmethod(factory)
+    def get_person(self): return self.person
+    def set_person(self, person): self.person = person
+    def add_person(self, value): self.person.append(value)
+    def insert_person_at(self, index, value): self.person.insert(index, value)
+    def replace_person_at(self, index, value): self.person[index] = value
+    def get_specialperson(self): return self.specialperson
+    def set_specialperson(self, specialperson): self.specialperson = specialperson
+    def add_specialperson(self, value): self.specialperson.append(value)
+    def insert_specialperson_at(self, index, value): self.specialperson.insert(index, value)
+    def replace_specialperson_at(self, index, value): self.specialperson[index] = value
+    def hasContent_(self):
+        if (
+            self.person or
+            self.specialperson
+        ):
+            return True
+        else:
+            return False
+# end class peopleType
+
+
+class personType(GeneratedsSuper):
+    member_data_items_ = [
+        MemberSpec_('value', 'xs:string', 0, 1, {'use': 'optional'}),
+        MemberSpec_('id', 'xs:integer', 0, 1, {'use': 'optional'}),
+        MemberSpec_('ratio', 'xs:float', 0, 1, {'use': 'optional'}),
+        MemberSpec_('name', 'xs:string', 0, 0, {u'type': u'xs:string', u'name': u'name'}, None),
+        MemberSpec_('interest', 'xs:string', 1, 0, {u'maxOccurs': u'unbounded', u'type': u'xs:string', u'name': u'interest'}, None),
+        MemberSpec_('category', 'xs:integer', 0, 1, {u'type': u'xs:integer', u'name': u'category', u'minOccurs': u'0'}, None),
+        MemberSpec_('description', 'xs:string', 0, 0, {u'type': u'xs:string', u'name': u'description'}, None),
+    ]
+    subclass = None
+    superclass = None
+    def __init__(self, value=None, id=None, ratio=None, name=None, interest=None, category=None, description=None):
+        self.original_tagname_ = None
+        self.value = _cast(None, value)
+        self.id = _cast(int, id)
+        self.ratio = _cast(float, ratio)
+        self.name = name
+        if interest is None:
+            self.interest = []
+        else:
+            self.interest = interest
+        self.category = category
+        self.description = description
+    def factory(*args_, **kwargs_):
+        if CurrentSubclassModule_ is not None:
+            subclass = getSubclassFromModule_(
+                CurrentSubclassModule_, personType)
+            if subclass is not None:
+                return subclass(*args_, **kwargs_)
+        if personType.subclass:
+            return personType.subclass(*args_, **kwargs_)
+        else:
+            return personType(*args_, **kwargs_)
+    factory = staticmethod(factory)
+    def get_name(self): return self.name
+    def set_name(self, name): self.name = name
+    def get_interest(self): return self.interest
+    def set_interest(self, interest): self.interest = interest
+    def add_interest(self, value): self.interest.append(value)
+    def insert_interest_at(self, index, value): self.interest.insert(index, value)
+    def replace_interest_at(self, index, value): self.interest[index] = value
+    def get_category(self): return self.category
+    def set_category(self, category): self.category = category
+    def get_description(self): return self.description
+    def set_description(self, description): self.description = description
+    def get_value(self): return self.value
+    def set_value(self, value): self.value = value
+    def get_id(self): return self.id
+    def set_id(self, id): self.id = id
+    def get_ratio(self): return self.ratio
+    def set_ratio(self, ratio): self.ratio = ratio
+    def hasContent_(self):
+        if (
+            self.name is not None or
+            self.interest or
+            self.category is not None or
+            self.description is not None
+        ):
+            return True
+        else:
+            return False
+# end class personType
+
+
+GDSClassesMapping = {
+    'people': peopleType,
+    'person': personType,
+}
+
+
+
+__all__ = [
+    "peopleType",
+    "personType"
+]
diff --git a/tests/test.py b/tests/test.py
index 56a70b9..ffa9bf7 100755
--- a/tests/test.py
+++ b/tests/test.py
@@ -899,6 +899,31 @@ class GenTest(unittest.TestCase):
         self.remove('{}2_sub.py'.format(t_))
         self.remove('{}2_out.xml'.format(t_))
 
+    #
+    # Test for command line option --no-namespace-defs.
+    def test_036_no_namespace_defs(self):
+        cmdTempl = (
+            'python generateDS.py --no-dates --no-versions '
+            '--disable-xml --disable-generatedssuper-lookup '
+            '--member-specs=list -f -a "xsd:" '
+            '-o tests/%s2_sup.py -s tests/%s2_sub.py '
+            '--super=%s2_sup --no-warnings '
+            'tests/%s.xsd'
+        )
+        t_ = 'no_namespace_defs'
+        cmd = cmdTempl % (t_, t_, t_, t_, )
+        self.executeClean(cmd, cwd='..')
+        self.compareFiles(
+            '{}1_sup.py'.format(t_),
+            '{}2_sup.py'.format(t_),
+            ('sys.stdout.write',))
+        self.compareFiles('{}1_sub.py'.format(t_), '{}2_sub.py'.format(t_))
+        # Need to preserve generated files for next command, cleanup at end
+        # cleanup generated files
+        #self.remove('{}2_sup.py'.format(t_))
+        #self.remove('{}2_sub.py'.format(t_))
+        #self.remove('{}2_out.xml'.format(t_))
+
     def compareFiles(self, left, right, ignore=None):
         with open(left) as left_file:
             with open(right) as right_file:
diff --git a/tutorial/generateds_tutorial.html b/tutorial/generateds_tutorial.html
index 4b83f30..c8c30d8 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.29.10</td>
+<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.11</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 14, 2018</td>
+<tr class="field"><th class="field-name">date:</th><td class="field-body">March 16, 2018</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: 2018-03-14 18:27 UTC.
+Generated on: 2018-03-16 20:52 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 e89fa7e..4218043 100644
--- a/tutorial/generateds_tutorial.txt
+++ b/tutorial/generateds_tutorial.txt
@@ -11,7 +11,7 @@ generateDS -- Introduction and Tutorial
 
 .. version
 
-:revision: 2.29.10
+:revision: 2.29.11
 
 .. version
 
diff --git a/tutorial/generateds_tutorial.zip b/tutorial/generateds_tutorial.zip
index febd5dad5775f685cfc1d863691555447c06084d..e7990575fca2070f20ed4e6f7e2ac5703cd65229 100644
GIT binary patch
delta 9878
zcmV;HCTZD&{Q`ph0vk|E0|XQR000O8Hd$~?Z5W4?T>=0A5Cs4L7n5+677#9Ucyv`%
z2>=6V2&`JM2&|Do9Dm3GIb9NDsevqQmO~SuKr^&cPbbl5p|WU5axMn)<4elte0b;(
zEtV<r>GARD_VzQYI$*%4Gv57#^%}MzN3w&-jsoal;c>_mo%YqI&~K}%)<bS7)^Mkv
z5WWws?{wg(wGmUQ!Ty~>aIW(TEGNANEOCV5p#olQ&V9Yv9Dk2T^)5-taitX85d_N6
zk#)@oxkYHmdpf#sfG3Pe`Z3gX7;;hq_}JnIIwA}SE$l}addo7La#cU7f_wVsJ|aFj
z+17BauD__OtHrrg*YF~rmvS_1p~P!A`wD0F0?vL{oNK5bqdT;@hHvv0&dmz0FE4LC
zD5aRFOJK<i!joG89)BLTk8tk{hJ^J}Q0h5MLo_IQZv2#%Hl54s(~pu#?o*E1FzFAR
z<T4(YTUsZdtOJ<}Qx>{hObzUIZ?<EpcRM(?&a^N`6Z{z2H9^GFz_&8&z<z=AhGGH1
zXWjK4FTi-6m<u*8IJr8lpo!E8qhAmAkW7o6e&wpl;7>%B;C~T&{zykc7d;lYaAPyr
zj51Z9#4ZX;!P|8Twi&cf^sb>^$HZRYOg+_m(sl_fB8pg)aLJA_nTNHd$&1MXkdR>+
z9vbJ7C(Z_88QAh^*cV|$vXqBCtHM*FUW&E%W2v9XSyddu^NC<|xdl387B<bZdxytz
zP_#IWfsgx0hDu*@NfQP|GoJCHwdpw}G&u}iJz21}*ypx}o2pvNDk(F@|8iU~ez5Ya
zUVBJ?X1{5bpL13H15ir?1QY-O00;nzZg5PkBwfcvlfeQg2ZJuGT4OD&v+x2c27eQx
za<G%k|J=kt9`7W?2U*OQkSz?w`Pt<8BlP&EyZ&6~YYGl`(%`LIB~Iq2K!>v@!nZUd
zakGq#a3-1p@c_*!>YUMwa)o*omm*STUc@tH1T3Fpe8Z{+x+gwd--!3|TxCXGdUj+l
z6QXn2M%5vzY$XiFjMKOb?VFZa*?(g_nwn9I+xwDK&J0AL^W79}5e%sTW;E`4Bj?FP
zsfm<enF75KS7o^&VhIG*1^T?k!GXyF49Y1++#td3fe|0q;59O^;H4CRDjZmWi5Dl3
zf&}V8ra8tMbO11H5pxt_PC;~aig^C~;k_{PrAlRegONZU0(xDbg#u%3@PCeY0hK7S
zws2Jk$Uz94Y>+_U;^vr<xQ28uG1|LCj>W~oz)D#LkRe4~fJjaxn>MO@Re%TQLo7-$
zaR84LfCI3gsi?l-lOfwcH({z75dz6$%4!Bw0AA^w>#WH-r~{D^2{CX8q(l;Q2!P@A
z$T;qKu;BU>BnR*)FZ3K7EPpMr(EyyV=w4^^h~-%pU729(;Dt~%bg&WeoC7KM8QP4z
zj+OAa4I3A60cLAz%e@AiFRZL;V^jxtCPukIFiAY^Q(s_5OMSoc#hsCfqsd@8`Exci
z`Ah$|AEu#RUV+9QaFFE@RfU!+#N5xFcMgtj^Stls4VEjBI^x*MxPKFCA)&K@Tp>v>
zMXQk7LjD3T!-q5p+fi;DT@0odoA`Y)4z(IGA&HVkkjZ*5<gOeYaS@|aq*|IHzEn<O
z1u)@SS7C~NAzVQQh8Mfb^vWUsWH5cQiTqChO;~7DoU!U;1V9r6O&~P93_?2sVWN2<
z^CguRz-$3-DvKOmPk#r~r<-`8`qrC7z3GVKZ3R;1IrtKChM~#TJYIlO&D2uf$JlLP
zT%HZ4&o*&+Ll8tC1mPeMVw;M1kOrd4qEH~Z^U9Pu4I3-vQ2Yi^9QA3Xw_EUT&&GWr
zg^_uT3`|kf3ZJA7yXS~qj}G_g$e*zS^zzNeYkt8F4FUU<K7WScs2wv9WyBZkxtuQ@
zdM^;Y9u<Bg+!o=scn6QG1b-i<r6?dE?j|lP$?A#vT6vtDoDHVm^k^jS6wOYuAC=?c
z?-Md2Ke`i0`5{@46vSQ;b`GuM12)z8f%*TYPt?9+7(>woA{roH098|}Je<_hN1_Nk
zLS1ZVcuqL>VSo7(Y!?%(D>w)we-6SimKPB^55b`HTNB@vO)eO*9$g^B&Ji&TOM0!!
zkv@(Pya-nXgrA`dAuub$sE8r350|pYuyEked&21T=mMd4f#?w&AqB!2GaO;z9E;qO
zu&6TPBq7&hK_*Wbvp!#im_0$v00=P?fo!oBzS170z<=mwvDVqp47|hhEgqB>egT=E
zFXJSFXCa09V8K>#xeQbJpy%_dFyKcO2yy`wgb-y?V+Ky)d7lovwcvyWClH(fa6b|_
zVZmY8o{7m3Ozp>)qt7sd5Xae?hKkP-*B-U#$CW_|3yLhxF~Ua@ht^6jFu1dsPiR6M
zi-7D9NPk+_{w$s^5YHa{z{mta*{r~V`r3#ZluI0rp(mJoN{n>D4g(O63#6{Bk}|xP
zN!5_@{0vd-QIxkH6k#*}xDXbKU?{tF1rnA0(io%sl)+CTsNm~e+Z$GBVxGNo45|R<
z(<>e|z%r>FuMt>0EmH0`V(prqyUfVazD}lW0)KVAp!haVfP)a(u5@t+L@IQ3yM(`x
zRJvq;$Z@b-L+S;Dj7zapNxrBOOcoQZ?}X%J+EAu$1AoYZg`7i7k;^PrrVSFZ^Ivoo
zU|#BA#%#`_7_g6L+>xN}>m}dAs{q^5LP+f{ps|BGZeG0w9L7yywiduH5daHOV<CG9
zDu3imSLMMqjwQ&qMZM|uG5-!LC3Py!WA7{)mD*9A?yhAqLX^fGoNka^t#TQafUv?5
zXY-_rz!>##Xk?*zY6JH>kWzcqfrP6A1&7vws0>6fgJa4-!Y=~_-7?U@VzHxWB(P`{
z99uLJP0=Vgv}h!HiblcyMI*7LXcY7ojel}0aDE<S8BdnO;%zRwm7P{W=gmevP>_^B
z+Tyrbdr>R64c`I}9cLQefQ5^>%4y@gMU`>olbD0#nAu(ok^;jnfEu(59xZ^(T;9Hl
zlLUmWrz*(BPy<S57HlX9)xZie$u_USCl=;Pnl97qlR3pRhN|7U&Z~sv3?kS<seeXz
z&~pQgO9{q@ihHfRG;sW2Mthg~V1)rFMWkjX06lDN2f;YF)QrV$J3hx7ov<kF))@vw
z%5ut%yB|1wEZwf4)@GMt_gWHR5eW7`;61-(JVqT0_pS8G*S4Bo%Wb=__ox&%af;P6
zaq{^yiuC8tr$Za8s&odNy_ewHW`BtaNZ@4>{|1($hc~nbEC1#(>r{SzSpR12QuYX6
zjK8{8HAXFPsM&%Btg{6TT?|Fc($%>IS|C5n-OZFM17U=F47?sp>j?f8A5~>DZ2PN-
z-$E1wJEny0u(n~xkY>0WGoLQQ-B7`rdP^UrILMMJ8sOk;PJRG?eJO0@hJVc$B<z8N
z3$X$d>Ld!`mKgOL`qL&Dz|H6ovRkmQMZ$ndn8bIFoDLg*K19OY;?b#ZM|bX;Rgg3B
z308ml%(b(G+|{xsgw37}C^&`?8M+{j0={K8a)X8w<o!KP*P|8nZG5)3F>7H*ROQ-2
z%cz|okz}?O8Mqg)!{BVg+J8)+vdtssu4n%PNrwP0fW8C=>kh`sw{Qm`7cg>S59F*F
zwkJdMftYTX({?Q20*qGc3w%@t7~qkoUB@5P)`-k~?F%@JrPU+U89#bq;9!DKK!yQ{
zd%596H(jJ3N#R3u=z0;*dh|U#8*)|HEvL3Etui!##&u9JehM%FaDV;j<_xk|Y|zMm
zuViv(EvwbXq40xaZa!{n;JF|O@80bW`eA9n%^E@|g={&-tgb~lV<VCZJ39i4oz$V#
zX$tIUu1sqYsR~Hx7w08bGte6VR#Cj5ET}G>Lhzz9mr$y9u!L0yFNSQjtZlyBChXw>
zI$RpbOi%)bVzXj{vwt^`99nAIsNF2}O5jh~P|y!(iJJB~(u+22M2&e<aoAQ_=<6Ep
zS711>so1GAkkhHF3M4l+(`QlO@gxQD4o@p(lo9~(c9OoGsx$4QxKJ1gt!oy4GO9Bt
zMO5Yz#N(BLe-$kbi!j7}bzLBzUVja?4z_{_F=GxDmzZ<L27h%hRNTSIWw{&$V0SWI
zatQ?_rAi>Z(4aj$$c5W8g+ec3CtNL+cQltG=hQ^NXpfaq0WN4YYRY`C3Nm2Q)dzc$
zUq>MD2+@!#61W3pvFU8qBI|4pp68h$XHo9s$Y!9feE<%@$@!a)*QaENs6f!9=A3!~
z07mQxhJou=8h@_$S>`c)VB80QBYwc|Mh_<P*h=?}IZSe`TdYN6MQ2VKFOK?zjg#x9
zqLe~|ajmTU9U5aT{BWw>TwWxSq!`GBF-U_48hgl=0%`7=#NiNHEq)id0HviYuzX#p
z9$#rRD+reAXu_GzEO0(Z!R(@)KbBY_d5j$tBY!2nWq-5#1%${W!p2(Dtj&`N8x6wm
zRRg1+ia+86yB0GIKD()i0!iYOncJHgei>yr7+GRDYAo3*@H0AVHR6uIu7%9`A;{Q-
zrbOc>xugt%R7_=LEZ&tXZKEI$L)S8AMRmDKU=$CVu#iIX4+v6xK-tQH9I!xMzkZF;
zEL|qmJ%5-lAq>RHUQRdu02Sa`9rz8E1-EU#{Rm;|Om0rjr=C4Vqg>Mlg}|s}!Bca8
z6!wv}eSp9UUhT|W8J@z>+Kl|3$(reo=@~S2An%L#mMUR9>_dLm;0!5%OxdX$^ubtJ
zv|%hzvX0>VXL}SddO`=lg1g;oR>Hm!Bw)zDH-AHr#{@hU&sSKmJe!Q{TTg@??OjE)
zJHj<vW3QR&$T5voLZpJ7VPGVDgjy9GY}axQ8~Uwsnt0ghJ^DYJ@T@WHh4{DSx{*X`
zd%YF{KSUy|RNYwbkU?UoWrG832;}8!`oabq0KW~^-iSV7l|hszIXc3m3Nl6_8Hx_<
z#(x-;8&JD74-3>Mr?vvuDNZK|;^#i40?i}k7D{z3xPA1V)^`rKbll{AGaN1pIg2~f
zm>&_8VX4QkwJtIA)a5_bD;v5((1F@Rr5{(??kQ*oof2)UlKsh8)b}WrIHIRb^_$4P
zc`$WCz(@sH_CDd=r(C1K4Rvi|<4P7(P=AA}izM3CoFC>YFUe)2_KBFrjkv~f65nRJ
zpsFf;nUTINcsgVWXCzb<P=dfI$V@fiiDWWBGIkqd>$BCa5#lFps|vUAJ##`}jYS%b
zRSfhb+V+gme&|K_VqSjh0!^E2)@0mUOdG-Tk)dzn!NHK%1WjJU!a>NO{%xHxVt*7W
zD-A(g$WFNNw%Mq11)aST_un;lyI+R?M~&s$Qos*bzCb#0uyelwu#O}tLxdnh*|7oV
zSpvu#TAqXqYKt!@Y*n6X=V9x!WES*ViAMy7jQ<3!zxB7|w(C9{2fp0L#qU~WHNH$5
z&UQA=^e6_GI3aC^SE%r(c3!9D9DffF`gb_TNynG@c`lLa4-P<w$hGT$xiW*?b!cO$
z3=6(Y(N@-2r#($kFgW3AK@(Fo(P`CJ?uoRQOD&HiVk;tOlkpMlJ$TrBKaKs8v*=b!
zf3agaZb1q`GgxSI7pLqB?7c`^VY4NFLi2AFV+Yi-g{^T(xdyu$_NJ!61%JzY^%oO)
zdz=N`37<C*%nt#sZT!_bjVgvEyp0)~Al1c|+q<to9vWlgH+R<gVKVbb$q;cvOQvMx
ztZV(1q5lt~JyFu75K3fJPBln+i7%t+cm6oASFh(v4n>18eI<?>xAY+g0j(x?UD9VB
zf|z(S0o`egfJ*lqPt=Y9w14@I#S1H$+n}Of=A^b&f2>=~t`J3M`aZ1gdf?fC>o(8U
zP2_3qKTsxOBAKm3nsrF@ORbRDx~CUd0>~7ETBI(p#%2eYwelnbSNce+wnikwU{lv|
zOd!U(I=G{PQh#SzK`qT4(70^E5=v!pbf^1G0vGUrWcpWT%kQpDtbex|JGY>jFPKtn
zcD0;z(3lc9>fIgfv}uPn#Rof{({>yuO@KkkH8VT3Oh0XCi&k(Ke%$EG0vX+-BX5L{
zeNA&$oHL=u+$J_S=x9qp{kLz`mK)q6`o4G2IjJdDk+9IgQOwgs9Wi4r6C1H}O6x${
zkiXuS$Qd=SoKq*8rGL&nMi*L_ZtmAkO}HswB%T|baDuQgEct1ZVx^+-0N-G8XV5aj
z4b}zTES6P1*Q~HshEGQntzO%$HZ{cufg9|yTfk+gB1|>p9Vc+pFj4m^IjzUP;;fZi
z28~tlECKsPH_dmQ3AI>&m$bPPUXLS1FEL=&xE828&35;!5r0E;>qk_z!=RE{pLP6*
z?`oV}id1_ii4;G$d0B!4<n)C~aa*|_u#XH@=_~r8C|4kWv3>J$T>~jZhxx&ZTjsK?
zXR5K6rAz8<)s2@rL9!yqu>jdS^9sLz{`V-JmyOK11i)|Hcs8?1*zA0V{Voq(hzy<8
zCpXX8>M!4c<9{%al{=2%AbsO*z-)s&xE}A7N~iVCt1-Om4t(JNCMr4xIiS5Z>r{aq
zj^=*KJr%TLLrwy(iW8SuK;yz6j||jdP{5<c-eeW$Q*i&ZJ#yz<v{zXTh%U2wn3MbL
z?riCweo}|!-YEf{lG&2Lom!vPM|N(GhkK=Z**6G@*MCpI47u@XDji-^ZUtttN@OwI
zvb%>`RE%xH3LKE}naKVQOUJeX=M9BgJH(rJs?+BWL<{`x87Y&8l5bBPM2t6VEYOIz
z{hucqd46N=4vtx!StT7np1S|f0$XpU3C?OsTh+r_uGI;rGT9{#Re(=RTXP~nr=V38
zFgO!d7=Hn(9w)?s;AG!e)<A%YJ2wA2O!}05ql}Ncr*U|D^mdGRPlo}|Yw*2YIh`%D
zBO6tTC|d!QaLgJ<$>XWt*5<-q8Qu}!>a~g7jce7jP>Wncctu5`IfQa|a9<i0z)JO=
z!sV*G*Wg6$^bvL38k&(qwb>SiCI8pnl|Hv|9Dn=o`&VqDasVheNJ?@Xrf3ySQL-wO
zloBD!DcOZu5=&|waF^KyNaB6S-~Ohrx%LD|>E)%uDqG|pGd(@MGkyHJXDfRv5U5OK
zjS*uu7ty(x`<qd2ibjAMNd7nz9N{tyejEwfPnNE01oeQ$qRlPt@oZ>JNL;6kX9DtD
z9DieVljzL6m|d>Gv12=PE;w-t15?likJIR^9G|jyfNLXb#~j<S;(tT_6nM9U1Ou_y
z74uGD{nc=tX12Ukt<e;#Wp_nxX!6a?v032+;YUzzwau~;H>7CsBbU+&i{E&Rp(QMs
zwjDfY31Lmp*a@-_g_R@(RpCnP(ED2MA%D1L%Cskh%|1xE=HTPpc+B(%6zD~wo4dJF
zwtu%J?4HE{G?MJT89}H~peQpWKF!Dg;{Jye`!_yqTxhBt+oA6V&?@ea*)3>)__+nJ
zV}Sp5flICIFqfGc;W|qRDoZNO73d>Ys=BuB_@zK&{9(bMvIMqKj^d!Pk4E)2_J4}`
zfGXoEwW)~B)f7Mk_F6^YKE)PP^9YPdG4n)`eYr;4%>qhBp54zGAL6|T8savY%t5uI
z1`T)pHM#zSG9qg$yvx;EkyneVf}jbEquJZjicytLcsp`xBJuvFwHtB=NWvbCm1yH}
z+rZ8CArm910Vu0}x;pC%2xd%|2Y>rPsD9Kp6-wGlAC}yqE@XG`HcO$jsnW)>RQ|{_
zwY;hOIbFau;D=nWGyi`0TXYloSGjBW@rWANkRnvr1Psf48gk&r>w2Kadl9AQYYq@o
zKT6{U&RT@=l`-0|{obi~@9<q-pn3!SIBcs#BJAsk$bnQ8y41JYMPA|6v42g55D@qb
z(O<=ZJDtHJ1SC{Ubf9M+da0OwxLiN`H?bldwoabFi+q(V`FAXg%)hI3ihjY2Y)=}n
z8a_V<N@QF}6X&p)Wcix^j4r{YrDf|%=?lJOQ5q-izzx!a9IYD)kAepPv@_YRzyQ^T
zU_&dDX($}pMBPiSUZOa$<bUwCHyR-&`{6f5FZ{-#Pzx43&>sv#M_`Z#j=)$F;0cU<
zr(-;Av!XiPHmNUEbBFh@*C_`mxGs(ri^JF?f}v|;y)~(SogL*qo}z?gIl^QWAN>M0
zLiyPf2)NKq{k-cMfMVRl87XYRd}2f<<n#tq%X)~8CAGsrZVm)NAb))4U}2(=o-{r?
z4j={MnY!R?A;=BFXb|<Lv-`Mnw@Qb2C>d5h@bZaX#X3If%{_k_;JY~kw-W5c%aVu$
z2Axt0C7}Byf?5|E!R1COY&$2b(>Anu^ATZ0Tt?wSgWYOm=EOpoMfoLbhn$#gXOi}t
zJzc!Magwcg>H<zuF@Nc$cD9@?L>3t|LdqnR$%3JZMQUH~3w{cnjBSa7cXxMWaCS)?
zl!u4L@5rO!IEj~iTKL03zoMkUbwJN4v6nvaU230gJF*=LF5(LxVwS7D;5sAaR-SdL
zyxcSWHLXf}y#+r~kcNM_RNUXKnLz?d@zm^hO}1=Fb;SpzoPUi;cx?_3;!B51sxARG
zghnP7F(;zJ=_3?T_3Lv0`ildlWNV@4I<s?+sfr~wqKno{$fND8Aa4O2Ax;;L{8eBO
zCGmlalYxWQHTNJ+7o`d3p7KfumZtdkQoZhy{*DP_<prfumG78RBS83dA-`I1d;nox
zCjo@#5T@0~%zs{1H0U{{0U!oRD~EkjRY2;`vlVOu_&r0g0BaN}%AIE5Cz-2edf&{I
zCKC4Xt?-ZGE+`(ZHmf@m#R6M8V3lfqkj(8jP_>1uYF3b0DYb|niypNu#>H~31Z5cR
z41xg1`l%N!lvpf#!?1T2FN-z&0ws(VN!<H&V3~67SAU`cq;qTchg^dPLVGQ*z{U&y
zu#j2Cj}}Kl*N{8F0-F9^`bR$`4`Lu!U8Ir0m5E%^jZLVv<_`8+IzWcqqx~l>?ejde
z_rQPSmjQowR70yuBz99aH?E+_YGh45rBi}Pr<O|GN^2q(e2X-bg6h0<Fyq}+%hmOH
zRK%$I7k?mf^>-0A=lZB|;fgpxELUsj4IautzPQ*)9BkG>s`?>)r1OgAE@L`5r;FDD
zE^p_#;G&j|-i&*BG5QYSL$uWf#w0DfG8~H9JR3d<vH}Aa>?uJ`Sfp*^m~h%Fxg=nK
zU&<}fJiYgEO+184qU4HzZqv(n#(!YuJ;Wv;wtqdV6B29qB_ZkHvDnf}A*A|Lc9kQP
zoI*Sgo*zO<42*41@<x<pWiyY&HLkfW6{T2H=hf>L7P?wRtlE#vp(}H6hqW52^;~{s
z!;%qR9Wd;$#BnJa3g<c1pGve<TAezqCME#Hp|f<ccH$_y$d@1r?P_0S@=C$6K%kYk
zS$}BTbuD(2yC{%~Z-{#BK><53hv(YVtqHqSnW`WoV7N3Cf55bC2p%fsA5M+J{CKuz
zwkOvT%?BX&w^gwObLU1QH1W&Ed?a;&%|eaq6AKt{YVetb(4uemh+TpcZH1^fjM{xm
z-+VW>?30piKxWGIg6tG3&N8FvuQOOcp?`2RfG=&dV2Adew5{Qi$IDeNnF};xO8g_j
zsPxi7*lfJG?5N@xJ%QOPy&nK|6Yuw045wYkvhucftGQ7xd>lU8u`eOEp-Tq=jdkOt
zyZQTZ8Q>?ANwuGr^vm*kW3Z)^_#@cC&6WYnWy(I*Wa)pHnCPQ%Ub&c~S8Btz-GAk#
z$cIK@qNNI1@f#SUzKOu{VHtC-g}RZI+SO96vnFdhtFl=A&T6dIjr*#yUj4pmE!eu=
zd`ot;@lQbC*_WB9!;>G5-%r2NME!6)J^lMvny8~658t1>KHh$!JeNaTLRrJP2;E>g
zTOON0aGb{SQZ2_KbaRm0|I`F=nST%v68#Oy6+-R>>5A!s<Z;UkhTBSk53@Y*3j(TX
z#8Yjv>o{iyf&Unz0`YPUs*`w%0skEVEK~hU$Z7yZ7F71U?0vQ%+ohrwQm#rAb+tOX
zC~dC(Fpo<Cq>+u6Z&2%@fB|#HPd3@OECrs(P>mb6N(zHt9Pr`@N3jO4bAMkD{6y_o
zr8BC=g?RvUgW$Z0(}L;WEr&{q5JA-o(?uog4xkabQ7)imeDHVxXUJLe46(VTs(Uyq
zg2<YfDzrJ5n_)#fj1~*PI$_mis>?-b2BLNctag`*cu_J;vxbcxIvUpu#|4O^u6i~s
zTF;?|CF7!H<sa|RFVD3%^?$C|XL8izX|aDNK_)95@%9O3A@1$$>`s1ub8?E$TWf7V
ztE6g5kou?(b7UFh=zKXc6OUYS@4`(`llXy&*DO?)U&MFtL`Bo?%g(|Lql^E!0zA95
z(AN`dc|XduLSs1F4wd%a(a3??!CM1wDRgUfiQ7`u@R*KBLTff9N`E?{WtMjzn)G5#
zz(!N^K+}S$OIF@m1L>1a4MN7%L$)WbwRX;SpW#N4Vh3Jje?ZJ-ocr`|B{9joy$eq&
z>zY#5VU{P$YMSww`Hh;xBcHLf#si46<_#@vww_n3*)<*41iI6ccHQZor#Y!E5LaTH
zm#$`El~&j`cR^Ph{C`EUZzOOA+K{AN1>P#$Te$z}n_L>sf0=KV^aH%^Z+)A232dHN
zxo?8T6^*$N?MJhW85P*c0UOuXD2>R5YFIu+n@ZJ4U3E7*KX{vZA4P4ckHF}ZF;u1k
zK$xFL?jo3zmbC9mDR9Q^oVe5Yb+w&6*6}NQprgt7Yjeu0R)6HOZ^@mZ1xec=05L!i
z6h{hTPC}gnARKBZEU{j-$)gnqGA1$L0*Mx&0W>-O;!wiXfm^#l^59XGWizx+bW5jA
z7?@(q8uaLQlU0#V)QUHW(;N0y1;L}>QT0lr?%>T=I#x1W#o^oRCJg@^?mpXp_H_U0
zpWqbj9m^u)^|N0lAqIc9J9W3e4yDx!!kg1qmHNRi!Rb29u8X7~K|JO9xfT|J3pa3<
zoOgPvS!n$LGix5CH;`;pePz}Tzqt;gMpafpzLo}JK4we#Xwf~kR4vZ4>-7fvwtJ)$
zsLkagtFSa~oZrL&Vj57h)yr$gZkPe3EJrHzY8Ql`C&l$5T1$T=qRP{baC-*zBIuSe
zh+m>47<qM&I;1O>S3^oWgs?$Ar$j>03qnUP(EB>+8k=nE%Pc^`%ejeNcK4^Fe3c^T
z4tICIj97=Q{TXfTRR{CH*8UW>b~zsqH|%oBFpa-6XH3+A?xdishpyTnQLA#ra4tgF
zrgQ*etPeW$x^{n2OlrlwUM;^2Io&ode9T_tbzGtZNYCTDJGF&hP5w3KV{$4$#x|B)
zU4OIIRmixL0#TpdWBPS|$oS%^i=FY#vmN!LAz6Y#<@>ot^0t<5u~5yB8kehulM=|>
z8_qihxC}{JO1DVy4d=4+f<`8*8|q`di5CEig?H>b&MSW!Tzm=XTkxoTMKfq3xOQEb
z#o3{^OKP*y+gilo$LaKMN*q3Z{5XDp{PWM_qjzs6|9bJ)4?mu~Iegne9R41jygr?V
z?_P#S@7_)ikEW+zLLA;7zt~P34&R>~zdhbe98T0L8;Ha7{ozl?C$HbW`dZ?!ah@+N
zN_6@h9A|%dThNKyXPBcpBFhvu*pVRkvWvhRxB}}M?*H@VlSiFhr(<3p925tKQFcz_
z`}X(We^+w`9Jb>h3SjLccpo$4GCZVY&Z+I`O`IkG<u_1G&@RrQpaB#iztTrFVn)AG
z2h@tMHtHf#wtPcP#4h!wr9#4p3)_tV-ZHw1?lOPOZWwV9#}O299PM^ZCj66PQWYFt
zs>``$^mHzTS2EHq=m}-uC`4=>DP$dgBT5*jLA4+6++Lv1OX_go*O+Igt2eZq0nE*E
zrF3hM!7gXPMd#;u^bgmCq)<3)>2fv$e0|+&$yZM)eUu|aS8&E?*K*>!-@$ZN;I6Bu
zlXHLQxF^b`+h8hDceh_wwwY2%qoUQ>#MvxeY8^_d3O}nRv+Z$Z%bxLZ3OM(Onl{;j
zly9nr(O)f=$(5Sm#d;8)MX+dLzN$SUIaEW}|453UP+KDS_E?hH^+4qZ2lh$Ubi5EU
zrrGC|q&&Q4#@T#`m**YN$3=}DGJ>-UIR1ZD&Lk^FkU_6@ix{>~I6`mPRmlDfLRR6R
zoAOzJSO`+rfb12a?kVJ+93lGwTo1RxW-Vt_6vY*{O;?HJE*2$VnXlsN#Q|Ke(ktM9
zz+^g?<Bed$`)rF)pT&b`8svtABxp?(K?!<yF>~uu=&GsV=WH=AcvbNjhIl?ap(uZh
z7PrwF2}0A3&X0y0i9RHZ(+=W}M_O35Z7Eq^k&xsgK6z|}WOrSG_I5xxDong1s}ngy
zBFXjfX4Huz7l)7@qxhf<a!!@-3h`pyr&8@^OvwnOUDE*7I?Yj$G37_8I*G{zf&<<p
zVNTZ{K{+s|Vx6tgQy{yzT^d-9&#-^Gm2BjfrVR9uj!c2NtDHgNnz3ec{C|~re7%5!
zdaKip{|5I?%&m?I$N1X6b*iyi;=ARAc5YHBoB&JxpSU7z_@%!0^>UaKs38FbD8EJ;
zbJYOvHR}(UbG(TFea$T3ZIWy`t<GA9tV3h`^vCV9TE`PFuQdxVqg)A;q_Tg~UtYSY
zTBlR0n{R6b9qQld<)X$jO9Kl!wB%69I#+qm(0h1PFq1kIjD>lS{{%r|x^r*ik_y-y
zLyjI}e^A*JgbT}U)Rbxl3DFHs8p`dIRfvlW>Q|y#kbBp{$@iTO>$c8o(<hrR@01?;
zQxe~rBc<r*LeLGyfk`&Z(tS`!F8pq^^JKL9t@?HU*<SczdSpKXXY6%9G+d;hbXMZ;
zzkk8EfCvg|JVd*>G8E}3@*JRoN`+V{%VMgU!G7rRabPClESs<4UwG;J;C}(LMlvji
z2sT-8Ol=s4l#_b7HUnq~tdrrq90`hUa7?WvUB^X}*ts?XgD$L-5xP17MUzarN&$qE
zm%3L0&Xe!DSpy<#0F&W{6O&%MN&`r20F&W{6O+EXNCUKi0F&W{6O$agNdX6wX1rPf
zg_FU&S_2D)0F&W{6O%lK3X?m%Km)^u0F&W{9g~~AKmkgV+`U}_RF#wOxfPR8zAXl2
Ixc~qF0Kxa8egFUf

delta 9881
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
LEe2+}000006Vb#}

-- 
GitLab