[Python-checkins] distutils2 (merge default -> default): Merge with changes by Vinay and Alexis

eric.araujo python-checkins at python.org
Wed Aug 31 16:25:13 CEST 2011


http://hg.python.org/distutils2/rev/fe1ca017e5ef
changeset:   1127:fe1ca017e5ef
parent:      1126:19f1583d18e4
parent:      1125:4f4cb7e8c0c4
user:        Éric Araujo <merwok at netwok.org>
date:        Sun Aug 28 01:57:22 2011 +0200
summary:
  Merge with changes by Vinay and Alexis

files:
  distutils2/README                                                                         |    13 -
  distutils2/__init__.py                                                                    |     6 +-
  distutils2/_trove.py                                                                      |  1088 +++---
  distutils2/command/__init__.py                                                            |    10 +-
  distutils2/command/bdist.py                                                               |    29 +-
  distutils2/command/bdist_dumb.py                                                          |    39 +-
  distutils2/command/bdist_msi.py                                                           |   121 +-
  distutils2/command/bdist_wininst.py                                                       |   142 +-
  distutils2/command/build.py                                                               |    10 +-
  distutils2/command/build_clib.py                                                          |    61 +-
  distutils2/command/build_ext.py                                                           |   160 +-
  distutils2/command/build_py.py                                                            |    55 +-
  distutils2/command/build_scripts.py                                                       |    93 +-
  distutils2/command/check.py                                                               |    44 +-
  distutils2/command/clean.py                                                               |    11 +-
  distutils2/command/cmd.py                                                                 |    96 +-
  distutils2/command/command_template                                                       |    13 +-
  distutils2/command/config.py                                                              |   100 +-
  distutils2/command/install_data.py                                                        |    48 +-
  distutils2/command/install_dist.py                                                        |    74 +-
  distutils2/command/install_distinfo.py                                                    |    62 +-
  distutils2/command/install_headers.py                                                     |    12 +-
  distutils2/command/install_lib.py                                                         |    38 +-
  distutils2/command/install_scripts.py                                                     |    23 +-
  distutils2/command/register.py                                                            |   111 +-
  distutils2/command/sdist.py                                                               |   109 +-
  distutils2/command/test.py                                                                |    30 +-
  distutils2/command/upload.py                                                              |   140 +-
  distutils2/command/upload_docs.py                                                         |   110 +-
  distutils2/command/wininst-10.0-amd64.exe                                                 |   Bin 
  distutils2/command/wininst-10.0.exe                                                       |   Bin 
  distutils2/compat.py                                                                      |    20 +-
  distutils2/compiler/__init__.py                                                           |    75 +-
  distutils2/compiler/bcppcompiler.py                                                       |   181 +-
  distutils2/compiler/ccompiler.py                                                          |   192 +-
  distutils2/compiler/cygwinccompiler.py                                                    |    73 +-
  distutils2/compiler/extension.py                                                          |    43 +-
  distutils2/compiler/msvc9compiler.py                                                      |   166 +-
  distutils2/compiler/msvccompiler.py                                                       |   282 +-
  distutils2/compiler/unixccompiler.py                                                      |    45 +-
  distutils2/config.py                                                                      |   200 +-
  distutils2/create.py                                                                      |   542 +-
  distutils2/database.py                                                                    |   647 ++++
  distutils2/depgraph.py                                                                    |   125 +-
  distutils2/dist.py                                                                        |   190 +-
  distutils2/errors.py                                                                      |    52 +-
  distutils2/fancy_getopt.py                                                                |   180 +-
  distutils2/install.py                                                                     |   391 +-
  distutils2/manifest.py                                                                    |   141 +-
  distutils2/markers.py                                                                     |    69 +-
  distutils2/metadata.py                                                                    |   160 +-
  distutils2/pypi/__init__.py                                                               |     6 +-
  distutils2/pypi/base.py                                                                   |     4 +-
  distutils2/pypi/dist.py                                                                   |    87 +-
  distutils2/pypi/errors.py                                                                 |    22 +-
  distutils2/pypi/mirrors.py                                                                |     8 +-
  distutils2/pypi/simple.py                                                                 |   183 +-
  distutils2/pypi/wrapper.py                                                                |    18 +-
  distutils2/pypi/xmlrpc.py                                                                 |    41 +-
  distutils2/resources.py                                                                   |    25 -
  distutils2/run.py                                                                         |   568 ++-
  distutils2/tests/__init__.py                                                              |    54 +-
  distutils2/tests/__main__.py                                                              |    23 +
  distutils2/tests/fake_dists/babar-0.1.dist-info/INSTALLER                                 |   Bin 
  distutils2/tests/fake_dists/babar-0.1.dist-info/METADATA                                  |     4 +
  distutils2/tests/fake_dists/babar-0.1.dist-info/RECORD                                    |   Bin 
  distutils2/tests/fake_dists/babar-0.1.dist-info/REQUESTED                                 |   Bin 
  distutils2/tests/fake_dists/babar-0.1.dist-info/RESOURCES                                 |     2 +
  distutils2/tests/fake_dists/babar.cfg                                                     |     1 +
  distutils2/tests/fake_dists/babar.png                                                     |   Bin 
  distutils2/tests/fake_dists/bacon-0.1.egg-info/PKG-INFO                                   |     6 +
  distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/PKG-INFO                              |    18 +
  distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/SOURCES.txt                           |   Bin 
  distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/dependency_links.txt                  |     1 +
  distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/entry_points.txt                      |     3 +
  distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/not-zip-safe                          |     1 +
  distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/requires.txt                          |     6 +
  distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/top_level.txt                         |   Bin 
  distutils2/tests/fake_dists/cheese-2.0.2.egg-info                                         |     5 +
  distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/INSTALLER                            |   Bin 
  distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/METADATA                             |     9 +
  distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/RECORD                               |   Bin 
  distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/REQUESTED                            |   Bin 
  distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/__init__.py                             |     1 +
  distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/chocolate.py                            |    10 +
  distutils2/tests/fake_dists/choxie-2.0.0.9/truffles.py                                    |     5 +
  distutils2/tests/fake_dists/coconuts-aster-10.3.egg-info/PKG-INFO                         |     5 +
  distutils2/tests/fake_dists/grammar-1.0a4.dist-info/INSTALLER                             |   Bin 
  distutils2/tests/fake_dists/grammar-1.0a4.dist-info/METADATA                              |     5 +
  distutils2/tests/fake_dists/grammar-1.0a4.dist-info/RECORD                                |   Bin 
  distutils2/tests/fake_dists/grammar-1.0a4.dist-info/REQUESTED                             |   Bin 
  distutils2/tests/fake_dists/grammar-1.0a4/grammar/__init__.py                             |     1 +
  distutils2/tests/fake_dists/grammar-1.0a4/grammar/utils.py                                |     8 +
  distutils2/tests/fake_dists/nut-funkyversion.egg-info                                     |     3 +
  distutils2/tests/fake_dists/strawberry-0.6.egg                                            |   Bin 
  distutils2/tests/fake_dists/towel_stuff-0.1.dist-info/INSTALLER                           |   Bin 
  distutils2/tests/fake_dists/towel_stuff-0.1.dist-info/METADATA                            |     7 +
  distutils2/tests/fake_dists/towel_stuff-0.1.dist-info/RECORD                              |   Bin 
  distutils2/tests/fake_dists/towel_stuff-0.1.dist-info/REQUESTED                           |   Bin 
  distutils2/tests/fake_dists/towel_stuff-0.1/towel_stuff/__init__.py                       |    18 +
  distutils2/tests/fake_dists/truffles-5.0.egg-info                                         |     3 +
  distutils2/tests/fixer/fix_idioms.py                                                      |    18 +-
  distutils2/tests/pypi_server.py                                                           |    96 +-
  distutils2/tests/pypi_test_server.py                                                      |    59 +
  distutils2/tests/pypiserver/downloads_with_md5/packages/source/f/foobar/foobar-0.1.tar.gz |   Bin 
  distutils2/tests/pypiserver/downloads_with_md5/simple/foobar/foobar-0.1.tar.gz            |   Bin 
  distutils2/tests/pypiserver/downloads_with_md5/simple/foobar/index.html                   |     2 +-
  distutils2/tests/support.py                                                               |   433 ++-
  distutils2/tests/test_ccompiler.py                                                        |     8 +-
  distutils2/tests/test_command_bdist.py                                                    |     6 +-
  distutils2/tests/test_command_bdist_dumb.py                                               |    36 +-
  distutils2/tests/test_command_bdist_msi.py                                                |     7 +-
  distutils2/tests/test_command_bdist_wininst.py                                            |     9 +-
  distutils2/tests/test_command_build.py                                                    |     6 +-
  distutils2/tests/test_command_build_clib.py                                               |    43 +-
  distutils2/tests/test_command_build_ext.py                                                |   272 +-
  distutils2/tests/test_command_build_py.py                                                 |    34 +-
  distutils2/tests/test_command_build_scripts.py                                            |    23 +-
  distutils2/tests/test_command_check.py                                                    |    78 +-
  distutils2/tests/test_command_clean.py                                                    |    15 +-
  distutils2/tests/test_command_cmd.py                                                      |    31 +-
  distutils2/tests/test_command_config.py                                                   |    23 +-
  distutils2/tests/test_command_install_data.py                                             |    45 +-
  distutils2/tests/test_command_install_dist.py                                             |    52 +-
  distutils2/tests/test_command_install_distinfo.py                                         |    52 +-
  distutils2/tests/test_command_install_headers.py                                          |     5 +-
  distutils2/tests/test_command_install_lib.py                                              |    47 +-
  distutils2/tests/test_command_install_scripts.py                                          |    29 +-
  distutils2/tests/test_command_register.py                                                 |    95 +-
  distutils2/tests/test_command_sdist.py                                                    |   177 +-
  distutils2/tests/test_command_test.py                                                     |   105 +-
  distutils2/tests/test_command_upload.py                                                   |    54 +-
  distutils2/tests/test_command_upload_docs.py                                              |   116 +-
  distutils2/tests/test_compiler.py                                                         |    16 +-
  distutils2/tests/test_config.py                                                           |   248 +-
  distutils2/tests/test_create.py                                                           |   280 +-
  distutils2/tests/test_cygwinccompiler.py                                                  |    27 +-
  distutils2/tests/test_database.py                                                         |   674 ++++
  distutils2/tests/test_depgraph.py                                                         |   124 +-
  distutils2/tests/test_dist.py                                                             |   198 +-
  distutils2/tests/test_extension.py                                                        |     2 +-
  distutils2/tests/test_install.py                                                          |   177 +-
  distutils2/tests/test_manifest.py                                                         |    80 +-
  distutils2/tests/test_markers.py                                                          |    16 +-
  distutils2/tests/test_metadata.py                                                         |    75 +-
  distutils2/tests/test_mixin2to3.py                                                        |    90 +-
  distutils2/tests/test_msvc9compiler.py                                                    |    43 +-
  distutils2/tests/test_pypi_dist.py                                                        |    81 +-
  distutils2/tests/test_pypi_server.py                                                      |    80 +-
  distutils2/tests/test_pypi_simple.py                                                      |   145 +-
  distutils2/tests/test_pypi_xmlrpc.py                                                      |    56 +-
  distutils2/tests/test_resources.py                                                        |   174 -
  distutils2/tests/test_run.py                                                              |    40 +-
  distutils2/tests/test_uninstall.py                                                        |    99 +-
  distutils2/tests/test_unixccompiler.py                                                    |    25 +-
  distutils2/tests/test_util.py                                                             |   551 +++-
  distutils2/tests/test_version.py                                                          |    19 +-
  distutils2/tests/xxmodule.c                                                               |   379 --
  distutils2/util.py                                                                        |  1447 ++++++++-
  distutils2/version.py                                                                     |    16 +-
  scripts/pysetup                                                                           |     4 +
  setup.py                                                                                  |     6 +-
  sysconfig.cfg                                                                             |   111 +
  sysconfig.py                                                                              |   766 +++++
  test_distutils2.py                                                                        |     5 +
  165 files changed, 9733 insertions(+), 6080 deletions(-)


diff --git a/distutils2/README b/distutils2/README
deleted file mode 100644
--- a/distutils2/README
+++ /dev/null
@@ -1,13 +0,0 @@
-This directory contains the Distutils2 package.
-
-There's a full documentation available at:
-
-    http://docs.python.org/distutils/
-
-The Distutils-SIG web page is also a good starting point:
-
-    http://www.python.org/sigs/distutils-sig/
-
-WARNING: Distutils2 must remain compatible with Python 2.4
-
-$Id: README 70017 2009-02-27 12:53:34Z tarek.ziade $
diff --git a/distutils2/__init__.py b/distutils2/__init__.py
--- a/distutils2/__init__.py
+++ b/distutils2/__init__.py
@@ -1,12 +1,14 @@
-"""distutils
+"""Support for distutils2, distribution and installation of Python projects.
 
-Third-party tools can use parts of Distutils2 as building blocks
+Third-party tools can use parts of distutils2 as building blocks
 without causing the other modules to be imported:
 
     import distutils2.version
+    import distutils2.metadata
     import distutils2.pypi.simple
     import distutils2.tests.pypi_server
 """
+
 from logging import getLogger
 
 __all__ = ['__version__', 'logger']
diff --git a/distutils2/_trove.py b/distutils2/_trove.py
--- a/distutils2/_trove.py
+++ b/distutils2/_trove.py
@@ -1,4 +1,4 @@
-# Temporary helper for mkcfg.
+"""Temporary helper for create."""
 
 # XXX get the list from PyPI and cache it instead of hardcoding
 
@@ -6,547 +6,547 @@
 # than a list of strings
 
 all_classifiers = [
-    'Development Status :: 1 - Planning',
-    'Development Status :: 2 - Pre-Alpha',
-    'Development Status :: 3 - Alpha',
-    'Development Status :: 4 - Beta',
-    'Development Status :: 5 - Production/Stable',
-    'Development Status :: 6 - Mature',
-    'Development Status :: 7 - Inactive',
-    'Environment :: Console',
-    'Environment :: Console :: Curses',
-    'Environment :: Console :: Framebuffer',
-    'Environment :: Console :: Newt',
-    'Environment :: Console :: svgalib',
-    "Environment :: Handhelds/PDA's",
-    'Environment :: MacOS X',
-    'Environment :: MacOS X :: Aqua',
-    'Environment :: MacOS X :: Carbon',
-    'Environment :: MacOS X :: Cocoa',
-    'Environment :: No Input/Output (Daemon)',
-    'Environment :: Other Environment',
-    'Environment :: Plugins',
-    'Environment :: Web Environment',
-    'Environment :: Web Environment :: Buffet',
-    'Environment :: Web Environment :: Mozilla',
-    'Environment :: Web Environment :: ToscaWidgets',
-    'Environment :: Win32 (MS Windows)',
-    'Environment :: X11 Applications',
-    'Environment :: X11 Applications :: Gnome',
-    'Environment :: X11 Applications :: GTK',
-    'Environment :: X11 Applications :: KDE',
-    'Environment :: X11 Applications :: Qt',
-    'Framework :: BFG',
-    'Framework :: Buildout',
-    'Framework :: Chandler',
-    'Framework :: CubicWeb',
-    'Framework :: Django',
-    'Framework :: IDLE',
-    'Framework :: Paste',
-    'Framework :: Plone',
-    'Framework :: Pylons',
-    'Framework :: Setuptools Plugin',
-    'Framework :: Trac',
-    'Framework :: TurboGears',
-    'Framework :: TurboGears :: Applications',
-    'Framework :: TurboGears :: Widgets',
-    'Framework :: Twisted',
-    'Framework :: ZODB',
-    'Framework :: Zope2',
-    'Framework :: Zope3',
-    'Intended Audience :: Customer Service',
-    'Intended Audience :: Developers',
-    'Intended Audience :: Education',
-    'Intended Audience :: End Users/Desktop',
-    'Intended Audience :: Financial and Insurance Industry',
-    'Intended Audience :: Healthcare Industry',
-    'Intended Audience :: Information Technology',
-    'Intended Audience :: Legal Industry',
-    'Intended Audience :: Manufacturing',
-    'Intended Audience :: Other Audience',
-    'Intended Audience :: Religion',
-    'Intended Audience :: Science/Research',
-    'Intended Audience :: System Administrators',
-    'Intended Audience :: Telecommunications Industry',
-    'License :: Aladdin Free Public License (AFPL)',
-    'License :: DFSG approved',
-    'License :: Eiffel Forum License (EFL)',
-    'License :: Free For Educational Use',
-    'License :: Free For Home Use',
-    'License :: Free for non-commercial use',
-    'License :: Freely Distributable',
-    'License :: Free To Use But Restricted',
-    'License :: Freeware',
-    'License :: Netscape Public License (NPL)',
-    'License :: Nokia Open Source License (NOKOS)',
-    'License :: OSI Approved',
-    'License :: OSI Approved :: Academic Free License (AFL)',
-    'License :: OSI Approved :: Apache Software License',
-    'License :: OSI Approved :: Apple Public Source License',
-    'License :: OSI Approved :: Artistic License',
-    'License :: OSI Approved :: Attribution Assurance License',
-    'License :: OSI Approved :: BSD License',
-    'License :: OSI Approved :: Common Public License',
-    'License :: OSI Approved :: Eiffel Forum License',
-    'License :: OSI Approved :: European Union Public Licence 1.0 (EUPL 1.0)',
-    'License :: OSI Approved :: European Union Public Licence 1.1 (EUPL 1.1)',
-    'License :: OSI Approved :: GNU Affero General Public License v3',
-    'License :: OSI Approved :: GNU Free Documentation License (FDL)',
-    'License :: OSI Approved :: GNU General Public License (GPL)',
-    'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
-    'License :: OSI Approved :: IBM Public License',
-    'License :: OSI Approved :: Intel Open Source License',
-    'License :: OSI Approved :: ISC License (ISCL)',
-    'License :: OSI Approved :: Jabber Open Source License',
-    'License :: OSI Approved :: MIT License',
-    'License :: OSI Approved :: MITRE Collaborative Virtual Workspace License (CVW)',
-    'License :: OSI Approved :: Motosoto License',
-    'License :: OSI Approved :: Mozilla Public License 1.0 (MPL)',
-    'License :: OSI Approved :: Mozilla Public License 1.1 (MPL 1.1)',
-    'License :: OSI Approved :: Nethack General Public License',
-    'License :: OSI Approved :: Nokia Open Source License',
-    'License :: OSI Approved :: Open Group Test Suite License',
-    'License :: OSI Approved :: Python License (CNRI Python License)',
-    'License :: OSI Approved :: Python Software Foundation License',
-    'License :: OSI Approved :: Qt Public License (QPL)',
-    'License :: OSI Approved :: Ricoh Source Code Public License',
-    'License :: OSI Approved :: Sleepycat License',
-    'License :: OSI Approved :: Sun Industry Standards Source License (SISSL)',
-    'License :: OSI Approved :: Sun Public License',
-    'License :: OSI Approved :: University of Illinois/NCSA Open Source License',
-    'License :: OSI Approved :: Vovida Software License 1.0',
-    'License :: OSI Approved :: W3C License',
-    'License :: OSI Approved :: X.Net License',
-    'License :: OSI Approved :: zlib/libpng License',
-    'License :: OSI Approved :: Zope Public License',
-    'License :: Other/Proprietary License',
-    'License :: Public Domain',
-    'License :: Repoze Public License',
-    'Natural Language :: Afrikaans',
-    'Natural Language :: Arabic',
-    'Natural Language :: Bengali',
-    'Natural Language :: Bosnian',
-    'Natural Language :: Bulgarian',
-    'Natural Language :: Catalan',
-    'Natural Language :: Chinese (Simplified)',
-    'Natural Language :: Chinese (Traditional)',
-    'Natural Language :: Croatian',
-    'Natural Language :: Czech',
-    'Natural Language :: Danish',
-    'Natural Language :: Dutch',
-    'Natural Language :: English',
-    'Natural Language :: Esperanto',
-    'Natural Language :: Finnish',
-    'Natural Language :: French',
-    'Natural Language :: German',
-    'Natural Language :: Greek',
-    'Natural Language :: Hebrew',
-    'Natural Language :: Hindi',
-    'Natural Language :: Hungarian',
-    'Natural Language :: Icelandic',
-    'Natural Language :: Indonesian',
-    'Natural Language :: Italian',
-    'Natural Language :: Japanese',
-    'Natural Language :: Javanese',
-    'Natural Language :: Korean',
-    'Natural Language :: Latin',
-    'Natural Language :: Latvian',
-    'Natural Language :: Macedonian',
-    'Natural Language :: Malay',
-    'Natural Language :: Marathi',
-    'Natural Language :: Norwegian',
-    'Natural Language :: Panjabi',
-    'Natural Language :: Persian',
-    'Natural Language :: Polish',
-    'Natural Language :: Portuguese',
-    'Natural Language :: Portuguese (Brazilian)',
-    'Natural Language :: Romanian',
-    'Natural Language :: Russian',
-    'Natural Language :: Serbian',
-    'Natural Language :: Slovak',
-    'Natural Language :: Slovenian',
-    'Natural Language :: Spanish',
-    'Natural Language :: Swedish',
-    'Natural Language :: Tamil',
-    'Natural Language :: Telugu',
-    'Natural Language :: Thai',
-    'Natural Language :: Turkish',
-    'Natural Language :: Ukranian',
-    'Natural Language :: Urdu',
-    'Natural Language :: Vietnamese',
-    'Operating System :: BeOS',
-    'Operating System :: MacOS',
-    'Operating System :: MacOS :: MacOS 9',
-    'Operating System :: MacOS :: MacOS X',
-    'Operating System :: Microsoft',
-    'Operating System :: Microsoft :: MS-DOS',
-    'Operating System :: Microsoft :: Windows',
-    'Operating System :: Microsoft :: Windows :: Windows 3.1 or Earlier',
-    'Operating System :: Microsoft :: Windows :: Windows 95/98/2000',
-    'Operating System :: Microsoft :: Windows :: Windows CE',
-    'Operating System :: Microsoft :: Windows :: Windows NT/2000',
-    'Operating System :: OS/2',
-    'Operating System :: OS Independent',
-    'Operating System :: Other OS',
-    'Operating System :: PalmOS',
-    'Operating System :: PDA Systems',
-    'Operating System :: POSIX',
-    'Operating System :: POSIX :: AIX',
-    'Operating System :: POSIX :: BSD',
-    'Operating System :: POSIX :: BSD :: BSD/OS',
-    'Operating System :: POSIX :: BSD :: FreeBSD',
-    'Operating System :: POSIX :: BSD :: NetBSD',
-    'Operating System :: POSIX :: BSD :: OpenBSD',
-    'Operating System :: POSIX :: GNU Hurd',
-    'Operating System :: POSIX :: HP-UX',
-    'Operating System :: POSIX :: IRIX',
-    'Operating System :: POSIX :: Linux',
-    'Operating System :: POSIX :: Other',
-    'Operating System :: POSIX :: SCO',
-    'Operating System :: POSIX :: SunOS/Solaris',
-    'Operating System :: Unix',
-    'Programming Language :: Ada',
-    'Programming Language :: APL',
-    'Programming Language :: ASP',
-    'Programming Language :: Assembly',
-    'Programming Language :: Awk',
-    'Programming Language :: Basic',
-    'Programming Language :: C',
-    'Programming Language :: C#',
-    'Programming Language :: C++',
-    'Programming Language :: Cold Fusion',
-    'Programming Language :: Cython',
-    'Programming Language :: Delphi/Kylix',
-    'Programming Language :: Dylan',
-    'Programming Language :: Eiffel',
-    'Programming Language :: Emacs-Lisp',
-    'Programming Language :: Erlang',
-    'Programming Language :: Euler',
-    'Programming Language :: Euphoria',
-    'Programming Language :: Forth',
-    'Programming Language :: Fortran',
-    'Programming Language :: Haskell',
-    'Programming Language :: Java',
-    'Programming Language :: JavaScript',
-    'Programming Language :: Lisp',
-    'Programming Language :: Logo',
-    'Programming Language :: ML',
-    'Programming Language :: Modula',
-    'Programming Language :: Objective C',
-    'Programming Language :: Object Pascal',
-    'Programming Language :: OCaml',
-    'Programming Language :: Other',
-    'Programming Language :: Other Scripting Engines',
-    'Programming Language :: Pascal',
-    'Programming Language :: Perl',
-    'Programming Language :: PHP',
-    'Programming Language :: Pike',
-    'Programming Language :: Pliant',
-    'Programming Language :: PL/SQL',
-    'Programming Language :: PROGRESS',
-    'Programming Language :: Prolog',
-    'Programming Language :: Python',
-    'Programming Language :: Python :: 2',
-    'Programming Language :: Python :: 2.3',
-    'Programming Language :: Python :: 2.4',
-    'Programming Language :: Python :: 2.5',
-    'Programming Language :: Python :: 2.6',
-    'Programming Language :: Python :: 2.7',
-    'Programming Language :: Python :: 3',
-    'Programming Language :: Python :: 3.0',
-    'Programming Language :: Python :: 3.1',
-    'Programming Language :: Python :: 3.2',
-    'Programming Language :: REBOL',
-    'Programming Language :: Rexx',
-    'Programming Language :: Ruby',
-    'Programming Language :: Scheme',
-    'Programming Language :: Simula',
-    'Programming Language :: Smalltalk',
-    'Programming Language :: SQL',
-    'Programming Language :: Tcl',
-    'Programming Language :: Unix Shell',
-    'Programming Language :: Visual Basic',
-    'Programming Language :: XBasic',
-    'Programming Language :: YACC',
-    'Programming Language :: Zope',
-    'Topic :: Adaptive Technologies',
-    'Topic :: Artistic Software',
-    'Topic :: Communications',
-    'Topic :: Communications :: BBS',
-    'Topic :: Communications :: Chat',
-    'Topic :: Communications :: Chat :: AOL Instant Messenger',
-    'Topic :: Communications :: Chat :: ICQ',
-    'Topic :: Communications :: Chat :: Internet Relay Chat',
-    'Topic :: Communications :: Chat :: Unix Talk',
-    'Topic :: Communications :: Conferencing',
-    'Topic :: Communications :: Email',
-    'Topic :: Communications :: Email :: Address Book',
-    'Topic :: Communications :: Email :: Email Clients (MUA)',
-    'Topic :: Communications :: Email :: Filters',
-    'Topic :: Communications :: Email :: Mailing List Servers',
-    'Topic :: Communications :: Email :: Mail Transport Agents',
-    'Topic :: Communications :: Email :: Post-Office',
-    'Topic :: Communications :: Email :: Post-Office :: IMAP',
-    'Topic :: Communications :: Email :: Post-Office :: POP3',
-    'Topic :: Communications :: Fax',
-    'Topic :: Communications :: FIDO',
-    'Topic :: Communications :: File Sharing',
-    'Topic :: Communications :: File Sharing :: Gnutella',
-    'Topic :: Communications :: File Sharing :: Napster',
-    'Topic :: Communications :: Ham Radio',
-    'Topic :: Communications :: Internet Phone',
-    'Topic :: Communications :: Telephony',
-    'Topic :: Communications :: Usenet News',
-    'Topic :: Database',
-    'Topic :: Database :: Database Engines/Servers',
-    'Topic :: Database :: Front-Ends',
-    'Topic :: Desktop Environment',
-    'Topic :: Desktop Environment :: File Managers',
-    'Topic :: Desktop Environment :: Gnome',
-    'Topic :: Desktop Environment :: GNUstep',
-    'Topic :: Desktop Environment :: K Desktop Environment (KDE)',
-    'Topic :: Desktop Environment :: K Desktop Environment (KDE) :: Themes',
-    'Topic :: Desktop Environment :: PicoGUI',
-    'Topic :: Desktop Environment :: PicoGUI :: Applications',
-    'Topic :: Desktop Environment :: PicoGUI :: Themes',
-    'Topic :: Desktop Environment :: Screen Savers',
-    'Topic :: Desktop Environment :: Window Managers',
-    'Topic :: Desktop Environment :: Window Managers :: Afterstep',
-    'Topic :: Desktop Environment :: Window Managers :: Afterstep :: Themes',
-    'Topic :: Desktop Environment :: Window Managers :: Applets',
-    'Topic :: Desktop Environment :: Window Managers :: Blackbox',
-    'Topic :: Desktop Environment :: Window Managers :: Blackbox :: Themes',
-    'Topic :: Desktop Environment :: Window Managers :: CTWM',
-    'Topic :: Desktop Environment :: Window Managers :: CTWM :: Themes',
-    'Topic :: Desktop Environment :: Window Managers :: Enlightenment',
-    'Topic :: Desktop Environment :: Window Managers :: Enlightenment :: Epplets',
-    'Topic :: Desktop Environment :: Window Managers :: Enlightenment :: Themes DR15',
-    'Topic :: Desktop Environment :: Window Managers :: Enlightenment :: Themes DR16',
-    'Topic :: Desktop Environment :: Window Managers :: Enlightenment :: Themes DR17',
-    'Topic :: Desktop Environment :: Window Managers :: Fluxbox',
-    'Topic :: Desktop Environment :: Window Managers :: Fluxbox :: Themes',
-    'Topic :: Desktop Environment :: Window Managers :: FVWM',
-    'Topic :: Desktop Environment :: Window Managers :: FVWM :: Themes',
-    'Topic :: Desktop Environment :: Window Managers :: IceWM',
-    'Topic :: Desktop Environment :: Window Managers :: IceWM :: Themes',
-    'Topic :: Desktop Environment :: Window Managers :: MetaCity',
-    'Topic :: Desktop Environment :: Window Managers :: MetaCity :: Themes',
-    'Topic :: Desktop Environment :: Window Managers :: Oroborus',
-    'Topic :: Desktop Environment :: Window Managers :: Oroborus :: Themes',
-    'Topic :: Desktop Environment :: Window Managers :: Sawfish',
-    'Topic :: Desktop Environment :: Window Managers :: Sawfish :: Themes 0.30',
-    'Topic :: Desktop Environment :: Window Managers :: Sawfish :: Themes pre-0.30',
-    'Topic :: Desktop Environment :: Window Managers :: Waimea',
-    'Topic :: Desktop Environment :: Window Managers :: Waimea :: Themes',
-    'Topic :: Desktop Environment :: Window Managers :: Window Maker',
-    'Topic :: Desktop Environment :: Window Managers :: Window Maker :: Applets',
-    'Topic :: Desktop Environment :: Window Managers :: Window Maker :: Themes',
-    'Topic :: Desktop Environment :: Window Managers :: XFCE',
-    'Topic :: Desktop Environment :: Window Managers :: XFCE :: Themes',
-    'Topic :: Documentation',
-    'Topic :: Education',
-    'Topic :: Education :: Computer Aided Instruction (CAI)',
-    'Topic :: Education :: Testing',
-    'Topic :: Games/Entertainment',
-    'Topic :: Games/Entertainment :: Arcade',
-    'Topic :: Games/Entertainment :: Board Games',
-    'Topic :: Games/Entertainment :: First Person Shooters',
-    'Topic :: Games/Entertainment :: Fortune Cookies',
-    'Topic :: Games/Entertainment :: Multi-User Dungeons (MUD)',
-    'Topic :: Games/Entertainment :: Puzzle Games',
-    'Topic :: Games/Entertainment :: Real Time Strategy',
-    'Topic :: Games/Entertainment :: Role-Playing',
-    'Topic :: Games/Entertainment :: Side-Scrolling/Arcade Games',
-    'Topic :: Games/Entertainment :: Simulation',
-    'Topic :: Games/Entertainment :: Turn Based Strategy',
-    'Topic :: Home Automation',
-    'Topic :: Internet',
-    'Topic :: Internet :: File Transfer Protocol (FTP)',
-    'Topic :: Internet :: Finger',
-    'Topic :: Internet :: Log Analysis',
-    'Topic :: Internet :: Name Service (DNS)',
-    'Topic :: Internet :: Proxy Servers',
-    'Topic :: Internet :: WAP',
-    'Topic :: Internet :: WWW/HTTP',
-    'Topic :: Internet :: WWW/HTTP :: Browsers',
-    'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
-    'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries',
-    'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Message Boards',
-    'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: News/Diary',
-    'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Page Counters',
-    'Topic :: Internet :: WWW/HTTP :: HTTP Servers',
-    'Topic :: Internet :: WWW/HTTP :: Indexing/Search',
-    'Topic :: Internet :: WWW/HTTP :: Site Management',
-    'Topic :: Internet :: WWW/HTTP :: Site Management :: Link Checking',
-    'Topic :: Internet :: WWW/HTTP :: WSGI',
-    'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
-    'Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware',
-    'Topic :: Internet :: WWW/HTTP :: WSGI :: Server',
-    'Topic :: Internet :: Z39.50',
-    'Topic :: Multimedia',
-    'Topic :: Multimedia :: Graphics',
-    'Topic :: Multimedia :: Graphics :: 3D Modeling',
-    'Topic :: Multimedia :: Graphics :: 3D Rendering',
-    'Topic :: Multimedia :: Graphics :: Capture',
-    'Topic :: Multimedia :: Graphics :: Capture :: Digital Camera',
-    'Topic :: Multimedia :: Graphics :: Capture :: Scanners',
-    'Topic :: Multimedia :: Graphics :: Capture :: Screen Capture',
-    'Topic :: Multimedia :: Graphics :: Editors',
-    'Topic :: Multimedia :: Graphics :: Editors :: Raster-Based',
-    'Topic :: Multimedia :: Graphics :: Editors :: Vector-Based',
-    'Topic :: Multimedia :: Graphics :: Graphics Conversion',
-    'Topic :: Multimedia :: Graphics :: Presentation',
-    'Topic :: Multimedia :: Graphics :: Viewers',
-    'Topic :: Multimedia :: Sound/Audio',
-    'Topic :: Multimedia :: Sound/Audio :: Analysis',
-    'Topic :: Multimedia :: Sound/Audio :: Capture/Recording',
-    'Topic :: Multimedia :: Sound/Audio :: CD Audio',
-    'Topic :: Multimedia :: Sound/Audio :: CD Audio :: CD Playing',
-    'Topic :: Multimedia :: Sound/Audio :: CD Audio :: CD Ripping',
-    'Topic :: Multimedia :: Sound/Audio :: CD Audio :: CD Writing',
-    'Topic :: Multimedia :: Sound/Audio :: Conversion',
-    'Topic :: Multimedia :: Sound/Audio :: Editors',
-    'Topic :: Multimedia :: Sound/Audio :: MIDI',
-    'Topic :: Multimedia :: Sound/Audio :: Mixers',
-    'Topic :: Multimedia :: Sound/Audio :: Players',
-    'Topic :: Multimedia :: Sound/Audio :: Players :: MP3',
-    'Topic :: Multimedia :: Sound/Audio :: Sound Synthesis',
-    'Topic :: Multimedia :: Sound/Audio :: Speech',
-    'Topic :: Multimedia :: Video',
-    'Topic :: Multimedia :: Video :: Capture',
-    'Topic :: Multimedia :: Video :: Conversion',
-    'Topic :: Multimedia :: Video :: Display',
-    'Topic :: Multimedia :: Video :: Non-Linear Editor',
-    'Topic :: Office/Business',
-    'Topic :: Office/Business :: Financial',
-    'Topic :: Office/Business :: Financial :: Accounting',
-    'Topic :: Office/Business :: Financial :: Investment',
-    'Topic :: Office/Business :: Financial :: Point-Of-Sale',
-    'Topic :: Office/Business :: Financial :: Spreadsheet',
-    'Topic :: Office/Business :: Groupware',
-    'Topic :: Office/Business :: News/Diary',
-    'Topic :: Office/Business :: Office Suites',
-    'Topic :: Office/Business :: Scheduling',
-    'Topic :: Other/Nonlisted Topic',
-    'Topic :: Printing',
-    'Topic :: Religion',
-    'Topic :: Scientific/Engineering',
-    'Topic :: Scientific/Engineering :: Artificial Intelligence',
-    'Topic :: Scientific/Engineering :: Astronomy',
-    'Topic :: Scientific/Engineering :: Atmospheric Science',
-    'Topic :: Scientific/Engineering :: Bio-Informatics',
-    'Topic :: Scientific/Engineering :: Chemistry',
-    'Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)',
-    'Topic :: Scientific/Engineering :: GIS',
-    'Topic :: Scientific/Engineering :: Human Machine Interfaces',
-    'Topic :: Scientific/Engineering :: Image Recognition',
-    'Topic :: Scientific/Engineering :: Information Analysis',
-    'Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator',
-    'Topic :: Scientific/Engineering :: Mathematics',
-    'Topic :: Scientific/Engineering :: Medical Science Apps.',
-    'Topic :: Scientific/Engineering :: Physics',
-    'Topic :: Scientific/Engineering :: Visualization',
-    'Topic :: Security',
-    'Topic :: Security :: Cryptography',
-    'Topic :: Sociology',
-    'Topic :: Sociology :: Genealogy',
-    'Topic :: Sociology :: History',
-    'Topic :: Software Development',
-    'Topic :: Software Development :: Assemblers',
-    'Topic :: Software Development :: Bug Tracking',
-    'Topic :: Software Development :: Build Tools',
-    'Topic :: Software Development :: Code Generators',
-    'Topic :: Software Development :: Compilers',
-    'Topic :: Software Development :: Debuggers',
-    'Topic :: Software Development :: Disassemblers',
-    'Topic :: Software Development :: Documentation',
-    'Topic :: Software Development :: Embedded Systems',
-    'Topic :: Software Development :: Internationalization',
-    'Topic :: Software Development :: Interpreters',
-    'Topic :: Software Development :: Libraries',
-    'Topic :: Software Development :: Libraries :: Application Frameworks',
-    'Topic :: Software Development :: Libraries :: Java Libraries',
-    'Topic :: Software Development :: Libraries :: Perl Modules',
-    'Topic :: Software Development :: Libraries :: PHP Classes',
-    'Topic :: Software Development :: Libraries :: Pike Modules',
-    'Topic :: Software Development :: Libraries :: pygame',
-    'Topic :: Software Development :: Libraries :: Python Modules',
-    'Topic :: Software Development :: Libraries :: Ruby Modules',
-    'Topic :: Software Development :: Libraries :: Tcl Extensions',
-    'Topic :: Software Development :: Localization',
-    'Topic :: Software Development :: Object Brokering',
-    'Topic :: Software Development :: Object Brokering :: CORBA',
-    'Topic :: Software Development :: Pre-processors',
-    'Topic :: Software Development :: Quality Assurance',
-    'Topic :: Software Development :: Testing',
-    'Topic :: Software Development :: Testing :: Traffic Generation',
-    'Topic :: Software Development :: User Interfaces',
-    'Topic :: Software Development :: Version Control',
-    'Topic :: Software Development :: Version Control :: CVS',
-    'Topic :: Software Development :: Version Control :: RCS',
-    'Topic :: Software Development :: Version Control :: SCCS',
-    'Topic :: Software Development :: Widget Sets',
-    'Topic :: System',
-    'Topic :: System :: Archiving',
-    'Topic :: System :: Archiving :: Backup',
-    'Topic :: System :: Archiving :: Compression',
-    'Topic :: System :: Archiving :: Mirroring',
-    'Topic :: System :: Archiving :: Packaging',
-    'Topic :: System :: Benchmark',
-    'Topic :: System :: Boot',
-    'Topic :: System :: Boot :: Init',
-    'Topic :: System :: Clustering',
-    'Topic :: System :: Console Fonts',
-    'Topic :: System :: Distributed Computing',
-    'Topic :: System :: Emulators',
-    'Topic :: System :: Filesystems',
-    'Topic :: System :: Hardware',
-    'Topic :: System :: Hardware :: Hardware Drivers',
-    'Topic :: System :: Hardware :: Mainframes',
-    'Topic :: System :: Hardware :: Symmetric Multi-processing',
-    'Topic :: System :: Installation/Setup',
-    'Topic :: System :: Logging',
-    'Topic :: System :: Monitoring',
-    'Topic :: System :: Networking',
-    'Topic :: System :: Networking :: Firewalls',
-    'Topic :: System :: Networking :: Monitoring',
-    'Topic :: System :: Networking :: Monitoring :: Hardware Watchdog',
-    'Topic :: System :: Networking :: Time Synchronization',
-    'Topic :: System :: Operating System',
-    'Topic :: System :: Operating System Kernels',
-    'Topic :: System :: Operating System Kernels :: BSD',
-    'Topic :: System :: Operating System Kernels :: GNU Hurd',
-    'Topic :: System :: Operating System Kernels :: Linux',
-    'Topic :: System :: Power (UPS)',
-    'Topic :: System :: Recovery Tools',
-    'Topic :: System :: Shells',
-    'Topic :: System :: Software Distribution',
-    'Topic :: System :: Systems Administration',
-    'Topic :: System :: Systems Administration :: Authentication/Directory',
-    'Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP',
-    'Topic :: System :: Systems Administration :: Authentication/Directory :: NIS',
-    'Topic :: System :: System Shells',
-    'Topic :: Terminals',
-    'Topic :: Terminals :: Serial',
-    'Topic :: Terminals :: Telnet',
-    'Topic :: Terminals :: Terminal Emulators/X Terminals',
-    'Topic :: Text Editors',
-    'Topic :: Text Editors :: Documentation',
-    'Topic :: Text Editors :: Emacs',
-    'Topic :: Text Editors :: Integrated Development Environments (IDE)',
-    'Topic :: Text Editors :: Text Processing',
-    'Topic :: Text Editors :: Word Processors',
-    'Topic :: Text Processing',
-    'Topic :: Text Processing :: Filters',
-    'Topic :: Text Processing :: Fonts',
-    'Topic :: Text Processing :: General',
-    'Topic :: Text Processing :: Indexing',
-    'Topic :: Text Processing :: Linguistic',
-    'Topic :: Text Processing :: Markup',
-    'Topic :: Text Processing :: Markup :: HTML',
-    'Topic :: Text Processing :: Markup :: LaTeX',
-    'Topic :: Text Processing :: Markup :: SGML',
-    'Topic :: Text Processing :: Markup :: VRML',
-    'Topic :: Text Processing :: Markup :: XML',
-    'Topic :: Utilities',
+'Development Status :: 1 - Planning',
+'Development Status :: 2 - Pre-Alpha',
+'Development Status :: 3 - Alpha',
+'Development Status :: 4 - Beta',
+'Development Status :: 5 - Production/Stable',
+'Development Status :: 6 - Mature',
+'Development Status :: 7 - Inactive',
+'Environment :: Console',
+'Environment :: Console :: Curses',
+'Environment :: Console :: Framebuffer',
+'Environment :: Console :: Newt',
+'Environment :: Console :: svgalib',
+"Environment :: Handhelds/PDA's",
+'Environment :: MacOS X',
+'Environment :: MacOS X :: Aqua',
+'Environment :: MacOS X :: Carbon',
+'Environment :: MacOS X :: Cocoa',
+'Environment :: No Input/Output (Daemon)',
+'Environment :: Other Environment',
+'Environment :: Plugins',
+'Environment :: Web Environment',
+'Environment :: Web Environment :: Buffet',
+'Environment :: Web Environment :: Mozilla',
+'Environment :: Web Environment :: ToscaWidgets',
+'Environment :: Win32 (MS Windows)',
+'Environment :: X11 Applications',
+'Environment :: X11 Applications :: Gnome',
+'Environment :: X11 Applications :: GTK',
+'Environment :: X11 Applications :: KDE',
+'Environment :: X11 Applications :: Qt',
+'Framework :: BFG',
+'Framework :: Buildout',
+'Framework :: Chandler',
+'Framework :: CubicWeb',
+'Framework :: Django',
+'Framework :: IDLE',
+'Framework :: Paste',
+'Framework :: Plone',
+'Framework :: Pylons',
+'Framework :: Setuptools Plugin',
+'Framework :: Trac',
+'Framework :: TurboGears',
+'Framework :: TurboGears :: Applications',
+'Framework :: TurboGears :: Widgets',
+'Framework :: Twisted',
+'Framework :: ZODB',
+'Framework :: Zope2',
+'Framework :: Zope3',
+'Intended Audience :: Customer Service',
+'Intended Audience :: Developers',
+'Intended Audience :: Education',
+'Intended Audience :: End Users/Desktop',
+'Intended Audience :: Financial and Insurance Industry',
+'Intended Audience :: Healthcare Industry',
+'Intended Audience :: Information Technology',
+'Intended Audience :: Legal Industry',
+'Intended Audience :: Manufacturing',
+'Intended Audience :: Other Audience',
+'Intended Audience :: Religion',
+'Intended Audience :: Science/Research',
+'Intended Audience :: System Administrators',
+'Intended Audience :: Telecommunications Industry',
+'License :: Aladdin Free Public License (AFPL)',
+'License :: DFSG approved',
+'License :: Eiffel Forum License (EFL)',
+'License :: Free For Educational Use',
+'License :: Free For Home Use',
+'License :: Free for non-commercial use',
+'License :: Freely Distributable',
+'License :: Free To Use But Restricted',
+'License :: Freeware',
+'License :: Netscape Public License (NPL)',
+'License :: Nokia Open Source License (NOKOS)',
+'License :: OSI Approved',
+'License :: OSI Approved :: Academic Free License (AFL)',
+'License :: OSI Approved :: Apache Software License',
+'License :: OSI Approved :: Apple Public Source License',
+'License :: OSI Approved :: Artistic License',
+'License :: OSI Approved :: Attribution Assurance License',
+'License :: OSI Approved :: BSD License',
+'License :: OSI Approved :: Common Public License',
+'License :: OSI Approved :: Eiffel Forum License',
+'License :: OSI Approved :: European Union Public Licence 1.0 (EUPL 1.0)',
+'License :: OSI Approved :: European Union Public Licence 1.1 (EUPL 1.1)',
+'License :: OSI Approved :: GNU Affero General Public License v3',
+'License :: OSI Approved :: GNU Free Documentation License (FDL)',
+'License :: OSI Approved :: GNU General Public License (GPL)',
+'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
+'License :: OSI Approved :: IBM Public License',
+'License :: OSI Approved :: Intel Open Source License',
+'License :: OSI Approved :: ISC License (ISCL)',
+'License :: OSI Approved :: Jabber Open Source License',
+'License :: OSI Approved :: MIT License',
+'License :: OSI Approved :: MITRE Collaborative Virtual Workspace License (CVW)',
+'License :: OSI Approved :: Motosoto License',
+'License :: OSI Approved :: Mozilla Public License 1.0 (MPL)',
+'License :: OSI Approved :: Mozilla Public License 1.1 (MPL 1.1)',
+'License :: OSI Approved :: Nethack General Public License',
+'License :: OSI Approved :: Nokia Open Source License',
+'License :: OSI Approved :: Open Group Test Suite License',
+'License :: OSI Approved :: Python License (CNRI Python License)',
+'License :: OSI Approved :: Python Software Foundation License',
+'License :: OSI Approved :: Qt Public License (QPL)',
+'License :: OSI Approved :: Ricoh Source Code Public License',
+'License :: OSI Approved :: Sleepycat License',
+'License :: OSI Approved :: Sun Industry Standards Source License (SISSL)',
+'License :: OSI Approved :: Sun Public License',
+'License :: OSI Approved :: University of Illinois/NCSA Open Source License',
+'License :: OSI Approved :: Vovida Software License 1.0',
+'License :: OSI Approved :: W3C License',
+'License :: OSI Approved :: X.Net License',
+'License :: OSI Approved :: zlib/libpng License',
+'License :: OSI Approved :: Zope Public License',
+'License :: Other/Proprietary License',
+'License :: Public Domain',
+'License :: Repoze Public License',
+'Natural Language :: Afrikaans',
+'Natural Language :: Arabic',
+'Natural Language :: Bengali',
+'Natural Language :: Bosnian',
+'Natural Language :: Bulgarian',
+'Natural Language :: Catalan',
+'Natural Language :: Chinese (Simplified)',
+'Natural Language :: Chinese (Traditional)',
+'Natural Language :: Croatian',
+'Natural Language :: Czech',
+'Natural Language :: Danish',
+'Natural Language :: Dutch',
+'Natural Language :: English',
+'Natural Language :: Esperanto',
+'Natural Language :: Finnish',
+'Natural Language :: French',
+'Natural Language :: German',
+'Natural Language :: Greek',
+'Natural Language :: Hebrew',
+'Natural Language :: Hindi',
+'Natural Language :: Hungarian',
+'Natural Language :: Icelandic',
+'Natural Language :: Indonesian',
+'Natural Language :: Italian',
+'Natural Language :: Japanese',
+'Natural Language :: Javanese',
+'Natural Language :: Korean',
+'Natural Language :: Latin',
+'Natural Language :: Latvian',
+'Natural Language :: Macedonian',
+'Natural Language :: Malay',
+'Natural Language :: Marathi',
+'Natural Language :: Norwegian',
+'Natural Language :: Panjabi',
+'Natural Language :: Persian',
+'Natural Language :: Polish',
+'Natural Language :: Portuguese',
+'Natural Language :: Portuguese (Brazilian)',
+'Natural Language :: Romanian',
+'Natural Language :: Russian',
+'Natural Language :: Serbian',
+'Natural Language :: Slovak',
+'Natural Language :: Slovenian',
+'Natural Language :: Spanish',
+'Natural Language :: Swedish',
+'Natural Language :: Tamil',
+'Natural Language :: Telugu',
+'Natural Language :: Thai',
+'Natural Language :: Turkish',
+'Natural Language :: Ukranian',
+'Natural Language :: Urdu',
+'Natural Language :: Vietnamese',
+'Operating System :: BeOS',
+'Operating System :: MacOS',
+'Operating System :: MacOS :: MacOS 9',
+'Operating System :: MacOS :: MacOS X',
+'Operating System :: Microsoft',
+'Operating System :: Microsoft :: MS-DOS',
+'Operating System :: Microsoft :: Windows',
+'Operating System :: Microsoft :: Windows :: Windows 3.1 or Earlier',
+'Operating System :: Microsoft :: Windows :: Windows 95/98/2000',
+'Operating System :: Microsoft :: Windows :: Windows CE',
+'Operating System :: Microsoft :: Windows :: Windows NT/2000',
+'Operating System :: OS/2',
+'Operating System :: OS Independent',
+'Operating System :: Other OS',
+'Operating System :: PalmOS',
+'Operating System :: PDA Systems',
+'Operating System :: POSIX',
+'Operating System :: POSIX :: AIX',
+'Operating System :: POSIX :: BSD',
+'Operating System :: POSIX :: BSD :: BSD/OS',
+'Operating System :: POSIX :: BSD :: FreeBSD',
+'Operating System :: POSIX :: BSD :: NetBSD',
+'Operating System :: POSIX :: BSD :: OpenBSD',
+'Operating System :: POSIX :: GNU Hurd',
+'Operating System :: POSIX :: HP-UX',
+'Operating System :: POSIX :: IRIX',
+'Operating System :: POSIX :: Linux',
+'Operating System :: POSIX :: Other',
+'Operating System :: POSIX :: SCO',
+'Operating System :: POSIX :: SunOS/Solaris',
+'Operating System :: Unix',
+'Programming Language :: Ada',
+'Programming Language :: APL',
+'Programming Language :: ASP',
+'Programming Language :: Assembly',
+'Programming Language :: Awk',
+'Programming Language :: Basic',
+'Programming Language :: C',
+'Programming Language :: C#',
+'Programming Language :: C++',
+'Programming Language :: Cold Fusion',
+'Programming Language :: Cython',
+'Programming Language :: Delphi/Kylix',
+'Programming Language :: Dylan',
+'Programming Language :: Eiffel',
+'Programming Language :: Emacs-Lisp',
+'Programming Language :: Erlang',
+'Programming Language :: Euler',
+'Programming Language :: Euphoria',
+'Programming Language :: Forth',
+'Programming Language :: Fortran',
+'Programming Language :: Haskell',
+'Programming Language :: Java',
+'Programming Language :: JavaScript',
+'Programming Language :: Lisp',
+'Programming Language :: Logo',
+'Programming Language :: ML',
+'Programming Language :: Modula',
+'Programming Language :: Objective C',
+'Programming Language :: Object Pascal',
+'Programming Language :: OCaml',
+'Programming Language :: Other',
+'Programming Language :: Other Scripting Engines',
+'Programming Language :: Pascal',
+'Programming Language :: Perl',
+'Programming Language :: PHP',
+'Programming Language :: Pike',
+'Programming Language :: Pliant',
+'Programming Language :: PL/SQL',
+'Programming Language :: PROGRESS',
+'Programming Language :: Prolog',
+'Programming Language :: Python',
+'Programming Language :: Python :: 2',
+'Programming Language :: Python :: 2.3',
+'Programming Language :: Python :: 2.4',
+'Programming Language :: Python :: 2.5',
+'Programming Language :: Python :: 2.6',
+'Programming Language :: Python :: 2.7',
+'Programming Language :: Python :: 3',
+'Programming Language :: Python :: 3.0',
+'Programming Language :: Python :: 3.1',
+'Programming Language :: Python :: 3.2',
+'Programming Language :: REBOL',
+'Programming Language :: Rexx',
+'Programming Language :: Ruby',
+'Programming Language :: Scheme',
+'Programming Language :: Simula',
+'Programming Language :: Smalltalk',
+'Programming Language :: SQL',
+'Programming Language :: Tcl',
+'Programming Language :: Unix Shell',
+'Programming Language :: Visual Basic',
+'Programming Language :: XBasic',
+'Programming Language :: YACC',
+'Programming Language :: Zope',
+'Topic :: Adaptive Technologies',
+'Topic :: Artistic Software',
+'Topic :: Communications',
+'Topic :: Communications :: BBS',
+'Topic :: Communications :: Chat',
+'Topic :: Communications :: Chat :: AOL Instant Messenger',
+'Topic :: Communications :: Chat :: ICQ',
+'Topic :: Communications :: Chat :: Internet Relay Chat',
+'Topic :: Communications :: Chat :: Unix Talk',
+'Topic :: Communications :: Conferencing',
+'Topic :: Communications :: Email',
+'Topic :: Communications :: Email :: Address Book',
+'Topic :: Communications :: Email :: Email Clients (MUA)',
+'Topic :: Communications :: Email :: Filters',
+'Topic :: Communications :: Email :: Mailing List Servers',
+'Topic :: Communications :: Email :: Mail Transport Agents',
+'Topic :: Communications :: Email :: Post-Office',
+'Topic :: Communications :: Email :: Post-Office :: IMAP',
+'Topic :: Communications :: Email :: Post-Office :: POP3',
+'Topic :: Communications :: Fax',
+'Topic :: Communications :: FIDO',
+'Topic :: Communications :: File Sharing',
+'Topic :: Communications :: File Sharing :: Gnutella',
+'Topic :: Communications :: File Sharing :: Napster',
+'Topic :: Communications :: Ham Radio',
+'Topic :: Communications :: Internet Phone',
+'Topic :: Communications :: Telephony',
+'Topic :: Communications :: Usenet News',
+'Topic :: Database',
+'Topic :: Database :: Database Engines/Servers',
+'Topic :: Database :: Front-Ends',
+'Topic :: Desktop Environment',
+'Topic :: Desktop Environment :: File Managers',
+'Topic :: Desktop Environment :: Gnome',
+'Topic :: Desktop Environment :: GNUstep',
+'Topic :: Desktop Environment :: K Desktop Environment (KDE)',
+'Topic :: Desktop Environment :: K Desktop Environment (KDE) :: Themes',
+'Topic :: Desktop Environment :: PicoGUI',
+'Topic :: Desktop Environment :: PicoGUI :: Applications',
+'Topic :: Desktop Environment :: PicoGUI :: Themes',
+'Topic :: Desktop Environment :: Screen Savers',
+'Topic :: Desktop Environment :: Window Managers',
+'Topic :: Desktop Environment :: Window Managers :: Afterstep',
+'Topic :: Desktop Environment :: Window Managers :: Afterstep :: Themes',
+'Topic :: Desktop Environment :: Window Managers :: Applets',
+'Topic :: Desktop Environment :: Window Managers :: Blackbox',
+'Topic :: Desktop Environment :: Window Managers :: Blackbox :: Themes',
+'Topic :: Desktop Environment :: Window Managers :: CTWM',
+'Topic :: Desktop Environment :: Window Managers :: CTWM :: Themes',
+'Topic :: Desktop Environment :: Window Managers :: Enlightenment',
+'Topic :: Desktop Environment :: Window Managers :: Enlightenment :: Epplets',
+'Topic :: Desktop Environment :: Window Managers :: Enlightenment :: Themes DR15',
+'Topic :: Desktop Environment :: Window Managers :: Enlightenment :: Themes DR16',
+'Topic :: Desktop Environment :: Window Managers :: Enlightenment :: Themes DR17',
+'Topic :: Desktop Environment :: Window Managers :: Fluxbox',
+'Topic :: Desktop Environment :: Window Managers :: Fluxbox :: Themes',
+'Topic :: Desktop Environment :: Window Managers :: FVWM',
+'Topic :: Desktop Environment :: Window Managers :: FVWM :: Themes',
+'Topic :: Desktop Environment :: Window Managers :: IceWM',
+'Topic :: Desktop Environment :: Window Managers :: IceWM :: Themes',
+'Topic :: Desktop Environment :: Window Managers :: MetaCity',
+'Topic :: Desktop Environment :: Window Managers :: MetaCity :: Themes',
+'Topic :: Desktop Environment :: Window Managers :: Oroborus',
+'Topic :: Desktop Environment :: Window Managers :: Oroborus :: Themes',
+'Topic :: Desktop Environment :: Window Managers :: Sawfish',
+'Topic :: Desktop Environment :: Window Managers :: Sawfish :: Themes 0.30',
+'Topic :: Desktop Environment :: Window Managers :: Sawfish :: Themes pre-0.30',
+'Topic :: Desktop Environment :: Window Managers :: Waimea',
+'Topic :: Desktop Environment :: Window Managers :: Waimea :: Themes',
+'Topic :: Desktop Environment :: Window Managers :: Window Maker',
+'Topic :: Desktop Environment :: Window Managers :: Window Maker :: Applets',
+'Topic :: Desktop Environment :: Window Managers :: Window Maker :: Themes',
+'Topic :: Desktop Environment :: Window Managers :: XFCE',
+'Topic :: Desktop Environment :: Window Managers :: XFCE :: Themes',
+'Topic :: Documentation',
+'Topic :: Education',
+'Topic :: Education :: Computer Aided Instruction (CAI)',
+'Topic :: Education :: Testing',
+'Topic :: Games/Entertainment',
+'Topic :: Games/Entertainment :: Arcade',
+'Topic :: Games/Entertainment :: Board Games',
+'Topic :: Games/Entertainment :: First Person Shooters',
+'Topic :: Games/Entertainment :: Fortune Cookies',
+'Topic :: Games/Entertainment :: Multi-User Dungeons (MUD)',
+'Topic :: Games/Entertainment :: Puzzle Games',
+'Topic :: Games/Entertainment :: Real Time Strategy',
+'Topic :: Games/Entertainment :: Role-Playing',
+'Topic :: Games/Entertainment :: Side-Scrolling/Arcade Games',
+'Topic :: Games/Entertainment :: Simulation',
+'Topic :: Games/Entertainment :: Turn Based Strategy',
+'Topic :: Home Automation',
+'Topic :: Internet',
+'Topic :: Internet :: File Transfer Protocol (FTP)',
+'Topic :: Internet :: Finger',
+'Topic :: Internet :: Log Analysis',
+'Topic :: Internet :: Name Service (DNS)',
+'Topic :: Internet :: Proxy Servers',
+'Topic :: Internet :: WAP',
+'Topic :: Internet :: WWW/HTTP',
+'Topic :: Internet :: WWW/HTTP :: Browsers',
+'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
+'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries',
+'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Message Boards',
+'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: News/Diary',
+'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Page Counters',
+'Topic :: Internet :: WWW/HTTP :: HTTP Servers',
+'Topic :: Internet :: WWW/HTTP :: Indexing/Search',
+'Topic :: Internet :: WWW/HTTP :: Site Management',
+'Topic :: Internet :: WWW/HTTP :: Site Management :: Link Checking',
+'Topic :: Internet :: WWW/HTTP :: WSGI',
+'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
+'Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware',
+'Topic :: Internet :: WWW/HTTP :: WSGI :: Server',
+'Topic :: Internet :: Z39.50',
+'Topic :: Multimedia',
+'Topic :: Multimedia :: Graphics',
+'Topic :: Multimedia :: Graphics :: 3D Modeling',
+'Topic :: Multimedia :: Graphics :: 3D Rendering',
+'Topic :: Multimedia :: Graphics :: Capture',
+'Topic :: Multimedia :: Graphics :: Capture :: Digital Camera',
+'Topic :: Multimedia :: Graphics :: Capture :: Scanners',
+'Topic :: Multimedia :: Graphics :: Capture :: Screen Capture',
+'Topic :: Multimedia :: Graphics :: Editors',
+'Topic :: Multimedia :: Graphics :: Editors :: Raster-Based',
+'Topic :: Multimedia :: Graphics :: Editors :: Vector-Based',
+'Topic :: Multimedia :: Graphics :: Graphics Conversion',
+'Topic :: Multimedia :: Graphics :: Presentation',
+'Topic :: Multimedia :: Graphics :: Viewers',
+'Topic :: Multimedia :: Sound/Audio',
+'Topic :: Multimedia :: Sound/Audio :: Analysis',
+'Topic :: Multimedia :: Sound/Audio :: Capture/Recording',
+'Topic :: Multimedia :: Sound/Audio :: CD Audio',
+'Topic :: Multimedia :: Sound/Audio :: CD Audio :: CD Playing',
+'Topic :: Multimedia :: Sound/Audio :: CD Audio :: CD Ripping',
+'Topic :: Multimedia :: Sound/Audio :: CD Audio :: CD Writing',
+'Topic :: Multimedia :: Sound/Audio :: Conversion',
+'Topic :: Multimedia :: Sound/Audio :: Editors',
+'Topic :: Multimedia :: Sound/Audio :: MIDI',
+'Topic :: Multimedia :: Sound/Audio :: Mixers',
+'Topic :: Multimedia :: Sound/Audio :: Players',
+'Topic :: Multimedia :: Sound/Audio :: Players :: MP3',
+'Topic :: Multimedia :: Sound/Audio :: Sound Synthesis',
+'Topic :: Multimedia :: Sound/Audio :: Speech',
+'Topic :: Multimedia :: Video',
+'Topic :: Multimedia :: Video :: Capture',
+'Topic :: Multimedia :: Video :: Conversion',
+'Topic :: Multimedia :: Video :: Display',
+'Topic :: Multimedia :: Video :: Non-Linear Editor',
+'Topic :: Office/Business',
+'Topic :: Office/Business :: Financial',
+'Topic :: Office/Business :: Financial :: Accounting',
+'Topic :: Office/Business :: Financial :: Investment',
+'Topic :: Office/Business :: Financial :: Point-Of-Sale',
+'Topic :: Office/Business :: Financial :: Spreadsheet',
+'Topic :: Office/Business :: Groupware',
+'Topic :: Office/Business :: News/Diary',
+'Topic :: Office/Business :: Office Suites',
+'Topic :: Office/Business :: Scheduling',
+'Topic :: Other/Nonlisted Topic',
+'Topic :: Printing',
+'Topic :: Religion',
+'Topic :: Scientific/Engineering',
+'Topic :: Scientific/Engineering :: Artificial Intelligence',
+'Topic :: Scientific/Engineering :: Astronomy',
+'Topic :: Scientific/Engineering :: Atmospheric Science',
+'Topic :: Scientific/Engineering :: Bio-Informatics',
+'Topic :: Scientific/Engineering :: Chemistry',
+'Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)',
+'Topic :: Scientific/Engineering :: GIS',
+'Topic :: Scientific/Engineering :: Human Machine Interfaces',
+'Topic :: Scientific/Engineering :: Image Recognition',
+'Topic :: Scientific/Engineering :: Information Analysis',
+'Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator',
+'Topic :: Scientific/Engineering :: Mathematics',
+'Topic :: Scientific/Engineering :: Medical Science Apps.',
+'Topic :: Scientific/Engineering :: Physics',
+'Topic :: Scientific/Engineering :: Visualization',
+'Topic :: Security',
+'Topic :: Security :: Cryptography',
+'Topic :: Sociology',
+'Topic :: Sociology :: Genealogy',
+'Topic :: Sociology :: History',
+'Topic :: Software Development',
+'Topic :: Software Development :: Assemblers',
+'Topic :: Software Development :: Bug Tracking',
+'Topic :: Software Development :: Build Tools',
+'Topic :: Software Development :: Code Generators',
+'Topic :: Software Development :: Compilers',
+'Topic :: Software Development :: Debuggers',
+'Topic :: Software Development :: Disassemblers',
+'Topic :: Software Development :: Documentation',
+'Topic :: Software Development :: Embedded Systems',
+'Topic :: Software Development :: Internationalization',
+'Topic :: Software Development :: Interpreters',
+'Topic :: Software Development :: Libraries',
+'Topic :: Software Development :: Libraries :: Application Frameworks',
+'Topic :: Software Development :: Libraries :: Java Libraries',
+'Topic :: Software Development :: Libraries :: Perl Modules',
+'Topic :: Software Development :: Libraries :: PHP Classes',
+'Topic :: Software Development :: Libraries :: Pike Modules',
+'Topic :: Software Development :: Libraries :: pygame',
+'Topic :: Software Development :: Libraries :: Python Modules',
+'Topic :: Software Development :: Libraries :: Ruby Modules',
+'Topic :: Software Development :: Libraries :: Tcl Extensions',
+'Topic :: Software Development :: Localization',
+'Topic :: Software Development :: Object Brokering',
+'Topic :: Software Development :: Object Brokering :: CORBA',
+'Topic :: Software Development :: Pre-processors',
+'Topic :: Software Development :: Quality Assurance',
+'Topic :: Software Development :: Testing',
+'Topic :: Software Development :: Testing :: Traffic Generation',
+'Topic :: Software Development :: User Interfaces',
+'Topic :: Software Development :: Version Control',
+'Topic :: Software Development :: Version Control :: CVS',
+'Topic :: Software Development :: Version Control :: RCS',
+'Topic :: Software Development :: Version Control :: SCCS',
+'Topic :: Software Development :: Widget Sets',
+'Topic :: System',
+'Topic :: System :: Archiving',
+'Topic :: System :: Archiving :: Backup',
+'Topic :: System :: Archiving :: Compression',
+'Topic :: System :: Archiving :: Mirroring',
+'Topic :: System :: Archiving :: Packaging',
+'Topic :: System :: Benchmark',
+'Topic :: System :: Boot',
+'Topic :: System :: Boot :: Init',
+'Topic :: System :: Clustering',
+'Topic :: System :: Console Fonts',
+'Topic :: System :: Distributed Computing',
+'Topic :: System :: Emulators',
+'Topic :: System :: Filesystems',
+'Topic :: System :: Hardware',
+'Topic :: System :: Hardware :: Hardware Drivers',
+'Topic :: System :: Hardware :: Mainframes',
+'Topic :: System :: Hardware :: Symmetric Multi-processing',
+'Topic :: System :: Installation/Setup',
+'Topic :: System :: Logging',
+'Topic :: System :: Monitoring',
+'Topic :: System :: Networking',
+'Topic :: System :: Networking :: Firewalls',
+'Topic :: System :: Networking :: Monitoring',
+'Topic :: System :: Networking :: Monitoring :: Hardware Watchdog',
+'Topic :: System :: Networking :: Time Synchronization',
+'Topic :: System :: Operating System',
+'Topic :: System :: Operating System Kernels',
+'Topic :: System :: Operating System Kernels :: BSD',
+'Topic :: System :: Operating System Kernels :: GNU Hurd',
+'Topic :: System :: Operating System Kernels :: Linux',
+'Topic :: System :: Power (UPS)',
+'Topic :: System :: Recovery Tools',
+'Topic :: System :: Shells',
+'Topic :: System :: Software Distribution',
+'Topic :: System :: Systems Administration',
+'Topic :: System :: Systems Administration :: Authentication/Directory',
+'Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP',
+'Topic :: System :: Systems Administration :: Authentication/Directory :: NIS',
+'Topic :: System :: System Shells',
+'Topic :: Terminals',
+'Topic :: Terminals :: Serial',
+'Topic :: Terminals :: Telnet',
+'Topic :: Terminals :: Terminal Emulators/X Terminals',
+'Topic :: Text Editors',
+'Topic :: Text Editors :: Documentation',
+'Topic :: Text Editors :: Emacs',
+'Topic :: Text Editors :: Integrated Development Environments (IDE)',
+'Topic :: Text Editors :: Text Processing',
+'Topic :: Text Editors :: Word Processors',
+'Topic :: Text Processing',
+'Topic :: Text Processing :: Filters',
+'Topic :: Text Processing :: Fonts',
+'Topic :: Text Processing :: General',
+'Topic :: Text Processing :: Indexing',
+'Topic :: Text Processing :: Linguistic',
+'Topic :: Text Processing :: Markup',
+'Topic :: Text Processing :: Markup :: HTML',
+'Topic :: Text Processing :: Markup :: LaTeX',
+'Topic :: Text Processing :: Markup :: SGML',
+'Topic :: Text Processing :: Markup :: VRML',
+'Topic :: Text Processing :: Markup :: XML',
+'Topic :: Utilities',
 ]
diff --git a/distutils2/command/__init__.py b/distutils2/command/__init__.py
--- a/distutils2/command/__init__.py
+++ b/distutils2/command/__init__.py
@@ -1,8 +1,6 @@
-"""distutils.command
+"""Subpackage containing all standard commands."""
 
-Package containing implementation of all the standard Distutils
-commands."""
-from distutils2.errors import DistutilsModuleError
+from distutils2.errors import PackagingModuleError
 from distutils2.util import resolve_name
 
 __all__ = ['get_command_names', 'set_command', 'get_command_class',
@@ -50,9 +48,9 @@
     """Return the registered command"""
     try:
         cls = _COMMANDS[name]
-        if isinstance(cls, str):
+        if isinstance(cls, basestring):
             cls = resolve_name(cls)
             _COMMANDS[name] = cls
         return cls
     except KeyError:
-        raise DistutilsModuleError("Invalid command %s" % name)
+        raise PackagingModuleError("Invalid command %s" % name)
diff --git a/distutils2/command/bdist.py b/distutils2/command/bdist.py
--- a/distutils2/command/bdist.py
+++ b/distutils2/command/bdist.py
@@ -1,12 +1,15 @@
-"""distutils.command.bdist
+"""Create a built (binary) distribution.
 
-Implements the Distutils 'bdist' command (create a built [binary]
-distribution)."""
+If a --formats option was given on the command line, this command will
+call the corresponding bdist_* commands; if the option was absent, a
+bdist_* command depending on the current platform will be called.
+"""
+
 import os
 
 from distutils2 import util
 from distutils2.command.cmd import Command
-from distutils2.errors import DistutilsPlatformError, DistutilsOptionError
+from distutils2.errors import PackagingPlatformError, PackagingOptionError
 
 
 def show_formats():
@@ -52,8 +55,10 @@
          "lists available distribution formats", show_formats),
         ]
 
-    # This won't do in reality: will need to distinguish RPM-ish Linux,
-    # Debian-ish Linux, Solaris, FreeBSD, ..., Windows, Mac OS.
+    # This is of course very simplistic.  The various UNIX family operating
+    # systems have their specific formats, but they are out of scope for us;
+    # bdist_dumb is, well, dumb; it's more a building block for other
+    # distutils2 tools than a real end-user binary format.
     default_format = {'posix': 'gztar',
                       'nt': 'zip',
                       'os2': 'zip'}
@@ -79,7 +84,7 @@
         self.plat_name = None
         self.formats = None
         self.dist_dir = None
-        self.skip_build = 0
+        self.skip_build = False
         self.group = None
         self.owner = None
 
@@ -104,9 +109,8 @@
             try:
                 self.formats = [self.default_format[os.name]]
             except KeyError:
-                raise DistutilsPlatformError, \
-                      "don't know how to create built distributions " + \
-                      "on platform %s" % os.name
+                raise PackagingPlatformError("don't know how to create built distributions " + \
+                      "on platform %s" % os.name)
 
         if self.dist_dir is None:
             self.dist_dir = "dist"
@@ -118,12 +122,13 @@
             try:
                 commands.append(self.format_command[format][0])
             except KeyError:
-                raise DistutilsOptionError, "invalid format '%s'" % format
+                raise PackagingOptionError("invalid format '%s'" % format)
 
         # Reinitialize and run each command.
         for i in range(len(self.formats)):
             cmd_name = commands[i]
             sub_cmd = self.get_reinitialized_command(cmd_name)
+            sub_cmd.format = self.formats[i]
 
             # passing the owner and group names for tar archiving
             if cmd_name == 'bdist_dumb':
@@ -133,5 +138,5 @@
             # If we're going to need to run this command again, tell it to
             # keep its temporary files around so subsequent runs go faster.
             if cmd_name in commands[i+1:]:
-                sub_cmd.keep_temp = 1
+                sub_cmd.keep_temp = True
             self.run_command(cmd_name)
diff --git a/distutils2/command/bdist_dumb.py b/distutils2/command/bdist_dumb.py
--- a/distutils2/command/bdist_dumb.py
+++ b/distutils2/command/bdist_dumb.py
@@ -1,22 +1,19 @@
-"""distutils.command.bdist_dumb
+"""Create a "dumb" built distribution.
 
-Implements the Distutils 'bdist_dumb' command (create a "dumb" built
-distribution -- i.e., just an archive to be unpacked under $prefix or
-$exec_prefix)."""
-
+A dumb distribution is just an archive meant to be unpacked under
+sys.prefix or sys.exec_prefix.
+"""
 
 import os
+
 from shutil import rmtree
-try:
-    from sysconfig import get_python_version
-except ImportError:
-    from distutils2._backport.sysconfig import get_python_version
+from sysconfig import get_python_version
 from distutils2.util import get_platform
 from distutils2.command.cmd import Command
-from distutils2.errors import DistutilsPlatformError
+from distutils2.errors import PackagingPlatformError
 from distutils2 import logger
 
-class bdist_dumb (Command):
+class bdist_dumb(Command):
 
     description = 'create a "dumb" built distribution'
 
@@ -52,14 +49,14 @@
                        'os2': 'zip' }
 
 
-    def initialize_options (self):
+    def initialize_options(self):
         self.bdist_dir = None
         self.plat_name = None
         self.format = None
-        self.keep_temp = 0
+        self.keep_temp = False
         self.dist_dir = None
-        self.skip_build = 0
-        self.relative = 0
+        self.skip_build = False
+        self.relative = False
         self.owner = None
         self.group = None
 
@@ -72,9 +69,8 @@
             try:
                 self.format = self.default_format[os.name]
             except KeyError:
-                raise DistutilsPlatformError, \
-                      ("don't know how to create dumb built distributions " +
-                       "on platform %s") % os.name
+                raise PackagingPlatformError(("don't know how to create dumb built distributions " +
+                       "on platform %s") % os.name)
 
         self.set_undefined_options('bdist', 'dist_dir', 'plat_name')
 
@@ -82,10 +78,11 @@
         if not self.skip_build:
             self.run_command('build')
 
-        install = self.get_reinitialized_command('install_dist', reinit_subcommands=1)
+        install = self.get_reinitialized_command('install_dist',
+                                                 reinit_subcommands=True)
         install.root = self.bdist_dir
         install.skip_build = self.skip_build
-        install.warn_dir = 0
+        install.warn_dir = False
 
         logger.info("installing to %s", self.bdist_dir)
         self.run_command('install_dist')
@@ -106,7 +103,7 @@
         else:
             if (self.distribution.has_ext_modules() and
                 (install.install_base != install.install_platbase)):
-                raise DistutilsPlatformError(
+                raise PackagingPlatformError(
                     "can't make a dumb built distribution where base and "
                     "platbase are different (%r, %r)" %
                     (install.install_base, install.install_platbase))
diff --git a/distutils2/command/bdist_msi.py b/distutils2/command/bdist_msi.py
--- a/distutils2/command/bdist_msi.py
+++ b/distutils2/command/bdist_msi.py
@@ -1,25 +1,33 @@
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2005, 2006 Martin von Löwis
+"""Create a Microsoft Installer (.msi) binary distribution."""
+
+# Copyright (C) 2005, 2006 Martin von Löwis
 # Licensed to PSF under a Contributor Agreement.
-# The bdist_wininst command proper
-# based on bdist_wininst
-"""
-Implements the bdist_msi command.
-"""
-import sys, os
+
+import sys
+import os
+import msilib
+
+
 from sysconfig import get_python_version
-
-from distutils2.core import Command
-from distutils2.version import StrictVersion
-from distutils2.errors import DistutilsOptionError
-from distutils2 import log
+from shutil import rmtree
+from distutils2.command.cmd import Command
+from distutils2.version import NormalizedVersion
+from distutils2.errors import PackagingOptionError
+from distutils2 import logger as log
 from distutils2.util import get_platform
-from distutils2._backport.shutil import rmtree
-
-import msilib
 from msilib import schema, sequence, text
 from msilib import Directory, Feature, Dialog, add_data
 
+class MSIVersion(NormalizedVersion):
+    """
+    MSI ProductVersion must be strictly numeric.
+    MSIVersion disallows prerelease and postrelease versions.
+    """
+    def __init__(self, *args, **kwargs):
+        super(MSIVersion, self).__init__(*args, **kwargs)
+        if not self.is_final:
+            raise ValueError("ProductVersion must be strictly numeric")
+
 class PyDialog(Dialog):
     """Dialog class with a fixed layout: controls at the top, then a ruler,
     then a list of buttons: back, next, cancel. Optionally a bitmap at the
@@ -81,7 +89,7 @@
         Return the button, so that events can be associated"""
         return self.pushbutton(name, int(self.w*xpos - 28), self.h-27, 56, 17, 3, title, next)
 
-class bdist_msi (Command):
+class bdist_msi(Command):
 
     description = "create a Microsoft Installer (.msi) binary distribution"
 
@@ -123,20 +131,20 @@
                     '3.5', '3.6', '3.7', '3.8', '3.9']
     other_version = 'X'
 
-    def initialize_options (self):
+    def initialize_options(self):
         self.bdist_dir = None
         self.plat_name = None
-        self.keep_temp = 0
-        self.no_target_compile = 0
-        self.no_target_optimize = 0
+        self.keep_temp = False
+        self.no_target_compile = False
+        self.no_target_optimize = False
         self.target_version = None
         self.dist_dir = None
-        self.skip_build = 0
+        self.skip_build = False
         self.install_script = None
         self.pre_install_script = None
         self.versions = None
 
-    def finalize_options (self):
+    def finalize_options(self):
         if self.bdist_dir is None:
             bdist_base = self.get_finalized_command('bdist').bdist_base
             self.bdist_dir = os.path.join(bdist_base, 'msi')
@@ -147,41 +155,39 @@
             self.versions = [self.target_version]
             if not self.skip_build and self.distribution.has_ext_modules()\
                and self.target_version != short_version:
-                raise DistutilsOptionError, \
-                      "target version can only be %s, or the '--skip-build'" \
-                      " option must be specified" % (short_version,)
+                raise PackagingOptionError("target version can only be %s, or the '--skip-build'" \
+                      " option must be specified" % (short_version,))
         else:
             self.versions = list(self.all_versions)
 
         self.set_undefined_options('bdist', 'dist_dir', 'plat_name')
 
         if self.pre_install_script:
-            raise DistutilsOptionError, "the pre-install-script feature is not yet implemented"
+            raise PackagingOptionError("the pre-install-script feature is not yet implemented")
 
         if self.install_script:
             for script in self.distribution.scripts:
                 if self.install_script == os.path.basename(script):
                     break
             else:
-                raise DistutilsOptionError, \
-                      "install_script '%s' not found in scripts" % \
-                      self.install_script
+                raise PackagingOptionError("install_script '%s' not found in scripts" % \
+                      self.install_script)
         self.install_script_key = None
-    # finalize_options()
 
 
-    def run (self):
+    def run(self):
         if not self.skip_build:
             self.run_command('build')
 
-        install = self.get_reinitialized_command('install_dist', reinit_subcommands=1)
+        install = self.get_reinitialized_command('install_dist',
+                                                 reinit_subcommands=True)
         install.prefix = self.bdist_dir
         install.skip_build = self.skip_build
-        install.warn_dir = 0
+        install.warn_dir = False
 
         install_lib = self.get_reinitialized_command('install_lib')
         # we do not want to include pyc or pyo files
-        install_lib.compile = 0
+        install_lib.compile = False
         install_lib.optimize = 0
 
         if self.distribution.has_ext_modules():
@@ -223,10 +229,7 @@
             author = metadata.maintainer
         if not author:
             author = "UNKNOWN"
-        version = metadata.get_version()
-        # ProductVersion must be strictly numeric
-        # XXX need to deal with prerelease versions
-        sversion = "%d.%d.%d" % StrictVersion(version).version
+        version = MSIVersion(metadata.get_version())
         # Prefix ProductName with Python x.y, so that
         # it sorts together with the other Python packages
         # in Add-Remove-Programs (APR)
@@ -237,7 +240,7 @@
             product_name = "Python %s" % (fullname)
         self.db = msilib.init_database(installer_name, schema,
                 product_name, msilib.gen_uuid(),
-                sversion, author)
+                str(version), author)
         msilib.add_tables(self.db, sequence)
         props = [('DistVersion', version)]
         email = metadata.author_email or metadata.maintainer_email
@@ -307,7 +310,7 @@
                             key = seen[afile] = dir.add_file(file)
                             if file==self.install_script:
                                 if self.install_script_key:
-                                    raise DistutilsOptionError(
+                                    raise PackagingOptionError(
                                           "Multiple files with name %s" % file)
                                 self.install_script_key = '[#%s]' % key
                         else:
@@ -387,27 +390,27 @@
         #     entries for each version as the above code does
         if self.pre_install_script:
             scriptfn = os.path.join(self.bdist_dir, "preinstall.bat")
-            f = open(scriptfn, "w")
-            # The batch file will be executed with [PYTHON], so that %1
-            # is the path to the Python interpreter; %0 will be the path
-            # of the batch file.
-            # rem ="""
-            # %1 %0
-            # exit
-            # """
-            # <actual script>
-            f.write('rem ="""\n%1 %0\nexit\n"""\n')
-            f.write(open(self.pre_install_script).read())
-            f.close()
+            with open(scriptfn, "w") as f:
+                # The batch file will be executed with [PYTHON], so that %1
+                # is the path to the Python interpreter; %0 will be the path
+                # of the batch file.
+                # rem ="""
+                # %1 %0
+                # exit
+                # """
+                # <actual script>
+                f.write('rem ="""\n%1 %0\nexit\n"""\n')
+                with open(self.pre_install_script) as fp:
+                    f.write(fp.read())
             add_data(self.db, "Binary",
-                [("PreInstall", msilib.Binary(scriptfn))
-                ])
+                     [("PreInstall", msilib.Binary(scriptfn)),
+                     ])
             add_data(self.db, "CustomAction",
-                [("PreInstall", 2, "PreInstall", None)
-                ])
+                     [("PreInstall", 2, "PreInstall", None),
+                     ])
             add_data(self.db, "InstallExecuteSequence",
-                    [("PreInstall", "NOT Installed", 450)])
-
+                     [("PreInstall", "NOT Installed", 450),
+                     ])
 
     def add_ui(self):
         db = self.db
diff --git a/distutils2/command/bdist_wininst.py b/distutils2/command/bdist_wininst.py
--- a/distutils2/command/bdist_wininst.py
+++ b/distutils2/command/bdist_wininst.py
@@ -1,25 +1,21 @@
-"""distutils.command.bdist_wininst
+"""Create an executable installer for Windows."""
 
-Implements the Distutils 'bdist_wininst' command: create a windows installer
-exe-program."""
-
+# FIXME synchronize bytes/str use with same file in distutils
 
 import sys
 import os
-import string
+
 from shutil import rmtree
-try:
-    from sysconfig import get_python_version
-except ImportError:
-    from distutils2._backport.sysconfig import get_python_version
+from sysconfig import get_python_version
 from distutils2.command.cmd import Command
-from distutils2.errors import DistutilsOptionError, DistutilsPlatformError
+from distutils2.errors import PackagingOptionError, PackagingPlatformError
 from distutils2 import logger
 from distutils2.util import get_platform
 
-class bdist_wininst (Command):
 
-    description = "create an executable installer for MS Windows"
+class bdist_wininst(Command):
+
+    description = "create an executable installer for Windows"
 
     user_options = [('bdist-dir=', None,
                      "temporary directory for creating the distribution"),
@@ -61,25 +57,23 @@
     boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
                        'skip-build']
 
-    def initialize_options (self):
+    def initialize_options(self):
         self.bdist_dir = None
         self.plat_name = None
-        self.keep_temp = 0
-        self.no_target_compile = 0
-        self.no_target_optimize = 0
+        self.keep_temp = False
+        self.no_target_compile = False
+        self.no_target_optimize = False
         self.target_version = None
         self.dist_dir = None
         self.bitmap = None
         self.title = None
-        self.skip_build = 0
+        self.skip_build = False
         self.install_script = None
         self.pre_install_script = None
         self.user_access_control = None
 
-    # initialize_options()
 
-
-    def finalize_options (self):
+    def finalize_options(self):
         if self.bdist_dir is None:
             if self.skip_build and self.plat_name:
                 # If build is skipped and plat_name is overridden, bdist will
@@ -94,9 +88,8 @@
         if not self.skip_build and self.distribution.has_ext_modules():
             short_version = get_python_version()
             if self.target_version and self.target_version != short_version:
-                raise DistutilsOptionError, \
-                      "target version can only be %s, or the '--skip-build'" \
-                      " option must be specified" % (short_version,)
+                raise PackagingOptionError("target version can only be %s, or the '--skip-build'" \
+                      " option must be specified" % (short_version,))
             self.target_version = short_version
 
         self.set_undefined_options('bdist', 'dist_dir', 'plat_name')
@@ -106,32 +99,30 @@
                 if self.install_script == os.path.basename(script):
                     break
             else:
-                raise DistutilsOptionError, \
-                      "install_script '%s' not found in scripts" % \
-                      self.install_script
-    # finalize_options()
+                raise PackagingOptionError("install_script '%s' not found in scripts" % \
+                      self.install_script)
 
-
-    def run (self):
+    def run(self):
         if (sys.platform != "win32" and
             (self.distribution.has_ext_modules() or
              self.distribution.has_c_libraries())):
-            raise DistutilsPlatformError \
+            raise PackagingPlatformError \
                   ("distribution contains extensions and/or C libraries; "
                    "must be compiled on a Windows 32 platform")
 
         if not self.skip_build:
             self.run_command('build')
 
-        install = self.get_reinitialized_command('install', reinit_subcommands=1)
+        install = self.get_reinitialized_command('install',
+                                                 reinit_subcommands=True)
         install.root = self.bdist_dir
         install.skip_build = self.skip_build
-        install.warn_dir = 0
+        install.warn_dir = False
         install.plat_name = self.plat_name
 
         install_lib = self.get_reinitialized_command('install_lib')
         # we do not want to include pyc or pyo files
-        install_lib.compile = 0
+        install_lib.compile = False
         install_lib.optimize = 0
 
         if self.distribution.has_ext_modules():
@@ -153,7 +144,7 @@
         # Use a custom scheme for the zip-file, because we have to decide
         # at installation time which scheme to use.
         for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'):
-            value = string.upper(key)
+            value = key.upper()
             if key == 'headers':
                 value = value + '/Include/$dist_name'
             setattr(install,
@@ -196,7 +187,7 @@
             else:
                 rmtree(self.bdist_dir)
 
-    def get_inidata (self):
+    def get_inidata(self):
         # Return data describing the installation.
 
         lines = []
@@ -211,14 +202,14 @@
 
         # Escape newline characters
         def escape(s):
-            return string.replace(s, "\n", "\\n")
+            return s.replace("\n", "\\n")
 
         for name in ["author", "author_email", "description", "maintainer",
                      "maintainer_email", "name", "url", "version"]:
             data = getattr(metadata, name, "")
             if data:
                 info = info + ("\n    %s: %s" % \
-                               (string.capitalize(name), escape(data)))
+                               (name.capitalize(), escape(data)))
                 lines.append("%s=%s" % (name, escape(data)))
 
         # The [setup] section contains entries controlling
@@ -241,11 +232,9 @@
         build_info = "Built %s with distutils2-%s" % \
                      (time.ctime(time.time()), distutils2.__version__)
         lines.append("build_info=%s" % build_info)
-        return string.join(lines, "\n")
+        return "\n".join(lines)
 
-    # get_inidata()
-
-    def create_exe (self, arcname, fullname, bitmap=None):
+    def create_exe(self, arcname, fullname, bitmap=None):
         import struct
 
         self.mkpath(self.dist_dir)
@@ -253,52 +242,48 @@
         cfgdata = self.get_inidata()
 
         installer_name = self.get_installer_filename(fullname)
-        self.announce("creating %s" % installer_name)
+        logger.info("creating %s", installer_name)
 
         if bitmap:
-            bitmapdata = open(bitmap, "rb").read()
+            with open(bitmap, "rb") as fp:
+                bitmapdata = fp.read()
             bitmaplen = len(bitmapdata)
         else:
             bitmaplen = 0
 
-        file = open(installer_name, "wb")
-        file.write(self.get_exe_bytes())
-        if bitmap:
-            file.write(bitmapdata)
+        with open(installer_name, "wb") as file:
+            file.write(self.get_exe_bytes())
+            if bitmap:
+                file.write(bitmapdata)
 
-        # Convert cfgdata from unicode to ascii, mbcs encoded
-        try:
-            unicode
-        except NameError:
-            pass
-        else:
+            # Convert cfgdata from unicode to ascii, mbcs encoded
             if isinstance(cfgdata, unicode):
                 cfgdata = cfgdata.encode("mbcs")
 
-        # Append the pre-install script
-        cfgdata = cfgdata + "\0"
-        if self.pre_install_script:
-            script_data = open(self.pre_install_script, "r").read()
-            cfgdata = cfgdata + script_data + "\n\0"
-        else:
-            # empty pre-install script
+            # Append the pre-install script
             cfgdata = cfgdata + "\0"
-        file.write(cfgdata)
+            if self.pre_install_script:
+                with open(self.pre_install_script) as fp:
+                    script_data = fp.read()
+                cfgdata = cfgdata + script_data + "\n\0"
+            else:
+                # empty pre-install script
+                cfgdata = cfgdata + "\0"
+            file.write(cfgdata)
 
-        # The 'magic number' 0x1234567B is used to make sure that the
-        # binary layout of 'cfgdata' is what the wininst.exe binary
-        # expects.  If the layout changes, increment that number, make
-        # the corresponding changes to the wininst.exe sources, and
-        # recompile them.
-        header = struct.pack("<iii",
-                             0x1234567B,       # tag
-                             len(cfgdata),     # length
-                             bitmaplen,        # number of bytes in bitmap
-                             )
-        file.write(header)
-        file.write(open(arcname, "rb").read())
-
-    # create_exe()
+            # The 'magic number' 0x1234567B is used to make sure that the
+            # binary layout of 'cfgdata' is what the wininst.exe binary
+            # expects.  If the layout changes, increment that number, make
+            # the corresponding changes to the wininst.exe sources, and
+            # recompile them.
+            header = struct.pack("<iii",
+                                 0x1234567B,       # tag
+                                 len(cfgdata),     # length
+                                 bitmaplen,        # number of bytes in bitmap
+                                 )
+            file.write(header)
+            with open(arcname, "rb") as fp:
+                file.write(fp.read())
 
     def get_installer_filename(self, fullname):
         # Factored out to allow overriding in subclasses
@@ -312,9 +297,8 @@
             installer_name = os.path.join(self.dist_dir,
                                           "%s.%s.exe" % (fullname, self.plat_name))
         return installer_name
-    # get_installer_filename()
 
-    def get_exe_bytes (self):
+    def get_exe_bytes(self):
         from distutils2.compiler.msvccompiler import get_build_version
         # If a target-version other than the current version has been
         # specified, then using the MSVC version from *this* build is no good.
@@ -354,5 +338,5 @@
             sfix = ''
 
         filename = os.path.join(directory, "wininst-%.1f%s.exe" % (bv, sfix))
-        return open(filename, "rb").read()
-# class bdist_wininst
+        with open(filename, "rb") as fp:
+            return fp.read()
diff --git a/distutils2/command/build.py b/distutils2/command/build.py
--- a/distutils2/command/build.py
+++ b/distutils2/command/build.py
@@ -1,13 +1,11 @@
-"""distutils.command.build
+"""Main build command, which calls the other build_* commands."""
 
-Implements the Distutils 'build' command.
-"""
 import sys
 import os
 
 from distutils2.util import get_platform
 from distutils2.command.cmd import Command
-from distutils2.errors import DistutilsOptionError
+from distutils2.errors import PackagingOptionError
 from distutils2.compiler import show_compilers
 
 
@@ -67,7 +65,7 @@
         self.compiler = None
         self.plat_name = None
         self.debug = None
-        self.force = 0
+        self.force = False
         self.executable = None
         self.use_2to3 = False
         self.convert_2to3_doctests = None
@@ -81,7 +79,7 @@
             # supported via ./configure flags, if at all).  Avoid misleading
             # other platforms.
             if os.name != 'nt':
-                raise DistutilsOptionError(
+                raise PackagingOptionError(
                             "--plat-name only supported on Windows (try "
                             "using './configure --help' on your platform)")
 
diff --git a/distutils2/command/build_clib.py b/distutils2/command/build_clib.py
--- a/distutils2/command/build_clib.py
+++ b/distutils2/command/build_clib.py
@@ -1,10 +1,8 @@
-"""distutils.command.build_clib
+"""Build C/C++ libraries.
 
-Implements the Distutils 'build_clib' command, to build a C/C++ library
-that is included in the module distribution and needed by an extension
-module."""
-
-
+This command is useful to build libraries that are included in the
+distribution and needed by extension modules.
+"""
 
 # XXX this module has *lots* of code ripped-off quite transparently from
 # build_ext.py -- not surprisingly really, as the work required to build
@@ -17,7 +15,7 @@
 
 import os
 from distutils2.command.cmd import Command
-from distutils2.errors import DistutilsSetupError
+from distutils2.errors import PackagingSetupError
 from distutils2.compiler import customize_compiler
 from distutils2 import logger
 
@@ -29,7 +27,7 @@
 
 class build_clib(Command):
 
-    description = "build C/C++ libraries used by Python extensions"
+    description = "build C/C++ libraries used by extension modules"
 
     user_options = [
         ('build-clib=', 'b',
@@ -63,7 +61,7 @@
         self.define = None
         self.undef = None
         self.debug = None
-        self.force = 0
+        self.force = False
         self.compiler = None
 
 
@@ -84,7 +82,7 @@
 
         if self.include_dirs is None:
             self.include_dirs = self.distribution.include_dirs or []
-        if isinstance(self.include_dirs, str):
+        if isinstance(self.include_dirs, basestring):
             self.include_dirs = self.include_dirs.split(os.pathsep)
 
         # XXX same as for build_ext -- what about 'self.define' and
@@ -105,7 +103,7 @@
             self.compiler.set_include_dirs(self.include_dirs)
         if self.define is not None:
             # 'define' option is a list of (name,value) tuples
-            for (name,value) in self.define:
+            for name, value in self.define:
                 self.compiler.define_macro(name, value)
         if self.undef is not None:
             for macro in self.undef:
@@ -121,34 +119,29 @@
         This method checks that it is a list of 2-tuples, where the tuples
         are (library_name, build_info_dict).
 
-        Raise DistutilsSetupError if the structure is invalid anywhere;
+        Raise PackagingSetupError if the structure is invalid anywhere;
         just returns otherwise.
         """
         if not isinstance(libraries, list):
-            raise DistutilsSetupError, \
-                  "'libraries' option must be a list of tuples"
+            raise PackagingSetupError("'libraries' option must be a list of tuples")
 
         for lib in libraries:
             if not isinstance(lib, tuple) and len(lib) != 2:
-                raise DistutilsSetupError, \
-                      "each element of 'libraries' must a 2-tuple"
+                raise PackagingSetupError("each element of 'libraries' must a 2-tuple")
 
             name, build_info = lib
 
-            if not isinstance(name, str):
-                raise DistutilsSetupError, \
-                      "first element of each tuple in 'libraries' " + \
-                      "must be a string (the library name)"
+            if not isinstance(name, basestring):
+                raise PackagingSetupError("first element of each tuple in 'libraries' " + \
+                      "must be a string (the library name)")
             if '/' in name or (os.sep != '/' and os.sep in name):
-                raise DistutilsSetupError, \
-                      ("bad library name '%s': " +
+                raise PackagingSetupError(("bad library name '%s': " +
                        "may not contain directory separators") % \
-                      lib[0]
+                      lib[0])
 
             if not isinstance(build_info, dict):
-                raise DistutilsSetupError, \
-                      "second element of each tuple in 'libraries' " + \
-                      "must be a dictionary (build info)"
+                raise PackagingSetupError("second element of each tuple in 'libraries' " + \
+                      "must be a dictionary (build info)")
 
     def get_library_names(self):
         # Assume the library list is valid -- 'check_library_list()' is
@@ -157,7 +150,7 @@
             return None
 
         lib_names = []
-        for (lib_name, build_info) in self.libraries:
+        for lib_name, build_info in self.libraries:
             lib_names.append(lib_name)
         return lib_names
 
@@ -165,25 +158,23 @@
     def get_source_files(self):
         self.check_library_list(self.libraries)
         filenames = []
-        for (lib_name, build_info) in self.libraries:
+        for lib_name, build_info in self.libraries:
             sources = build_info.get('sources')
             if sources is None or not isinstance(sources, (list, tuple)):
-                raise DistutilsSetupError, \
-                      ("in 'libraries' option (library '%s'), "
+                raise PackagingSetupError(("in 'libraries' option (library '%s'), "
                        "'sources' must be present and must be "
-                       "a list of source filenames") % lib_name
+                       "a list of source filenames") % lib_name)
 
             filenames.extend(sources)
         return filenames
 
     def build_libraries(self, libraries):
-        for (lib_name, build_info) in libraries:
+        for lib_name, build_info in libraries:
             sources = build_info.get('sources')
             if sources is None or not isinstance(sources, (list, tuple)):
-                raise DistutilsSetupError, \
-                      ("in 'libraries' option (library '%s'), " +
+                raise PackagingSetupError(("in 'libraries' option (library '%s'), " +
                        "'sources' must be present and must be " +
-                       "a list of source filenames") % lib_name
+                       "a list of source filenames") % lib_name)
             sources = list(sources)
 
             logger.info("building '%s' library", lib_name)
diff --git a/distutils2/command/build_ext.py b/distutils2/command/build_ext.py
--- a/distutils2/command/build_ext.py
+++ b/distutils2/command/build_ext.py
@@ -1,30 +1,26 @@
-"""distutils.command.build_ext
+"""Build extension modules."""
 
-Implements the Distutils 'build_ext' command, for building extension
-modules (currently limited to C extensions, should accommodate C++
-extensions ASAP)."""
+# FIXME Is this module limited to C extensions or do C++ extensions work too?
+# The docstring of this module said that C++ was not supported, but other
+# comments contradict that.
 
-
-import sys, os, re
-from warnings import warn
+import os
+import re
+import sys
+import logging
+import sysconfig
 
 from distutils2.util import get_platform
 from distutils2.command.cmd import Command
-from distutils2.errors import (CCompilerError, CompileError, DistutilsError,
-                               DistutilsPlatformError, DistutilsSetupError)
+from distutils2.errors import (CCompilerError, CompileError, PackagingError,
+                               PackagingPlatformError, PackagingSetupError)
 from distutils2.compiler import customize_compiler, show_compilers
 from distutils2.util import newer_group
 from distutils2.compiler.extension import Extension
 from distutils2 import logger
-from distutils2._backport import sysconfig
 
-# this keeps compatibility from 2.3 to 2.5
-if sys.version < "2.6":
-    USER_BASE = None
-    HAS_USER_SITE = False
-else:
-    from site import USER_BASE
-    HAS_USER_SITE = True
+import site
+HAS_USER_SITE = True
 
 if os.name == 'nt':
     from distutils2.compiler.msvccompiler import get_build_version
@@ -38,11 +34,11 @@
 
 class build_ext(Command):
 
-    description = "build C/C++ extensions (compile/link to build directory)"
+    description = "build C/C++ extension modules (compile/link to build directory)"
 
     # XXX thoughts on how to deal with complex command-line options like
     # these, i.e. how to make it so fancy_getopt can suck them off the
-    # command line and make it look like setup.py defined the appropriate
+    # command line and turn them into the appropriate
     # lists of tuples of what-have-you.
     #   - each command needs a callback to process its command-line options
     #   - Command.__init__() needs access to its share of the whole
@@ -90,15 +86,13 @@
          "forcibly build everything (ignore file timestamps)"),
         ('compiler=', 'c',
          "specify the compiler type"),
-        ('swig-cpp', None,
-         "make SWIG create C++ files (default is C)"),
         ('swig-opts=', None,
          "list of SWIG command-line options"),
         ('swig=', None,
          "path to the SWIG executable"),
         ]
 
-    boolean_options = ['inplace', 'debug', 'force', 'swig-cpp']
+    boolean_options = ['inplace', 'debug', 'force']
 
     if HAS_USER_SITE:
         user_options.append(('user', None,
@@ -110,46 +104,12 @@
          "list available compilers", show_compilers),
         ]
 
-
-    # making 'compiler' a property to deprecate
-    # its usage as something else than a compiler type
-    # e.g. like a compiler instance
-    def __init__(self, dist):
-        self._compiler = None
-        Command.__init__(self, dist)
-
-    def __setattr__(self, name, value):
-        # need this to make sure setattr() (used in distutils)
-        # doesn't kill our property
-        if name == 'compiler':
-            self._set_compiler(value)
-        else:
-            self.__dict__[name] = value
-
-    def _set_compiler(self, compiler):
-        if not isinstance(compiler, str) and compiler is not None:
-            # we don't want to allow that anymore in the future
-            warn("'compiler' specifies the compiler type in build_ext. "
-                 "If you want to get the compiler object itself, "
-                 "use 'compiler_obj'", DeprecationWarning)
-        self._compiler = compiler
-
-    def _get_compiler(self):
-        if not isinstance(self._compiler, str) and self._compiler is not None:
-            # we don't want to allow that anymore in the future
-            warn("'compiler' specifies the compiler type in build_ext. "
-                 "If you want to get the compiler object itself, "
-                 "use 'compiler_obj'", DeprecationWarning)
-        return self._compiler
-
-    compiler = property(_get_compiler, _set_compiler)
-
     def initialize_options(self):
         self.extensions = None
         self.build_lib = None
         self.plat_name = None
         self.build_temp = None
-        self.inplace = 0
+        self.inplace = False
         self.package = None
 
         self.include_dirs = None
@@ -163,7 +123,6 @@
         self.force = None
         self.compiler = None
         self.swig = None
-        self.swig_cpp = None
         self.swig_opts = None
         if HAS_USER_SITE:
             self.user = None
@@ -183,7 +142,7 @@
             if not isinstance(self.extensions, (list, tuple)):
                 type_name = (self.extensions is None and 'None'
                             or type(self.extensions).__name__)
-                raise DistutilsSetupError(
+                raise PackagingSetupError(
                     "'ext_modules' must be a sequence of Extension instances,"
                     " not %s" % (type_name,))
             for i, ext in enumerate(self.extensions):
@@ -191,7 +150,7 @@
                     continue                # OK! (assume type-checking done
                                             # by Extension constructor)
                 type_name = (ext is None and 'None' or type(ext).__name__)
-                raise DistutilsSetupError(
+                raise PackagingSetupError(
                     "'ext_modules' item %d must be an Extension instance,"
                     " not %s" % (i, type_name))
 
@@ -201,7 +160,7 @@
         plat_py_include = sysconfig.get_path('platinclude')
         if self.include_dirs is None:
             self.include_dirs = self.distribution.include_dirs or []
-        if isinstance(self.include_dirs, str):
+        if isinstance(self.include_dirs, basestring):
             self.include_dirs = self.include_dirs.split(os.pathsep)
 
         # Put the Python "system" include dir at the end, so that
@@ -210,7 +169,7 @@
         if plat_py_include != py_include:
             self.include_dirs.append(plat_py_include)
 
-        if isinstance(self.libraries, str):
+        if isinstance(self.libraries, basestring):
             self.libraries = [self.libraries]
 
         # Life is easier if we're not forever checking for None, so
@@ -219,12 +178,12 @@
             self.libraries = []
         if self.library_dirs is None:
             self.library_dirs = []
-        elif isinstance(self.library_dirs, str):
+        elif isinstance(self.library_dirs, basestring):
             self.library_dirs = self.library_dirs.split(os.pathsep)
 
         if self.rpath is None:
             self.rpath = []
-        elif isinstance(self.rpath, str):
+        elif isinstance(self.rpath, basestring):
             self.rpath = self.rpath.split(os.pathsep)
 
         # for extensions under windows use different directories
@@ -317,8 +276,8 @@
 
         # Finally add the user include and library directories if requested
         if HAS_USER_SITE and self.user:
-            user_include = os.path.join(USER_BASE, "include")
-            user_lib = os.path.join(USER_BASE, "lib")
+            user_include = os.path.join(site.USER_BASE, "include")
+            user_lib = os.path.join(site.USER_BASE, "lib")
             if os.path.isdir(user_include):
                 self.include_dirs.append(user_include)
             if os.path.isdir(user_lib):
@@ -328,18 +287,6 @@
     def run(self):
         from distutils2.compiler import new_compiler
 
-        # 'self.extensions', as supplied by setup.py, is a list of
-        # Extension instances.  See the documentation for Extension (in
-        # distutils.extension) for details.
-        #
-        # For backwards compatibility with Distutils 0.8.2 and earlier, we
-        # also allow the 'extensions' list to be a list of tuples:
-        #    (ext_name, build_info)
-        # where build_info is a dictionary containing everything that
-        # Extension instances do except the name, with a few things being
-        # differently named.  We convert these 2-tuples to Extension
-        # instances as needed.
-
         if not self.extensions:
             return
 
@@ -351,24 +298,17 @@
             self.libraries.extend(build_clib.get_library_names() or [])
             self.library_dirs.append(build_clib.build_clib)
 
+        # Temporary kludge until we remove the verbose arguments and use
+        # logging everywhere
+        verbose = logger.getEffectiveLevel() >= logging.DEBUG
+
         # Setup the CCompiler object that we'll use to do all the
         # compiling and linking
-
-        # used to prevent the usage of an existing compiler for the
-        # compiler option when calling new_compiler()
-        # this will be removed in 3.3 and 2.8
-        if not isinstance(self._compiler, str):
-            self._compiler = None
-
-        self.compiler_obj = new_compiler(compiler=self._compiler,
-                                         verbose=self.verbose,
+        self.compiler_obj = new_compiler(compiler=self.compiler,
+                                         verbose=verbose,
                                          dry_run=self.dry_run,
                                          force=self.force)
 
-        # used to keep the compiler object reachable with
-        # "self.compiler". this will be removed in 3.3 and 2.8
-        self._compiler = self.compiler_obj
-
         customize_compiler(self.compiler_obj)
         # If we are cross-compiling, init the compiler now (if we are not
         # cross-compiling, init would not hurt, but people may rely on
@@ -384,7 +324,7 @@
             self.compiler_obj.set_include_dirs(self.include_dirs)
         if self.define is not None:
             # 'define' option is a list of (name,value) tuples
-            for (name, value) in self.define:
+            for name, value in self.define:
                 self.compiler_obj.define_macro(name, value)
         if self.undef is not None:
             for macro in self.undef:
@@ -423,19 +363,19 @@
         for ext in self.extensions:
             try:
                 self.build_extension(ext)
-            except (CCompilerError, DistutilsError, CompileError), e:
+            except (CCompilerError, PackagingError, CompileError):
                 if not ext.optional:
                     raise
-                self.warn('building extension "%s" failed: %s' %
-                          (ext.name, e))
+                logger.warning('%s: building extension %r failed: %s',
+                               self.get_command_name(), ext.name,
+                               sys.exc_info()[1])
 
     def build_extension(self, ext):
         sources = ext.sources
         if sources is None or not isinstance(sources, (list, tuple)):
-            raise DistutilsSetupError, \
-                  ("in 'ext_modules' option (extension '%s'), " +
+            raise PackagingSetupError(("in 'ext_modules' option (extension '%s'), " +
                    "'sources' must be present and must be " +
-                   "a list of source filenames") % ext.name
+                   "a list of source filenames") % ext.name)
         sources = list(sources)
 
         ext_path = self.get_ext_fullpath(ext.name)
@@ -484,7 +424,7 @@
         # The setup.py script for Python on Unix needs to be able to
         # get this list so it can perform all the clean up needed to
         # avoid keeping object files around when cleaning out a failed
-        # build of an extension module.  Since Distutils does not
+        # build of an extension module.  Since Packaging does not
         # track dependencies, we have to get rid of intermediates to
         # ensure all the intermediates will be properly re-built.
         #
@@ -527,17 +467,13 @@
         # source -- but there should be an option to put SWIG output in
         # the temp dir.
 
-        if self.swig_cpp:
-            logger.warn("--swig-cpp is deprecated - use --swig-opts=-c++")
-
-        if self.swig_cpp or ('-c++' in self.swig_opts) or \
-           ('-c++' in extension.swig_opts):
+        if ('-c++' in self.swig_opts or '-c++' in extension.swig_opts):
             target_ext = '.cpp'
         else:
             target_ext = '.c'
 
         for source in sources:
-            (base, ext) = os.path.splitext(source)
+            base, ext = os.path.splitext(source)
             if ext == ".i":             # SWIG interface file
                 new_sources.append(base + '_wrap' + target_ext)
                 swig_sources.append(source)
@@ -551,8 +487,6 @@
         swig = self.swig or self.find_swig()
         swig_cmd = [swig, "-python"]
         swig_cmd.extend(self.swig_opts)
-        if self.swig_cpp:
-            swig_cmd.append("-c++")
 
         # Do not override commandline arguments
         if not self.swig_opts:
@@ -591,9 +525,8 @@
             return "swig.exe"
 
         else:
-            raise DistutilsPlatformError, \
-                  ("I don't know how to find (much less run) SWIG "
-                   "on platform '%s'") % os.name
+            raise PackagingPlatformError(("I don't know how to find (much less run) SWIG "
+                   "on platform '%s'") % os.name)
 
     # -- Name generators -----------------------------------------------
     # (extension names, filenames, whatever)
@@ -654,7 +587,7 @@
         provided, "init" + module_name.  Only relevant on Windows, where
         the .pyd file (DLL) must export the module "init" function.
         """
-        initfunc_name = "init" + ext.name.split('.')[-1]
+        initfunc_name = "PyInit_" + ext.name.split('.')[-1]
         if initfunc_name not in ext.export_symbols:
             ext.export_symbols.append(initfunc_name)
         return ext.export_symbols
@@ -723,9 +656,8 @@
 
         else:
             if sysconfig.get_config_var('Py_ENABLE_SHARED'):
-                template = "python%d.%d"
-                pythonlib = (template %
-                             (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
+                pythonlib = 'python{}.{}'.format(
+                    sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)
                 return ext.libraries + [pythonlib]
             else:
                 return ext.libraries
diff --git a/distutils2/command/build_py.py b/distutils2/command/build_py.py
--- a/distutils2/command/build_py.py
+++ b/distutils2/command/build_py.py
@@ -1,15 +1,12 @@
-"""distutils.command.build_py
-
-Implements the Distutils 'build_py' command."""
-
+"""Build pure Python modules (just copy to build directory)."""
 
 import os
 import sys
-import logging
 from glob import glob
 
+from distutils2 import logger
 from distutils2.command.cmd import Command
-from distutils2.errors import DistutilsOptionError, DistutilsFileError
+from distutils2.errors import PackagingOptionError, PackagingFileError
 from distutils2.util import convert_path
 from distutils2.compat import Mixin2to3
 
@@ -18,10 +15,10 @@
 
 class build_py(Command, Mixin2to3):
 
-    description = "\"build\" pure Python modules (copy to build directory)"
+    description = "build pure Python modules (copy to build directory)"
 
     user_options = [
-        ('build-lib=', 'd', "directory to \"build\" (copy) to"),
+        ('build-lib=', 'd', "directory to build (copy) to"),
         ('compile', 'c', "compile .py to .pyc"),
         ('no-compile', None, "don't compile .py files [default]"),
         ('optimize=', 'O',
@@ -45,7 +42,7 @@
         self.package = None
         self.package_data = None
         self.package_dir = None
-        self.compile = 0
+        self.compile = False
         self.optimize = 0
         self.force = None
         self._updated_files = []
@@ -77,7 +74,7 @@
                 self.optimize = int(self.optimize)
                 assert 0 <= self.optimize <= 2
             except (ValueError, AssertionError):
-                raise DistutilsOptionError("optimize must be 0, 1, or 2")
+                raise PackagingOptionError("optimize must be 0, 1, or 2")
 
     def run(self):
         # XXX copy_file by default preserves atime and mtime.  IMHO this is
@@ -111,7 +108,7 @@
             self.run_2to3(self._updated_files, self._doctests_2to3,
                                             self.use_2to3_fixers)
 
-        self.byte_compile(self.get_outputs(include_bytecode=0))
+        self.byte_compile(self.get_outputs(include_bytecode=False))
 
     # -- Top-level worker functions ------------------------------------
 
@@ -154,7 +151,7 @@
             # Each pattern has to be converted to a platform-specific path
             filelist = glob(os.path.join(src_dir, convert_path(pattern)))
             # Files that match more than one pattern are only added once
-            files.extend([fn for fn in filelist if fn not in files])
+            files.extend(fn for fn in filelist if fn not in files)
         return files
 
     def build_package_data(self):
@@ -179,6 +176,7 @@
         """Return the directory, relative to the top of the source
            distribution, where package 'package' should be found
            (at least according to the 'package_dir' option, if any)."""
+
         path = package.split('.')
         if self.package_dir is not None:
             path.insert(0, self.package_dir)
@@ -197,10 +195,10 @@
         # circumvent them.
         if package_dir != "":
             if not os.path.exists(package_dir):
-                raise DistutilsFileError(
+                raise PackagingFileError(
                       "package directory '%s' does not exist" % package_dir)
             if not os.path.isdir(package_dir):
-                raise DistutilsFileError(
+                raise PackagingFileError(
                        "supposed package directory '%s' exists, "
                        "but is not a directory" % package_dir)
 
@@ -210,8 +208,8 @@
             if os.path.isfile(init_py):
                 return init_py
             else:
-                logging.warning(("package init file '%s' not found " +
-                                 "(or not a regular file)"), init_py)
+                logger.warning(("package init file '%s' not found " +
+                                "(or not a regular file)"), init_py)
 
         # Either not in a package at all (__init__.py not expected), or
         # __init__.py doesn't exist -- so don't return the filename.
@@ -219,8 +217,8 @@
 
     def check_module(self, module, module_file):
         if not os.path.isfile(module_file):
-            logging.warning("file %s (for module %s) not found",
-                            module_file, module)
+            logger.warning("file %s (for module %s) not found",
+                           module_file, module)
             return False
         else:
             return True
@@ -240,7 +238,7 @@
                 module = os.path.splitext(os.path.basename(f))[0]
                 modules.append((package, module, f))
             else:
-                self.debug_print("excluding %s" % setup_script)
+                logger.debug("excluding %s", setup_script)
         return modules
 
     def find_modules(self):
@@ -273,10 +271,10 @@
             module_base = path[-1]
 
             try:
-                (package_dir, checked) = packages[package]
+                package_dir, checked = packages[package]
             except KeyError:
                 package_dir = self.get_package_dir(package)
-                checked = 0
+                checked = False
 
             if not checked:
                 init_py = self.check_package(package, package_dir)
@@ -323,10 +321,10 @@
         outfile_path = [build_dir] + list(package) + [module + ".py"]
         return os.path.join(*outfile_path)
 
-    def get_outputs(self, include_bytecode=1):
+    def get_outputs(self, include_bytecode=True):
         modules = self.find_all_modules()
         outputs = []
-        for (package, module, module_file) in modules:
+        for package, module, module_file in modules:
             package = package.split('.')
             filename = self.get_module_outfile(self.build_lib, package, module)
             outputs.append(filename)
@@ -344,7 +342,7 @@
         return outputs
 
     def build_module(self, module, module_file, package):
-        if isinstance(package, str):
+        if isinstance(package, basestring):
             package = package.split('.')
         elif not isinstance(package, (list, tuple)):
             raise TypeError(
@@ -356,11 +354,11 @@
         outfile = self.get_module_outfile(self.build_lib, package, module)
         dir = os.path.dirname(outfile)
         self.mkpath(dir)
-        return self.copy_file(module_file, outfile, preserve_mode=0)
+        return self.copy_file(module_file, outfile, preserve_mode=False)
 
     def build_modules(self):
         modules = self.find_modules()
-        for (package, module, module_file) in modules:
+        for package, module, module_file in modules:
 
             # Now "build" the module -- ie. copy the source file to
             # self.build_lib (the build directory for Python source).
@@ -385,13 +383,14 @@
 
             # Now loop over the modules we found, "building" each one (just
             # copy it to self.build_lib).
-            for (package_, module, module_file) in modules:
+            for package_, module, module_file in modules:
                 assert package == package_
                 self.build_module(module, module_file, package)
 
     def byte_compile(self, files):
         if hasattr(sys, 'dont_write_bytecode') and sys.dont_write_bytecode:
-            self.warn('byte-compiling is disabled, skipping.')
+            logger.warning('%s: byte-compiling is disabled, skipping.',
+                           self.get_command_name())
             return
 
         from distutils2.util import byte_compile
diff --git a/distutils2/command/build_scripts.py b/distutils2/command/build_scripts.py
--- a/distutils2/command/build_scripts.py
+++ b/distutils2/command/build_scripts.py
@@ -1,26 +1,24 @@
-"""distutils.command.build_scripts
+"""Build scripts (copy to build dir and fix up shebang line)."""
 
-Implements the Distutils 'build_scripts' command."""
-
-
-import os, re
-from stat import ST_MODE
+import os
+import re
+import sysconfig
 
 from distutils2.command.cmd import Command
-from distutils2.util import convert_path, newer
+from distutils2.util import convert_path, newer, detect_encoding, fsencode
 from distutils2 import logger
-from distutils2._backport import sysconfig
 from distutils2.compat import Mixin2to3
 
+
 # check if Python is called on the first line with this expression
-first_line_re = re.compile('^#!.*python[0-9.]*([ \t].*)?$')
+first_line_re = re.compile(b'^#!.*python[0-9.]*([ \t].*)?$')
 
-class build_scripts (Command, Mixin2to3):
+class build_scripts(Command, Mixin2to3):
 
-    description = "\"build\" scripts (copy and fixup #! line)"
+    description = "build scripts (copy and fix up shebang line)"
 
     user_options = [
-        ('build-dir=', 'd', "directory to \"build\" (copy) to"),
+        ('build-dir=', 'd', "directory to build (copy) to"),
         ('force', 'f', "forcibly build everything (ignore file timestamps"),
         ('executable=', 'e', "specify final destination interpreter path"),
         ]
@@ -28,7 +26,7 @@
     boolean_options = ['force']
 
 
-    def initialize_options (self):
+    def initialize_options(self):
         self.build_dir = None
         self.scripts = None
         self.force = None
@@ -38,7 +36,7 @@
         self.convert_2to3_doctests = None
         self.use_2to3_fixers = None
 
-    def finalize_options (self):
+    def finalize_options(self):
         self.set_undefined_options('build',
                                    ('build_scripts', 'build_dir'),
                                    'use_2to3', 'use_2to3_fixers',
@@ -49,14 +47,14 @@
     def get_source_files(self):
         return self.scripts
 
-    def run (self):
+    def run(self):
         if not self.scripts:
             return
         copied_files = self.copy_scripts()
-        if self.use_2to3 and self.copied_files:
-            self._run_2to3(self.copied_files, fixers=self.use_2to3_fixers)
+        if self.use_2to3 and copied_files:
+            self._run_2to3(copied_files, fixers=self.use_2to3_fixers)
 
-    def copy_scripts (self):
+    def copy_scripts(self):
         """Copy each script listed in 'self.scripts'; if it's marked as a
         Python script in the Unix way (first line matches 'first_line_re',
         ie. starts with "\#!" and contains "python"), then adjust the first
@@ -65,7 +63,7 @@
         self.mkpath(self.build_dir)
         outfiles = []
         for script in self.scripts:
-            adjust = 0
+            adjust = False
             script = convert_path(script)
             outfile = os.path.join(self.build_dir, os.path.basename(script))
             outfiles.append(outfile)
@@ -78,40 +76,62 @@
             # that way, we'll get accurate feedback if we can read the
             # script.
             try:
-                f = open(script, "r")
+                f = open(script, "rb")
             except IOError:
                 if not self.dry_run:
                     raise
                 f = None
             else:
+                encoding, lines = detect_encoding(f.readline)
+                f.seek(0)
                 first_line = f.readline()
                 if not first_line:
-                    self.warn("%s is an empty file (skipping)" % script)
+                    logger.warning('%s: %s is an empty file (skipping)',
+                                   self.get_command_name(),  script)
                     continue
 
                 match = first_line_re.match(first_line)
                 if match:
-                    adjust = 1
-                    post_interp = match.group(1) or ''
+                    adjust = True
+                    post_interp = match.group(1) or b''
 
             if adjust:
                 logger.info("copying and adjusting %s -> %s", script,
                          self.build_dir)
                 if not self.dry_run:
-                    outf = open(outfile, "w")
                     if not sysconfig.is_python_build():
-                        outf.write("#!%s%s\n" %
-                                   (self.executable,
-                                    post_interp))
+                        executable = self.executable
                     else:
-                        outf.write("#!%s%s\n" %
-                                   (os.path.join(
+                        executable = os.path.join(
                             sysconfig.get_config_var("BINDIR"),
                            "python%s%s" % (sysconfig.get_config_var("VERSION"),
-                                           sysconfig.get_config_var("EXE"))),
-                                    post_interp))
-                    outf.writelines(f.readlines())
-                    outf.close()
+                                           sysconfig.get_config_var("EXE")))
+                    executable = fsencode(executable)
+                    shebang = b"#!" + executable + post_interp + b"\n"
+                    # Python parser starts to read a script using UTF-8 until
+                    # it gets a #coding:xxx cookie. The shebang has to be the
+                    # first line of a file, the #coding:xxx cookie cannot be
+                    # written before. So the shebang has to be decodable from
+                    # UTF-8.
+                    try:
+                        shebang.decode('utf-8')
+                    except UnicodeDecodeError:
+                        raise ValueError(
+                            "The shebang ({!r}) is not decodable "
+                            "from utf-8".format(shebang))
+                    # If the script is encoded to a custom encoding (use a
+                    # #coding:xxx cookie), the shebang has to be decodable from
+                    # the script encoding too.
+                    try:
+                        shebang.decode(encoding)
+                    except UnicodeDecodeError:
+                        raise ValueError(
+                            "The shebang ({!r}) is not decodable "
+                            "from the script encoding ({})"
+                            .format(shebang, encoding))
+                    with open(outfile, "wb") as outf:
+                        outf.write(shebang)
+                        outf.writelines(f.readlines())
                 if f:
                     f.close()
             else:
@@ -124,13 +144,10 @@
                 if self.dry_run:
                     logger.info("changing mode of %s", file)
                 else:
-                    oldmode = os.stat(file)[ST_MODE] & 07777
-                    newmode = (oldmode | 0555) & 07777
+                    oldmode = os.stat(file).st_mode & 0o7777
+                    newmode = (oldmode | 0o555) & 0o7777
                     if newmode != oldmode:
                         logger.info("changing mode of %s from %o to %o",
                                  file, oldmode, newmode)
                         os.chmod(file, newmode)
         return outfiles
-    # copy_scripts ()
-
-# class build_scripts
diff --git a/distutils2/command/check.py b/distutils2/command/check.py
--- a/distutils2/command/check.py
+++ b/distutils2/command/check.py
@@ -1,16 +1,14 @@
-"""distutils.command.check
+"""Check PEP compliance of metadata."""
 
-Implements the Distutils 'check' command.
-"""
-
+from distutils2 import logger
 from distutils2.command.cmd import Command
-from distutils2.errors import DistutilsSetupError
+from distutils2.errors import PackagingSetupError
 from distutils2.util import resolve_name
 
 class check(Command):
-    """This command checks the metadata of the package.
-    """
-    description = ("perform some checks on the package")
+
+    description = "check PEP compliance of metadata"
+
     user_options = [('metadata', 'm', 'Verify metadata'),
                     ('all', 'a',
                      ('runs extended set of checks')),
@@ -21,18 +19,20 @@
 
     def initialize_options(self):
         """Sets default values for options."""
-        self.all = 0
-        self.metadata = 1
-        self.strict = 0
+        self.all = False
+        self.metadata = True
+        self.strict = False
         self._warnings = []
 
     def finalize_options(self):
         pass
 
-    def warn(self, msg):
-        """Counts the number of warnings that occurs."""
-        self._warnings.append(msg)
-        return Command.warn(self, msg)
+    def warn(self, msg, *args):
+        """Wrapper around logging that also remembers messages."""
+        # XXX we could use a special handler for this, but would need to test
+        # if it works even if the logger has a too high level
+        self._warnings.append((msg, args))
+        return logger.warning('%s: %s' % (self.get_command_name(), msg), *args)
 
     def run(self):
         """Runs the command."""
@@ -46,8 +46,8 @@
         # let's raise an error in strict mode, if we have at least
         # one warning
         if self.strict and len(self._warnings) > 0:
-            msg = '\n'.join(self._warnings)
-            raise DistutilsSetupError(msg)
+            msg = '\n'.join(msg % args for msg, args in self._warnings)
+            raise PackagingSetupError(msg)
 
     def check_metadata(self):
         """Ensures that all required elements of metadata are supplied.
@@ -58,7 +58,7 @@
         """
         missing, warnings = self.distribution.metadata.check(strict=True)
         if missing != []:
-            self.warn("missing required metadata: %s"  % ', '.join(missing))
+            self.warn('missing required metadata: %s', ', '.join(missing))
         for warning in warnings:
             self.warn(warning)
 
@@ -74,15 +74,15 @@
                     warning = '%s (line %s)' % (warning[1], line)
                 self.warn(warning)
         elif self.strict:
-            raise DistutilsSetupError('The docutils package is needed.')
+            raise PackagingSetupError('The docutils package is needed.')
 
     def check_hooks_resolvable(self):
-        for options in self.distribution.command_options.itervalues():
+        for options in self.distribution.command_options.values():
             for hook_kind in ("pre_hook", "post_hook"):
                 if hook_kind not in options:
                     break
-                for hook_name in options[hook_kind][1].itervalues():
+                for hook_name in options[hook_kind][1].values():
                     try:
                         resolve_name(hook_name)
                     except ImportError:
-                        self.warn("Name '%s' cannot be resolved." % hook_name)
+                        self.warn('name %r cannot be resolved', hook_name)
diff --git a/distutils2/command/clean.py b/distutils2/command/clean.py
--- a/distutils2/command/clean.py
+++ b/distutils2/command/clean.py
@@ -1,9 +1,6 @@
-"""distutils.command.clean
+"""Clean up temporary files created by the build command."""
 
-Implements the Distutils 'clean' command."""
-
-# contributed by Bastian Kleineidam <calvin at cs.uni-sb.de>, added 2000-03-18
-
+# Contributed by Bastian Kleineidam <calvin at cs.uni-sb.de>
 
 import os
 from shutil import rmtree
@@ -66,7 +63,7 @@
                     else:
                         rmtree(directory)
                 else:
-                    logger.warn("'%s' does not exist -- can't clean it",
+                    logger.warning("'%s' does not exist -- can't clean it",
                                 directory)
 
         # just for the heck of it, try to remove the base build directory:
@@ -77,5 +74,3 @@
                 logger.info("removing '%s'", self.build_base)
             except OSError:
                 pass
-
-# class clean
diff --git a/distutils2/command/cmd.py b/distutils2/command/cmd.py
--- a/distutils2/command/cmd.py
+++ b/distutils2/command/cmd.py
@@ -1,21 +1,16 @@
-"""distutils.cmd
+"""Base class for commands."""
 
-Provides the Command class, the base class for the command classes
-in the distutils.command package.
-"""
 import os
 import re
-import logging
-
-from distutils2.errors import DistutilsOptionError
+from shutil import copyfile, move
 from distutils2 import util
 from distutils2 import logger
-from distutils2._backport.shutil import copytree, copyfile, move, make_archive
+from distutils2.errors import PackagingOptionError
 
 
 class Command(object):
     """Abstract base class for defining command classes, the "worker bees"
-    of the Distutils.  A useful analogy for command classes is to think of
+    of the Packaging.  A useful analogy for command classes is to think of
     them as subroutines with local variables called "options".  The options
     are "declared" in 'initialize_options()' and "defined" (given their
     final values, aka "finalized") in 'finalize_options()', both of which
@@ -62,7 +57,8 @@
         from distutils2.dist import Distribution
 
         if not isinstance(dist, Distribution):
-            raise TypeError("dist must be a Distribution instance")
+            raise TypeError("dist must be an instance of Distribution, not %r"
+                            % type(dist))
         if self.__class__ is Command:
             raise RuntimeError("Command is an abstract class")
 
@@ -70,7 +66,7 @@
         self.initialize_options()
 
         # Per-command versions of the global flags, so that the user can
-        # customize Distutils' behaviour command-by-command and let some
+        # customize Packaging' behaviour command-by-command and let some
         # commands fall back on the Distribution's behaviour.  None means
         # "not defined, check self.distribution's copy", while 0 or 1 mean
         # false and true (duh).  Note that this means figuring out the real
@@ -80,10 +76,6 @@
         #     "fix" it?]
         self._dry_run = None
 
-        # verbose is largely ignored, but needs to be set for
-        # backwards compatibility (I think)?
-        self.verbose = dist.verbose
-
         # Some commands define a 'self.force' option to ignore file
         # timestamps, but methods defined *here* assume that
         # 'self.force' exists for all commands.  So define it here
@@ -92,13 +84,13 @@
 
         # The 'help' flag is just used for command line parsing, so
         # none of that complicated bureaucracy is needed.
-        self.help = 0
+        self.help = False
 
         # 'finalized' records whether or not 'finalize_options()' has been
         # called.  'finalize_options()' itself should not pay attention to
         # this flag: it is the business of 'ensure_finalized()', which
         # always calls 'finalize_options()', to respect/update it.
-        self.finalized = 0
+        self.finalized = False
 
     # XXX A more explicit way to customize dry_run would be better.
     @property
@@ -111,7 +103,7 @@
     def ensure_finalized(self):
         if not self.finalized:
             self.finalize_options()
-        self.finalized = 1
+        self.finalized = True
 
     # Subclasses must define:
     #   initialize_options()
@@ -156,18 +148,17 @@
     def dump_options(self, header=None, indent=""):
         if header is None:
             header = "command options for '%s':" % self.get_command_name()
-        self.announce(indent + header, level=logging.INFO)
+        logger.info(indent + header)
         indent = indent + "  "
         negative_opt = getattr(self, 'negative_opt', ())
-        for (option, _, _) in self.user_options:
+        for option, _, _ in self.user_options:
             if option in negative_opt:
                 continue
             option = option.replace('-', '_')
             if option[-1] == "=":
                 option = option[:-1]
             value = getattr(self, option)
-            self.announce(indent + "%s = %s" % (option, value),
-                          level=logging.INFO)
+            logger.info(indent + "%s = %s", option, value)
 
     def run(self):
         """A command's raison d'etre: carry out the action it exists to
@@ -182,13 +173,6 @@
         raise RuntimeError(
             "abstract method -- subclass %s must override" % self.__class__)
 
-    # TODO remove this method, just use logging.info
-    def announce(self, msg, level=logging.INFO):
-        """If the current verbosity level is of greater than or equal to
-        'level' print 'msg' to stdout.
-        """
-        logger.log(level, msg)
-
     # -- External interface --------------------------------------------
     # (called by outsiders)
 
@@ -221,7 +205,7 @@
     # value meets certain type and value constraints.  If not, we try to
     # force it into conformance (eg. if we expect a list but have a string,
     # split the string on comma and/or whitespace).  If we can't force the
-    # option into conformance, raise DistutilsOptionError.  Thus, command
+    # option into conformance, raise PackagingOptionError.  Thus, command
     # classes need do nothing more than (eg.)
     #   self.ensure_string_list('foo')
     # and they can be guaranteed that thereafter, self.foo will be
@@ -232,8 +216,8 @@
         if val is None:
             setattr(self, option, default)
             return default
-        elif not isinstance(val, str):
-            raise DistutilsOptionError("'%s' must be a %s (got `%s`)" %
+        elif not isinstance(val, basestring):
+            raise PackagingOptionError("'%s' must be a %s (got `%s`)" %
                                        (option, what, val))
         return val
 
@@ -252,28 +236,28 @@
         val = getattr(self, option)
         if val is None:
             return
-        elif isinstance(val, str):
+        elif isinstance(val, basestring):
             setattr(self, option, re.split(r',\s*|\s+', val))
         else:
             if isinstance(val, list):
                 # checks if all elements are str
-                ok = 1
+                ok = True
                 for element in val:
-                    if not isinstance(element, str):
-                        ok = 0
+                    if not isinstance(element, basestring):
+                        ok = False
                         break
             else:
-                ok = 0
+                ok = False
 
             if not ok:
-                raise DistutilsOptionError(
+                raise PackagingOptionError(
                     "'%s' must be a list of strings (got %r)" % (option, val))
 
     def _ensure_tested_string(self, option, tester,
                               what, error_fmt, default=None):
         val = self._ensure_stringlike(option, what, default)
         if val is not None and not tester(val):
-            raise DistutilsOptionError(
+            raise PackagingOptionError(
                 ("error in '%s' option: " + error_fmt) % (option, val))
 
     def ensure_filename(self, option):
@@ -324,7 +308,7 @@
                 setattr(self, dst_option,
                         getattr(src_cmd_obj, src_option))
 
-    def get_finalized_command(self, command, create=1):
+    def get_finalized_command(self, command, create=True):
         """Wrapper around Distribution's 'get_command_obj()' method: find
         (create if necessary and 'create' is true) the command object for
         'command', call its 'ensure_finalized()' method, and return the
@@ -334,7 +318,7 @@
         cmd_obj.ensure_finalized()
         return cmd_obj
 
-    def get_reinitialized_command(self, command, reinit_subcommands=0):
+    def get_reinitialized_command(self, command, reinit_subcommands=False):
         return self.distribution.get_reinitialized_command(
             command, reinit_subcommands)
 
@@ -364,14 +348,10 @@
 
     # -- External world manipulation -----------------------------------
 
-    # TODO remove this method, just use logging.warn
-    def warn(self, msg):
-        logger.warning("warning: %s: %s\n", self.get_command_name(), msg)
-
     def execute(self, func, args, msg=None, level=1):
         util.execute(func, args, msg, dry_run=self.dry_run)
 
-    def mkpath(self, name, mode=0777, dry_run=None, verbose=0):
+    def mkpath(self, name, mode=0o777, dry_run=None, verbose=0):
         if dry_run is None:
             dry_run = self.dry_run
         name = os.path.normpath(name)
@@ -386,7 +366,7 @@
         os.makedirs(name, mode)
 
     def copy_file(self, infile, outfile,
-                   preserve_mode=1, preserve_times=1, link=None, level=1):
+                  preserve_mode=True, preserve_times=True, link=None, level=1):
         """Copy a file respecting verbose, dry-run and force flags.  (The
         former two default to whatever is in the Distribution object, and
         the latter defaults to false for commands that don't define it.)"""
@@ -398,32 +378,34 @@
         copyfile(infile, outfile)
         return outfile, None  # XXX
 
-    def copy_tree(self, infile, outfile,
-                   preserve_mode=1, preserve_times=1, preserve_symlinks=0,
-                   level=1):
+    def copy_tree(self, infile, outfile, preserve_mode=True,
+                  preserve_times=True, preserve_symlinks=False, level=1):
         """Copy an entire directory tree respecting verbose, dry-run,
         and force flags.
         """
         if self.dry_run:
             return  # see if we want to display something
-        return copytree(infile, outfile, preserve_symlinks)
+
+
+        return util.copy_tree(infile, outfile, preserve_mode, preserve_times,
+            preserve_symlinks, not self.force, dry_run=self.dry_run)
 
     def move_file(self, src, dst, level=1):
-        """Move a file respectin dry-run flag."""
+        """Move a file respecting the dry-run flag."""
         if self.dry_run:
             return  # XXX log ?
         return move(src, dst)
 
-    def spawn(self, cmd, search_path=1, level=1):
+    def spawn(self, cmd, search_path=True, level=1):
         """Spawn an external command respecting dry-run flag."""
         from distutils2.util import spawn
         spawn(cmd, search_path, dry_run=self.dry_run)
 
     def make_archive(self, base_name, format, root_dir=None, base_dir=None,
                      owner=None, group=None):
-        return make_archive(base_name, format, root_dir,
-                            base_dir, dry_run=self.dry_run,
-                            owner=owner, group=group)
+        return util.make_archive(base_name, format, root_dir,
+                                 base_dir, dry_run=self.dry_run,
+                                 owner=owner, group=group)
 
     def make_file(self, infiles, outfile, func, args,
                   exec_msg=None, skip_msg=None, level=1):
@@ -439,7 +421,7 @@
             skip_msg = "skipping %s (inputs unchanged)" % outfile
 
         # Allow 'infiles' to be a single string
-        if isinstance(infiles, str):
+        if isinstance(infiles, basestring):
             infiles = (infiles,)
         elif not isinstance(infiles, (list, tuple)):
             raise TypeError(
diff --git a/distutils2/command/command_template b/distutils2/command/command_template
--- a/distutils2/command/command_template
+++ b/distutils2/command/command_template
@@ -1,7 +1,7 @@
-"""Implementation of the 'x' command."""
+"""Do X and Y."""
 
-import logging
-from distutils2.command.cmd import Command
+from packaging import logger
+from packaging.command.cmd import Command
 
 
 class x(Command):
@@ -12,11 +12,10 @@
     # List of option tuples: long name, short name (None if no short
     # name), and help string.
     user_options = [
-        ('', '', # long option, short option (one letter) or None
-         ""), # help text
+        ('', '',  # long option, short option (one letter) or None
+         ""),  # help text
         ]
 
-
     def initialize_options(self):
         self. = None
         self. = None
@@ -28,7 +27,7 @@
 
     def run(self):
         ...
-        logging.info(...)
+        logger.info(...)
 
         if not self.dry_run:
             ...
diff --git a/distutils2/command/config.py b/distutils2/command/config.py
--- a/distutils2/command/config.py
+++ b/distutils2/command/config.py
@@ -1,6 +1,6 @@
-"""distutils.command.config
+"""Prepare the build.
 
-Implements the Distutils 'config' command, a (mostly) empty command class
+This module provides config, a (mostly) empty command class
 that exists mainly to be sub-classed by specific module distributions and
 applications.  The idea is that while every "config" command is different,
 at least they're all named the same, and users always see "config" in the
@@ -8,11 +8,12 @@
 configure-like tasks: "try to compile this C code", or "figure out where
 this header file lives".
 """
+
 import os
 import re
 
 from distutils2.command.cmd import Command
-from distutils2.errors import DistutilsExecError
+from distutils2.errors import PackagingExecError
 from distutils2.compiler import customize_compiler
 from distutils2 import logger
 
@@ -20,7 +21,7 @@
 
 class config(Command):
 
-    description = "prepare to build"
+    description = "prepare the build"
 
     user_options = [
         ('compiler=', None,
@@ -56,8 +57,8 @@
         self.library_dirs = None
 
         # maximal output for now
-        self.noisy = 1
-        self.dump_source = 1
+        self.noisy = True
+        self.dump_source = True
 
         # list of temporary files generated along-the-way that we have
         # to clean at some point
@@ -66,17 +67,17 @@
     def finalize_options(self):
         if self.include_dirs is None:
             self.include_dirs = self.distribution.include_dirs or []
-        elif isinstance(self.include_dirs, str):
+        elif isinstance(self.include_dirs, basestring):
             self.include_dirs = self.include_dirs.split(os.pathsep)
 
         if self.libraries is None:
             self.libraries = []
-        elif isinstance(self.libraries, str):
+        elif isinstance(self.libraries, basestring):
             self.libraries = [self.libraries]
 
         if self.library_dirs is None:
             self.library_dirs = []
-        elif isinstance(self.library_dirs, str):
+        elif isinstance(self.library_dirs, basestring):
             self.library_dirs = self.library_dirs.split(os.pathsep)
 
     def run(self):
@@ -97,7 +98,7 @@
         from distutils2.compiler import new_compiler
         if not isinstance(self.compiler, CCompiler):
             self.compiler = new_compiler(compiler=self.compiler,
-                                         dry_run=self.dry_run, force=1)
+                                         dry_run=self.dry_run, force=True)
             customize_compiler(self.compiler)
             if self.include_dirs:
                 self.compiler.set_include_dirs(self.include_dirs)
@@ -109,36 +110,35 @@
 
     def _gen_temp_sourcefile(self, body, headers, lang):
         filename = "_configtest" + LANG_EXT[lang]
-        file = open(filename, "w")
-        if headers:
-            for header in headers:
-                file.write("#include <%s>\n" % header)
-            file.write("\n")
-        file.write(body)
-        if body[-1] != "\n":
-            file.write("\n")
-        file.close()
+        with open(filename, "w") as file:
+            if headers:
+                for header in headers:
+                    file.write("#include <%s>\n" % header)
+                file.write("\n")
+            file.write(body)
+            if body[-1] != "\n":
+                file.write("\n")
         return filename
 
     def _preprocess(self, body, headers, include_dirs, lang):
         src = self._gen_temp_sourcefile(body, headers, lang)
         out = "_configtest.i"
-        self.temp_files.extend([src, out])
+        self.temp_files.extend((src, out))
         self.compiler.preprocess(src, out, include_dirs=include_dirs)
-        return (src, out)
+        return src, out
 
     def _compile(self, body, headers, include_dirs, lang):
         src = self._gen_temp_sourcefile(body, headers, lang)
         if self.dump_source:
             dump_file(src, "compiling '%s':" % src)
-        (obj,) = self.compiler.object_filenames([src])
-        self.temp_files.extend([src, obj])
+        obj = self.compiler.object_filenames([src])[0]
+        self.temp_files.extend((src, obj))
         self.compiler.compile([src], include_dirs=include_dirs)
-        return (src, obj)
+        return src, obj
 
     def _link(self, body, headers, include_dirs, libraries, library_dirs,
               lang):
-        (src, obj) = self._compile(body, headers, include_dirs, lang)
+        src, obj = self._compile(body, headers, include_dirs, lang)
         prog = os.path.splitext(os.path.basename(src))[0]
         self.compiler.link_executable([obj], prog,
                                       libraries=libraries,
@@ -149,7 +149,7 @@
             prog = prog + self.compiler.exe_extension
         self.temp_files.append(prog)
 
-        return (src, obj, prog)
+        return src, obj, prog
 
     def _clean(self, *filenames):
         if not filenames:
@@ -182,11 +182,11 @@
         """
         from distutils2.compiler.ccompiler import CompileError
         self._check_compiler()
-        ok = 1
+        ok = True
         try:
             self._preprocess(body, headers, include_dirs, lang)
         except CompileError:
-            ok = 0
+            ok = False
 
         self._clean()
         return ok
@@ -203,20 +203,19 @@
         self._check_compiler()
         src, out = self._preprocess(body, headers, include_dirs, lang)
 
-        if isinstance(pattern, str):
+        if isinstance(pattern, basestring):
             pattern = re.compile(pattern)
 
-        file = open(out)
-        match = 0
-        while 1:
-            line = file.readline()
-            if line == '':
-                break
-            if pattern.search(line):
-                match = 1
-                break
+        with open(out) as file:
+            match = False
+            while True:
+                line = file.readline()
+                if line == '':
+                    break
+                if pattern.search(line):
+                    match = True
+                    break
 
-        file.close()
         self._clean()
         return match
 
@@ -228,9 +227,9 @@
         self._check_compiler()
         try:
             self._compile(body, headers, include_dirs, lang)
-            ok = 1
+            ok = True
         except CompileError:
-            ok = 0
+            ok = False
 
         logger.info(ok and "success!" or "failure.")
         self._clean()
@@ -247,9 +246,9 @@
         try:
             self._link(body, headers, include_dirs,
                        libraries, library_dirs, lang)
-            ok = 1
+            ok = True
         except (CompileError, LinkError):
-            ok = 0
+            ok = False
 
         logger.info(ok and "success!" or "failure.")
         self._clean()
@@ -267,9 +266,9 @@
             src, obj, exe = self._link(body, headers, include_dirs,
                                        libraries, library_dirs, lang)
             self.spawn([exe])
-            ok = 1
-        except (CompileError, LinkError, DistutilsExecError):
-            ok = 0
+            ok = True
+        except (CompileError, LinkError, PackagingExecError):
+            ok = False
 
         logger.info(ok and "success!" or "failure.")
         self._clean()
@@ -281,7 +280,7 @@
     # when implementing a real-world config command!)
 
     def check_func(self, func, headers=None, include_dirs=None,
-                   libraries=None, library_dirs=None, decl=0, call=0):
+                   libraries=None, library_dirs=None, decl=False, call=False):
 
         """Determine if function 'func' is available by constructing a
         source file that refers to 'func', and compiles and links it.
@@ -312,8 +311,6 @@
         return self.try_link(body, headers, include_dirs,
                              libraries, library_dirs)
 
-    # check_func ()
-
     def check_lib(self, library, library_dirs=None, headers=None,
                   include_dirs=None, other_libraries=[]):
         """Determine if 'library' is available to be linked against,
@@ -348,8 +345,5 @@
         logger.info(filename)
     else:
         logger.info(head)
-    file = open(filename)
-    try:
+    with open(filename) as file:
         logger.info(file.read())
-    finally:
-        file.close()
diff --git a/distutils2/command/install_data.py b/distutils2/command/install_data.py
--- a/distutils2/command/install_data.py
+++ b/distutils2/command/install_data.py
@@ -1,20 +1,18 @@
-"""distutils.command.install_data
+"""Install platform-independent data files."""
 
-Implements the Distutils 'install_data' command, for installing
-platform-independent data files."""
+# Contributed by Bastian Kleineidam
 
-# contributed by Bastian Kleineidam
+import os, sys
+from shutil import Error
+from sysconfig import get_paths, format_value
+from distutils2 import logger
+from distutils2.util import convert_path
+from distutils2.command.cmd import Command
 
 
-import os
-from distutils2.command.cmd import Command
-from distutils2.util import change_root, convert_path
-from distutils2._backport.sysconfig import get_paths, format_value
-from distutils2._backport.shutil import Error
-
 class install_data(Command):
 
-    description = "install data files"
+    description = "install platform-independent data files"
 
     user_options = [
         ('install-dir=', 'd',
@@ -32,9 +30,9 @@
         self.outfiles = []
         self.data_files_out = []
         self.root = None
-        self.force = 0
+        self.force = False
         self.data_files = self.distribution.data_files
-        self.warn_dir = 1
+        self.warn_dir = True
 
     def finalize_options(self):
         self.set_undefined_options('install_dist',
@@ -43,19 +41,20 @@
 
     def run(self):
         self.mkpath(self.install_dir)
-        for file in self.data_files.items():
-            destination = convert_path(self.expand_categories(file[1]))
+        for _file in self.data_files.items():
+            destination = convert_path(self.expand_categories(_file[1]))
             dir_dest = os.path.abspath(os.path.dirname(destination))
-            
+
             self.mkpath(dir_dest)
             try:
-                (out, _) = self.copy_file(file[0], dir_dest)
-            except Error, e:
-                self.warn(e)
+                out = self.copy_file(_file[0], dir_dest)[0]
+            except Error:
+                e = sys.exc_info()[1]
+                logger.warning('%s: %s', self.get_command_name(), e)
                 out = destination
 
             self.outfiles.append(out)
-            self.data_files_out.append((file[0], destination))
+            self.data_files_out.append((_file[0], destination))
 
     def expand_categories(self, path_with_categories):
         local_vars = get_paths()
@@ -63,15 +62,16 @@
         expanded_path = format_value(path_with_categories, local_vars)
         expanded_path = format_value(expanded_path, local_vars)
         if '{' in expanded_path and '}' in expanded_path:
-            self.warn("Unable to expand %s, some categories may missing." %
-                path_with_categories)
+            logger.warning(
+                '%s: unable to expand %s, some categories may be missing',
+                self.get_command_name(), path_with_categories)
         return expanded_path
 
     def get_source_files(self):
-        return self.data_files.keys()
+        return list(self.data_files)
 
     def get_inputs(self):
-        return self.data_files.keys()
+        return list(self.data_files)
 
     def get_outputs(self):
         return self.outfiles
diff --git a/distutils2/command/install_dist.py b/distutils2/command/install_dist.py
--- a/distutils2/command/install_dist.py
+++ b/distutils2/command/install_dist.py
@@ -1,27 +1,20 @@
-"""distutils.command.install
-
-Implements the Distutils 'install_dist' command."""
-
+"""Main install command, which calls the other install_* commands."""
 
 import sys
 import os
 
-from distutils2._backport import sysconfig
-from distutils2._backport.sysconfig import (get_config_vars, get_paths,
-                                            get_path, get_config_var)
+import sysconfig
+from sysconfig import get_config_vars, get_paths, get_path, get_config_var
 
 from distutils2 import logger
 from distutils2.command.cmd import Command
-from distutils2.errors import DistutilsPlatformError
+from distutils2.errors import PackagingPlatformError
 from distutils2.util import write_file
 from distutils2.util import convert_path, change_root, get_platform
-from distutils2.errors import DistutilsOptionError
+from distutils2.errors import PackagingOptionError
 
-# compatibility with 2.4 and 2.5
-if sys.version < '2.6':
-    HAS_USER_SITE = False
-else:
-    HAS_USER_SITE = True
+
+HAS_USER_SITE = True
 
 
 class install_dist(Command):
@@ -123,7 +116,7 @@
         self.exec_prefix = None
         self.home = None
         if HAS_USER_SITE:
-            self.user = 0
+            self.user = False
 
         # These select only the installation base; it's up to the user to
         # specify the installation scheme (currently, that means supplying
@@ -158,7 +151,7 @@
         # 'install_path_file' is always true unless some outsider meddles
         # with it.
         self.extra_path = None
-        self.install_path_file = 1
+        self.install_path_file = True
 
         # 'force' forces installation, even if target files are not
         # out-of-date.  'skip_build' skips running the "build" command,
@@ -166,9 +159,9 @@
         # a user option, it's just there so the bdist_* commands can turn
         # it off) determines whether we warn about installing to a
         # directory not in sys.path.
-        self.force = 0
-        self.skip_build = 0
-        self.warn_dir = 1
+        self.force = False
+        self.skip_build = False
+        self.warn_dir = True
 
         # These are only here as a conduit from the 'build' command to the
         # 'install_*' commands that do the real work.  ('build_base' isn't
@@ -218,25 +211,27 @@
 
         if ((self.prefix or self.exec_prefix or self.home) and
             (self.install_base or self.install_platbase)):
-            raise DistutilsOptionError(
+            raise PackagingOptionError(
                 "must supply either prefix/exec-prefix/home or "
                 "install-base/install-platbase -- not both")
 
         if self.home and (self.prefix or self.exec_prefix):
-            raise DistutilsOptionError(
+            raise PackagingOptionError(
                 "must supply either home or prefix/exec-prefix -- not both")
 
         if HAS_USER_SITE and self.user and (
                 self.prefix or self.exec_prefix or self.home or
                 self.install_base or self.install_platbase):
-            raise DistutilsOptionError(
+            raise PackagingOptionError(
                 "can't combine user with prefix/exec_prefix/home or "
                 "install_base/install_platbase")
 
         # Next, stuff that's wrong (or dubious) only on certain platforms.
         if os.name != "posix":
             if self.exec_prefix:
-                self.warn("exec-prefix option ignored on this platform")
+                logger.warning(
+                    '%s: exec-prefix option ignored on this platform',
+                    self.get_command_name())
                 self.exec_prefix = None
 
         # Now the interesting logic -- so interesting that we farm it out
@@ -355,14 +350,14 @@
                 self.install_headers is None or
                 self.install_scripts is None or
                 self.install_data is None):
-                raise DistutilsOptionError(
+                raise PackagingOptionError(
                     "install-base or install-platbase supplied, but "
                     "installation scheme is incomplete")
             return
 
         if HAS_USER_SITE and self.user:
             if self.install_userbase is None:
-                raise DistutilsPlatformError(
+                raise PackagingPlatformError(
                     "user base directory is not specified")
             self.install_base = self.install_platbase = self.install_userbase
             self.select_scheme("posix_user")
@@ -372,7 +367,7 @@
         else:
             if self.prefix is None:
                 if self.exec_prefix is not None:
-                    raise DistutilsOptionError(
+                    raise PackagingOptionError(
                         "must not supply exec-prefix without prefix")
 
                 self.prefix = os.path.normpath(sys.prefix)
@@ -390,7 +385,7 @@
         """Finalize options for non-posix platforms"""
         if HAS_USER_SITE and self.user:
             if self.install_userbase is None:
-                raise DistutilsPlatformError(
+                raise PackagingPlatformError(
                     "user base directory is not specified")
             self.install_base = self.install_platbase = self.install_userbase
             self.select_scheme(os.name + "_user")
@@ -405,7 +400,7 @@
             try:
                 self.select_scheme(os.name)
             except KeyError:
-                raise DistutilsPlatformError(
+                raise PackagingPlatformError(
                     "no support for installation on '%s'" % os.name)
 
     def dump_dirs(self, msg):
@@ -428,7 +423,7 @@
         """Set the install directories by applying the install schemes."""
         # it's the caller's problem if they supply a bad name!
         scheme = get_paths(name, expand=False)
-        for key, value in scheme.iteritems():
+        for key, value in scheme.items():
             if key == 'platinclude':
                 key = 'headers'
                 value = os.path.join(value, self.distribution.metadata['Name'])
@@ -469,7 +464,7 @@
             self.extra_path = self.distribution.extra_path
 
         if self.extra_path is not None:
-            if isinstance(self.extra_path, str):
+            if isinstance(self.extra_path, basestring):
                 self.extra_path = self.extra_path.split(',')
 
             if len(self.extra_path) == 1:
@@ -477,7 +472,7 @@
             elif len(self.extra_path) == 2:
                 path_file, extra_dirs = self.extra_path
             else:
-                raise DistutilsOptionError(
+                raise PackagingOptionError(
                     "'extra_path' option must be a list, tuple, or "
                     "comma-separated string with 1 or 2 elements")
 
@@ -504,9 +499,9 @@
         if HAS_USER_SITE and not self.user:
             return
         home = convert_path(os.path.expanduser("~"))
-        for name, path in self.config_vars.iteritems():
+        for name, path in self.config_vars.items():
             if path.startswith(home) and not os.path.isdir(path):
-                os.makedirs(path, 0700)
+                os.makedirs(path, 0o700)
 
     # -- Command execution methods -------------------------------------
 
@@ -521,7 +516,7 @@
             # internally, and not to sys.path, so we don't check the platform
             # matches what we are running.
             if self.warn_dir and build_plat != get_platform():
-                raise DistutilsPlatformError("Can't install when "
+                raise PackagingPlatformError("Can't install when "
                                              "cross-compiling")
 
         # Run all sub-commands (at least those that need to be run)
@@ -536,16 +531,16 @@
             outputs = self.get_outputs()
             if self.root:               # strip any package prefix
                 root_len = len(self.root)
-                for counter in xrange(len(outputs)):
+                for counter in range(len(outputs)):
                     outputs[counter] = outputs[counter][root_len:]
             self.execute(write_file,
                          (self.record, outputs),
                          "writing list of installed files to '%s'" %
                          self.record)
 
-        sys_path = map(os.path.normpath, sys.path)
-        sys_path = map(os.path.normcase, sys_path)
-        install_lib = os.path.normcase(os.path.normpath(self.install_lib))
+        normpath, normcase = os.path.normpath, os.path.normcase
+        sys_path = [normcase(normpath(p)) for p in sys.path]
+        install_lib = normcase(normpath(self.install_lib))
         if (self.warn_dir and
             not (self.path_file and self.install_path_file) and
             install_lib not in sys_path):
@@ -563,7 +558,8 @@
                          (filename, [self.extra_dirs]),
                          "creating %s" % filename)
         else:
-            self.warn("path file '%s' not created" % filename)
+            logger.warning('%s: path file %r not created',
+                           self.get_command_name(),  filename)
 
     # -- Reporting methods ---------------------------------------------
 
diff --git a/distutils2/command/install_distinfo.py b/distutils2/command/install_distinfo.py
--- a/distutils2/command/install_distinfo.py
+++ b/distutils2/command/install_distinfo.py
@@ -1,27 +1,16 @@
-"""
-distutils.command.install_distinfo
-==================================
+"""Create the PEP 376-compliant .dist-info directory."""
 
-:Author: Josip Djolonga
+# Forked from the former install_egg_info command by Josip Djolonga
 
-This module implements the ``install_distinfo`` command that creates the
-``.dist-info`` directory for the distribution, as specified in :pep:`376`.
-Usually, you do not have to call this command directly, it gets called
-automatically by the ``install_dist`` command.
-"""
-
-# This file was created from the code for the former command install_egg_info
-
+import codecs
 import csv
-from distutils2 import logger
-from distutils2._backport.shutil import rmtree
-from distutils2.command.cmd import Command
 import os
 import re
-try:
-    import hashlib
-except ImportError:
-    from distutils2._backport import hashlib
+import hashlib
+
+from distutils2.command.cmd import Command
+from distutils2 import logger
+from shutil import rmtree
 
 
 class install_distinfo(Command):
@@ -72,13 +61,11 @@
         if self.no_resources is None:
             self.no_resources = False
 
-
         metadata = self.distribution.metadata
 
         basename = "%s-%s.dist-info" % (
-                                        to_filename(safe_name(metadata['Name'])),
-                                        to_filename(safe_version(metadata['Version'])),
-                                        )
+            to_filename(safe_name(metadata['Name'])),
+            to_filename(safe_version(metadata['Version'])))
 
         self.distinfo_dir = os.path.join(self.distinfo_dir, basename)
         self.outputs = []
@@ -105,18 +92,14 @@
 
             installer_path = os.path.join(self.distinfo_dir, 'INSTALLER')
             logger.info('creating %s', installer_path)
-            f = open(installer_path, 'w')
-            try:
+            with open(installer_path, 'w') as f:
                 f.write(self.installer)
-            finally:
-                f.close()
             self.outputs.append(installer_path)
 
             if self.requested:
                 requested_path = os.path.join(self.distinfo_dir, 'REQUESTED')
                 logger.info('creating %s', requested_path)
-                f = open(requested_path, 'w')
-                f.close()
+                open(requested_path, 'wb').close()
                 self.outputs.append(requested_path)
 
 
@@ -126,25 +109,21 @@
                     resources_path = os.path.join(self.distinfo_dir,
                                                   'RESOURCES')
                     logger.info('creating %s', resources_path)
-                    f = open(resources_path, 'wb')
-                    try:
+                    with open(resources_path, 'wb') as f:
                         writer = csv.writer(f, delimiter=',',
-                                            lineterminator=os.linesep,
+                                            lineterminator='\n',
                                             quotechar='"')
                         for tuple in install_data.get_resources_out():
                             writer.writerow(tuple)
 
                         self.outputs.append(resources_path)
-                    finally:
-                        f.close()
 
             if not self.no_record:
                 record_path = os.path.join(self.distinfo_dir, 'RECORD')
                 logger.info('creating %s', record_path)
-                f = open(record_path, 'wb')
-                try:
+                with codecs.open(record_path, 'w', encoding='utf-8') as f:
                     writer = csv.writer(f, delimiter=',',
-                                        lineterminator=os.linesep,
+                                        lineterminator='\n',
                                         quotechar='"')
 
                     install = self.get_finalized_command('install_dist')
@@ -155,18 +134,15 @@
                             writer.writerow((fpath, '', ''))
                         else:
                             size = os.path.getsize(fpath)
-                            fd = open(fpath, 'r')
-                            hash = hashlib.md5()
-                            hash.update(fd.read())
+                            with open(fpath, 'rb') as fp:
+                                hash = hashlib.md5()
+                                hash.update(fp.read())
                             md5sum = hash.hexdigest()
                             writer.writerow((fpath, md5sum, size))
 
                     # add the RECORD file itself
                     writer.writerow((record_path, '', ''))
                     self.outputs.append(record_path)
-                finally:
-                    f.close()
-
 
     def get_outputs(self):
         return self.outputs
diff --git a/distutils2/command/install_headers.py b/distutils2/command/install_headers.py
--- a/distutils2/command/install_headers.py
+++ b/distutils2/command/install_headers.py
@@ -1,8 +1,4 @@
-"""distutils.command.install_headers
-
-Implements the Distutils 'install_headers' command, to install C/C++ header
-files to the Python include directory."""
-
+"""Install C/C++ header files to the Python include directory."""
 
 from distutils2.command.cmd import Command
 
@@ -22,7 +18,7 @@
 
     def initialize_options(self):
         self.install_dir = None
-        self.force = 0
+        self.force = False
         self.outfiles = []
 
     def finalize_options(self):
@@ -37,7 +33,7 @@
 
         self.mkpath(self.install_dir)
         for header in headers:
-            (out, _) = self.copy_file(header, self.install_dir)
+            out = self.copy_file(header, self.install_dir)[0]
             self.outfiles.append(out)
 
     def get_inputs(self):
@@ -45,5 +41,3 @@
 
     def get_outputs(self):
         return self.outfiles
-
-# class install_headers
diff --git a/distutils2/command/install_lib.py b/distutils2/command/install_lib.py
--- a/distutils2/command/install_lib.py
+++ b/distutils2/command/install_lib.py
@@ -1,14 +1,12 @@
-"""distutils.command.install_lib
-
-Implements the Distutils 'install_lib' command
-(install all Python modules)."""
-
+"""Install all modules (extensions and pure Python)."""
 
 import os
 import sys
+import logging
 
+from distutils2 import logger
 from distutils2.command.cmd import Command
-from distutils2.errors import DistutilsOptionError
+from distutils2.errors import PackagingOptionError
 
 
 # Extension for Python source files.
@@ -19,7 +17,7 @@
 
 class install_lib(Command):
 
-    description = "install all Python modules (extensions and pure Python)"
+    description = "install all modules (extensions and pure Python)"
 
     # The byte-compilation options are a tad confusing.  Here are the
     # possible scenarios:
@@ -55,7 +53,7 @@
         # let the 'install_dist' command dictate our installation directory
         self.install_dir = None
         self.build_dir = None
-        self.force = 0
+        self.force = False
         self.compile = None
         self.optimize = None
         self.skip_build = None
@@ -70,7 +68,7 @@
                                    'force', 'compile', 'optimize', 'skip_build')
 
         if self.compile is None:
-            self.compile = 1
+            self.compile = True
         if self.optimize is None:
             self.optimize = 0
 
@@ -80,7 +78,7 @@
                 if self.optimize not in (0, 1, 2):
                     raise AssertionError
             except (ValueError, AssertionError):
-                raise DistutilsOptionError, "optimize must be 0, 1, or 2"
+                raise PackagingOptionError("optimize must be 0, 1, or 2")
 
     def run(self):
         # Make sure we have built everything we need first
@@ -109,14 +107,19 @@
         if os.path.isdir(self.build_dir):
             outfiles = self.copy_tree(self.build_dir, self.install_dir)
         else:
-            self.warn("'%s' does not exist -- no Python modules to install" %
-                      self.build_dir)
+            logger.warning(
+                '%s: %r does not exist -- no Python modules to install',
+                self.get_command_name(), self.build_dir)
             return
         return outfiles
 
     def byte_compile(self, files):
-        if hasattr(sys, 'dont_write_bytecode') and sys.dont_write_bytecode:
-            self.warn('byte-compiling is disabled, skipping.')
+        if getattr(sys, 'dont_write_bytecode'):
+            # XXX do we want this?  because a Python runs without bytecode
+            # doesn't mean that the *dists should not contain bytecode
+            #--or does it?
+            logger.warning('%s: byte-compiling is disabled, skipping.',
+                           self.get_command_name())
             return
 
         from distutils2.util import byte_compile
@@ -127,6 +130,10 @@
         # should at least generate usable bytecode in RPM distributions.
         install_root = self.get_finalized_command('install_dist').root
 
+        # Temporary kludge until we remove the verbose arguments and use
+        # logging everywhere
+        verbose = logger.getEffectiveLevel() >= logging.DEBUG
+
         if self.compile:
             byte_compile(files, optimize=0,
                          force=self.force, prefix=install_root,
@@ -134,7 +141,8 @@
         if self.optimize > 0:
             byte_compile(files, optimize=self.optimize,
                          force=self.force, prefix=install_root,
-                         verbose=self.verbose, dry_run=self.dry_run)
+                         verbose=verbose,
+                         dry_run=self.dry_run)
 
 
     # -- Utility methods -----------------------------------------------
diff --git a/distutils2/command/install_scripts.py b/distutils2/command/install_scripts.py
--- a/distutils2/command/install_scripts.py
+++ b/distutils2/command/install_scripts.py
@@ -1,17 +1,12 @@
-"""distutils.command.install_scripts
+"""Install scripts."""
 
-Implements the Distutils 'install_scripts' command, for installing
-Python scripts."""
-
-# contributed by Bastian Kleineidam
-
+# Contributed by Bastian Kleineidam
 
 import os
 from distutils2.command.cmd import Command
 from distutils2 import logger
-from stat import ST_MODE
 
-class install_scripts (Command):
+class install_scripts(Command):
 
     description = "install scripts (Python or otherwise)"
 
@@ -25,19 +20,19 @@
     boolean_options = ['force', 'skip-build']
 
 
-    def initialize_options (self):
+    def initialize_options(self):
         self.install_dir = None
-        self.force = 0
+        self.force = False
         self.build_dir = None
         self.skip_build = None
 
-    def finalize_options (self):
+    def finalize_options(self):
         self.set_undefined_options('build', ('build_scripts', 'build_dir'))
         self.set_undefined_options('install_dist',
                                    ('install_scripts', 'install_dir'),
                                    'force', 'skip_build')
 
-    def run (self):
+    def run(self):
         if not self.skip_build:
             self.run_command('build_scripts')
 
@@ -53,11 +48,11 @@
                 if self.dry_run:
                     logger.info("changing mode of %s", file)
                 else:
-                    mode = ((os.stat(file)[ST_MODE]) | 0555) & 07777
+                    mode = (os.stat(file).st_mode | 0o555) & 0o7777
                     logger.info("changing mode of %s to %o", file, mode)
                     os.chmod(file, mode)
 
-    def get_inputs (self):
+    def get_inputs(self):
         return self.distribution.scripts or []
 
     def get_outputs(self):
diff --git a/distutils2/command/register.py b/distutils2/command/register.py
--- a/distutils2/command/register.py
+++ b/distutils2/command/register.py
@@ -1,26 +1,20 @@
-"""distutils.command.register
+"""Register a release with a project index."""
 
-Implements the Distutils 'register' command (register with the repository).
-"""
+# Contributed by Richard Jones
 
-# created 2002/10/21, Richard Jones
-
-
-import urllib2
+import sys
 import getpass
 import urlparse
-import StringIO
-import logging
+import urllib2
 
+from distutils2 import logger
+from distutils2.util import (read_pypirc, generate_pypirc, DEFAULT_REPOSITORY,
+                            DEFAULT_REALM, get_pypirc_path, encode_multipart)
 from distutils2.command.cmd import Command
-from distutils2 import logger
-from distutils2.metadata import metadata_to_dict
-from distutils2.util import (read_pypirc, generate_pypirc, DEFAULT_REPOSITORY,
-                             DEFAULT_REALM, get_pypirc_path)
 
 class register(Command):
 
-    description = "register the distribution with the Python package index"
+    description = "register a release with PyPI"
     user_options = [
         ('repository=', 'r',
          "repository URL [default: %s]" % DEFAULT_REPOSITORY),
@@ -37,9 +31,9 @@
     def initialize_options(self):
         self.repository = None
         self.realm = None
-        self.show_response = 0
-        self.list_classifiers = 0
-        self.strict = 0
+        self.show_response = False
+        self.list_classifiers = False
+        self.strict = False
 
     def finalize_options(self):
         if self.repository is None:
@@ -48,14 +42,17 @@
             self.realm = DEFAULT_REALM
 
     def run(self):
-        self.finalize_options()
         self._set_config()
 
         # Check the package metadata
         check = self.distribution.get_command_obj('check')
-        check.strict = self.strict
-        check.all = 1
-        self.run_command('check')
+        if check.strict != self.strict and not check.all:
+            # If check was already run but with different options,
+            # re-run it
+            check.strict = self.strict
+            check.all = True
+            self.distribution.have_run.pop('check', None)
+            self.run_command('check')
 
         if self.dry_run:
             self.verify_metadata()
@@ -123,6 +120,9 @@
              3. set the password to a random string and email the user.
 
         '''
+        # TODO factor registration out into another method
+        # TODO use print to print, not logging
+
         # see if we can short-cut and get the username/password from the
         # config
         if self.has_config:
@@ -136,24 +136,24 @@
         # get the user's login info
         choices = '1 2 3 4'.split()
         while choice not in choices:
-            self.announce('''\
+            logger.info('''\
 We need to know who you are, so please choose either:
  1. use your existing login,
  2. register as a new user,
  3. have the server generate a new password for you (and email it to you), or
  4. quit
-Your selection [default 1]: ''', logging.INFO)
+Your selection [default 1]: ''')
 
-            choice = raw_input()
+            choice = input()
             if not choice:
                 choice = '1'
             elif choice not in choices:
-                print 'Please choose one of the four options!'
+                print('Please choose one of the four options!')
 
         if choice == '1':
             # get the username and password
             while not username:
-                username = raw_input('Username: ')
+                username = input('Username: ')
             while not password:
                 password = getpass.getpass('Password: ')
 
@@ -164,8 +164,7 @@
             # send the info to the server and report the result
             code, result = self.post_to_server(self.build_post_data('submit'),
                 auth)
-            self.announce('Server response (%s): %s' % (code, result),
-                          logging.INFO)
+            logger.info('Server response (%s): %s', code, result)
 
             # possibly save the login
             if code == 200:
@@ -174,14 +173,13 @@
                     # so the upload command can reuse it
                     self.distribution.password = password
                 else:
-                    self.announce(('I can store your PyPI login so future '
-                                   'submissions will be faster.'),
-                                   logging.INFO)
-                    self.announce('(the login will be stored in %s)' % \
-                                  get_pypirc_path(), logging.INFO)
+                    logger.info(
+                        'I can store your PyPI login so future submissions '
+                        'will be faster.\n(the login will be stored in %s)',
+                        get_pypirc_path())
                     choice = 'X'
                     while choice.lower() not in 'yn':
-                        choice = raw_input('Save your login (y/N)?')
+                        choice = input('Save your login (y/N)?')
                         if not choice:
                             choice = 'n'
                     if choice.lower() == 'y':
@@ -192,7 +190,7 @@
             data['name'] = data['password'] = data['email'] = ''
             data['confirm'] = None
             while not data['name']:
-                data['name'] = raw_input('Username: ')
+                data['name'] = input('Username: ')
             while data['password'] != data['confirm']:
                 while not data['password']:
                     data['password'] = getpass.getpass('Password: ')
@@ -201,9 +199,9 @@
                 if data['password'] != data['confirm']:
                     data['password'] = ''
                     data['confirm'] = None
-                    print "Password and confirm don't match!"
+                    print("Password and confirm don't match!")
             while not data['email']:
-                data['email'] = raw_input('   EMail: ')
+                data['email'] = input('   EMail: ')
             code, result = self.post_to_server(data)
             if code != 200:
                 logger.info('server response (%s): %s', code, result)
@@ -214,14 +212,14 @@
             data = {':action': 'password_reset'}
             data['email'] = ''
             while not data['email']:
-                data['email'] = raw_input('Your email address: ')
+                data['email'] = input('Your email address: ')
             code, result = self.post_to_server(data)
             logger.info('server response (%s): %s', code, result)
 
     def build_post_data(self, action):
         # figure the data to send - the metadata plus some additional
         # information used by the package server
-        data = metadata_to_dict(self.distribution.metadata)
+        data = self.distribution.metadata.todict()
         data[':action'] = action
         return data
 
@@ -230,33 +228,13 @@
         ''' Post a query to the server, and return a string response.
         '''
         if 'name' in data:
-            self.announce('Registering %s to %s' % (data['name'],
-                                                   self.repository),
-                                                   logging.INFO)
+            logger.info('Registering %s to %s', data['name'], self.repository)
         # Build up the MIME payload for the urllib2 POST data
-        boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
-        sep_boundary = '\n--' + boundary
-        end_boundary = sep_boundary + '--'
-        body = StringIO.StringIO()
-        for key, value in data.iteritems():
-            # handle multiple entries for the same name
-            if not isinstance(value, (tuple, list)):
-                value = [value]
-
-            for value in value:
-                body.write(sep_boundary)
-                body.write('\nContent-Disposition: form-data; name="%s"'%key)
-                body.write("\n\n")
-                body.write(value)
-                if value and value[-1] == '\r':
-                    body.write('\n')  # write an extra newline (lurve Macs)
-        body.write(end_boundary)
-        body.write("\n")
-        body = body.getvalue()
+        content_type, body = encode_multipart(data.items(), [])
 
         # build the Request
         headers = {
-            'Content-type': 'multipart/form-data; boundary=%s; charset=utf-8'%boundary,
+            'Content-type': content_type,
             'Content-length': str(len(body))
         }
         req = urllib2.Request(self.repository, body, headers)
@@ -268,18 +246,19 @@
         data = ''
         try:
             result = opener.open(req)
-        except urllib2.HTTPError, e:
+        except urllib2.HTTPError:
+            e = sys.exc_info()[1]
             if self.show_response:
                 data = e.fp.read()
             result = e.code, e.msg
-        except urllib2.URLError, e:
-            result = 500, str(e)
+        except urllib2.URLError:
+            result = 500, str(sys.exc_info()[1])
         else:
             if self.show_response:
                 data = result.read()
             result = 200, 'OK'
         if self.show_response:
             dashes = '-' * 75
-            self.announce('%s%s%s' % (dashes, data, dashes))
+            logger.info('%s%s%s', dashes, data, dashes)
 
         return result
diff --git a/distutils2/command/sdist.py b/distutils2/command/sdist.py
--- a/distutils2/command/sdist.py
+++ b/distutils2/command/sdist.py
@@ -1,34 +1,27 @@
-"""distutils.command.sdist
+"""Create a source distribution."""
 
-Implements the Distutils 'sdist' command (create a source distribution)."""
 import os
+import re
 import sys
+from StringIO import StringIO
 from shutil import rmtree
-import re
-from StringIO import StringIO
 
-try:
-    from shutil import get_archive_formats
-except ImportError:
-    from distutils2._backport.shutil import get_archive_formats
-
+from distutils2 import logger
+from distutils2.util import resolve_name, get_archive_formats
+from distutils2.errors import (PackagingPlatformError, PackagingOptionError,
+                              PackagingModuleError, PackagingFileError)
 from distutils2.command import get_command_names
 from distutils2.command.cmd import Command
-from distutils2.errors import (DistutilsPlatformError, DistutilsOptionError,
-                               DistutilsModuleError, DistutilsFileError)
 from distutils2.manifest import Manifest
-from distutils2 import logger
-from distutils2.util import resolve_name
+
 
 def show_formats():
     """Print all possible values for the 'formats' option (used by
     the "--help-formats" command-line option).
     """
     from distutils2.fancy_getopt import FancyGetopt
-    formats = []
-    for name, desc in get_archive_formats():
-        formats.append(("formats=" + name, None, desc))
-    formats.sort()
+    formats = sorted(('formats=' + name, None, desc)
+                     for name, desc in get_archive_formats())
     FancyGetopt(formats).print_help(
         "List of available source distribution formats:")
 
@@ -36,6 +29,7 @@
 _COLLAPSE_PATTERN = re.compile('\\\w\n', re.M)
 _COMMENTED_LINE = re.compile('^#.*\n$|^\w*\n$', re.M)
 
+
 class sdist(Command):
 
     description = "create a source distribution (tarball, zip file, etc.)"
@@ -84,26 +78,24 @@
         ]
 
     negative_opt = {'no-defaults': 'use-defaults',
-                    'no-prune': 'prune' }
+                    'no-prune': 'prune'}
 
     default_format = {'posix': 'gztar',
-                      'nt': 'zip' }
-
+                      'nt': 'zip'}
 
     def initialize_options(self):
         self.manifest = None
-
         # 'use_defaults': if true, we will include the default file set
         # in the manifest
-        self.use_defaults = 1
-        self.prune = 1
-        self.manifest_only = 0
+        self.use_defaults = True
+        self.prune = True
+        self.manifest_only = False
         self.formats = None
-        self.keep_temp = 0
+        self.keep_temp = False
         self.dist_dir = None
 
         self.archive_files = None
-        self.metadata_check = 1
+        self.metadata_check = True
         self.owner = None
         self.group = None
         self.filelist = None
@@ -125,14 +117,13 @@
             try:
                 self.formats = [self.default_format[os.name]]
             except KeyError:
-                raise DistutilsPlatformError, \
-                      "don't know how to create source distributions " + \
-                      "on platform %s" % os.name
+                raise PackagingPlatformError("don't know how to create source "
+                       "distributions on platform %s" % os.name)
 
         bad_format = self._check_archive_formats(self.formats)
         if bad_format:
-            raise DistutilsOptionError, \
-                  "unknown archive format '%s'" % bad_format
+            raise PackagingOptionError("unknown archive format '%s'" \
+                        % bad_format)
 
         if self.dist_dir is None:
             self.dist_dir = "dist"
@@ -143,7 +134,7 @@
         if self.manifest_builders is None:
             self.manifest_builders = []
         else:
-            if isinstance(self.manifest_builders, str):
+            if isinstance(self.manifest_builders, basestring):
                 self.manifest_builders = self.manifest_builders.split(',')
             builders = []
             for builder in self.manifest_builders:
@@ -152,14 +143,13 @@
                     continue
                 try:
                     builder = resolve_name(builder)
-                except ImportError, e:
-                    raise DistutilsModuleError(e)
+                except ImportError:
+                    raise PackagingModuleError(sys.exc_info()[1])
 
                 builders.append(builder)
 
             self.manifest_builders = builders
 
-
     def run(self):
         # 'filelist' contains the list of files that will make up the
         # manifest
@@ -191,7 +181,8 @@
         """
         template_exists = len(self.distribution.extra_files) > 0
         if not template_exists:
-            self.warn('Using default file list')
+            logger.warning('%s: using default file list',
+                           self.get_command_name())
         self.filelist.findall()
 
         if self.use_defaults:
@@ -210,20 +201,24 @@
         self.filelist.write(self.manifest)
 
     def add_defaults(self):
-        """Add all the default files to self.filelist:
-          - all pure Python modules mentioned in setup script
-          - all files pointed by package_data (build_py)
-          - all files defined in data_files.
-          - all files defined as scripts.
-          - all C sources listed as part of extensions or C libraries
-            in the setup script (doesn't catch C headers!)
-        Warns if (README or README.txt) or setup.py are missing; everything
-        else is optional.
+        """Add all default files to self.filelist.
+
+        In addition to the setup.cfg file, this will include all files returned
+        by the get_source_files of every registered command.  This will find
+        Python modules and packages, data files listed in package_data_,
+        data_files and extra_files, scripts, C sources of extension modules or
+        C libraries (headers are missing).
         """
+        if os.path.exists('setup.cfg'):
+            self.filelist.append('setup.cfg')
+        else:
+            logger.warning("%s: standard 'setup.cfg' file not found",
+                           self.get_command_name())
+
         for cmd_name in get_command_names():
             try:
                 cmd_obj = self.get_finalized_command(cmd_name)
-            except DistutilsOptionError:
+            except PackagingOptionError:
                 pass
             else:
                 self.filelist.extend(cmd_obj.get_source_files())
@@ -252,8 +247,7 @@
         vcs_dirs = ['RCS', 'CVS', r'\.svn', r'\.hg', r'\.git', r'\.bzr',
                     '_darcs']
         vcs_ptrn = r'(^|%s)(%s)(%s).*' % (seps, '|'.join(vcs_dirs), seps)
-        self.filelist.exclude_pattern(vcs_ptrn, is_regex=1)
-
+        self.filelist.exclude_pattern(vcs_ptrn, is_regex=True)
 
     def make_release_tree(self, base_dir, files):
         """Create the directory tree that will become the source
@@ -285,18 +279,19 @@
             msg = "copying files to %s..." % base_dir
 
         if not files:
-            logger.warn("no files to distribute -- empty manifest?")
+            logger.warning("no files to distribute -- empty manifest?")
         else:
             logger.info(msg)
 
         for file in self.distribution.metadata.requires_files:
             if file not in files:
-                msg = "'%s' must be included explicitly in 'extra_files'" % file
-                raise DistutilsFileError(msg)
+                msg = "'%s' must be included explicitly in 'extra_files'" \
+                        % file
+                raise PackagingFileError(msg)
 
         for file in files:
             if not os.path.isfile(file):
-                logger.warn("'%s' not a regular file -- skipping", file)
+                logger.warning("'%s' not a regular file -- skipping", file)
             else:
                 dest = os.path.join(base_dir, file)
                 self.copy_file(file, dest, link=link)
@@ -342,12 +337,12 @@
         """
         return self.archive_files
 
-    def create_tree(self, base_dir, files, mode=0777, verbose=1, dry_run=0):
-        need_dir = {}
+    def create_tree(self, base_dir, files, mode=0o777, verbose=1,
+                    dry_run=False):
+        need_dir = set()
         for file in files:
-            need_dir[os.path.join(base_dir, os.path.dirname(file))] = 1
-        need_dirs = sorted(need_dir)
+            need_dir.add(os.path.join(base_dir, os.path.dirname(file)))
 
         # Now create them
-        for dir in need_dirs:
+        for dir in sorted(need_dir):
             self.mkpath(dir, mode, verbose=verbose, dry_run=dry_run)
diff --git a/distutils2/command/test.py b/distutils2/command/test.py
--- a/distutils2/command/test.py
+++ b/distutils2/command/test.py
@@ -1,20 +1,20 @@
+"""Run the project's test suite."""
+
 import os
 import sys
+import logging
 import unittest
 
+from distutils2 import logger
 from distutils2.command.cmd import Command
-from distutils2.errors import DistutilsOptionError
+from distutils2.database import get_distribution
+from distutils2.errors import PackagingOptionError
 from distutils2.util import resolve_name
 
-try:
-    from pkgutil import get_distribution
-except ImportError:
-    from distutils2._backport.pkgutil import get_distribution
-
 
 class test(Command):
 
-    description = "run the distribution's test suite"
+    description = "run the project's test suite"
 
     user_options = [
         ('suite=', 's',
@@ -34,11 +34,11 @@
         self.build_lib = self.get_finalized_command("build").build_lib
         for requirement in self.tests_require:
             if get_distribution(requirement) is None:
-                self.announce("test dependency %s is not installed, "
-                              "tests may fail" % requirement)
+                logger.warning("test dependency %s is not installed, "
+                               "tests may fail", requirement)
         if (not self.suite and not self.runner and
             self.get_ut_with_discovery() is None):
-            raise DistutilsOptionError(
+            raise PackagingOptionError(
                 "no test discovery available, please give a 'suite' or "
                 "'runner' option or install unittest2")
 
@@ -60,16 +60,22 @@
             self.run_command('build')
             sys.path.insert(0, build.build_lib)
 
+            # Temporary kludge until we remove the verbose arguments and use
+            # logging everywhere
+            logger = logging.getLogger('distutils2')
+            verbose = logger.getEffectiveLevel() >= logging.DEBUG
+            verbosity = verbose + 1
+
             # run the tests
             if self.runner:
                 resolve_name(self.runner)()
             elif self.suite:
-                runner = unittest.TextTestRunner(verbosity=self.verbose + 1)
+                runner = unittest.TextTestRunner(verbosity=verbosity)
                 runner.run(resolve_name(self.suite)())
             elif self.get_ut_with_discovery():
                 ut = self.get_ut_with_discovery()
                 test_suite = ut.TestLoader().discover(os.curdir)
-                runner = ut.TextTestRunner(verbosity=self.verbose + 1)
+                runner = ut.TextTestRunner(verbosity=verbosity)
                 runner.run(test_suite)
         finally:
             sys.path[:] = prev_syspath
diff --git a/distutils2/command/upload.py b/distutils2/command/upload.py
--- a/distutils2/command/upload.py
+++ b/distutils2/command/upload.py
@@ -1,27 +1,21 @@
-"""distutils.command.upload
+"""Upload a distribution to a project index."""
 
-Implements the Distutils 'upload' subcommand (upload package to PyPI)."""
-import os
+import os, sys
 import socket
+import logging
 import platform
-import logging
-from urllib2 import urlopen, Request, HTTPError
+import urlparse
+from io import BytesIO
 from base64 import standard_b64encode
-import urlparse
-try:
-    from cStringIO import StringIO
-except ImportError:
-    from StringIO import StringIO
-try:
-    from hashlib import md5
-except ImportError:
-    from distutils2._backport.hashlib import md5
+from hashlib import md5
+from urllib2 import HTTPError
+from urllib2 import urlopen, Request
 
-from distutils2.errors import DistutilsOptionError
-from distutils2.util import spawn
+from distutils2 import logger
+from distutils2.errors import PackagingOptionError
+from distutils2.util import (spawn, read_pypirc, DEFAULT_REPOSITORY,
+                            DEFAULT_REALM, encode_multipart)
 from distutils2.command.cmd import Command
-from distutils2.metadata import metadata_to_dict
-from distutils2.util import read_pypirc, DEFAULT_REPOSITORY, DEFAULT_REALM
 
 
 class upload(Command):
@@ -46,10 +40,10 @@
     def initialize_options(self):
         self.repository = None
         self.realm = None
-        self.show_response = 0
+        self.show_response = False
         self.username = ''
         self.password = ''
-        self.show_response = 0
+        self.show_response = False
         self.sign = False
         self.identity = None
         self.upload_docs = False
@@ -60,9 +54,8 @@
         if self.realm is None:
             self.realm = DEFAULT_REALM
         if self.identity and not self.sign:
-            raise DistutilsOptionError(
-                "Must use --sign for --identity to have meaning"
-            )
+            raise PackagingOptionError(
+                "Must use --sign for --identity to have meaning")
         config = read_pypirc(self.repository, self.realm)
         if config != {}:
             self.username = config['username']
@@ -77,7 +70,8 @@
 
     def run(self):
         if not self.distribution.dist_files:
-            raise DistutilsOptionError("No dist file created in earlier command")
+            raise PackagingOptionError(
+                "No dist file created in earlier command")
         for command, pyversion, filename in self.distribution.dist_files:
             self.upload_file(command, pyversion, filename)
         if self.upload_docs:
@@ -90,13 +84,13 @@
     # XXX to be refactored with register.post_to_server
     def upload_file(self, command, pyversion, filename):
         # Makes sure the repository URL is compliant
-        schema, netloc, url, params, query, fragments = \
+        scheme, netloc, url, params, query, fragments = \
             urlparse.urlparse(self.repository)
         if params or query or fragments:
             raise AssertionError("Incompatible url %s" % self.repository)
 
-        if schema not in ('http', 'https'):
-            raise AssertionError("unsupported schema " + schema)
+        if scheme not in ('http', 'https'):
+            raise AssertionError("unsupported scheme " + scheme)
 
         # Sign if requested
         if self.sign:
@@ -108,99 +102,69 @@
 
         # Fill in the data - send all the metadata in case we need to
         # register a new release
-        content = open(filename,'rb').read()
+        with open(filename, 'rb') as f:
+            content = f.read()
 
-        data = metadata_to_dict(self.distribution.metadata)
+        data = self.distribution.metadata.todict()
 
         # extra upload infos
         data[':action'] = 'file_upload'
         data['protcol_version'] = '1'
-        data['content'] = [os.path.basename(filename), content]
+        data['content'] = (os.path.basename(filename), content)
         data['filetype'] = command
         data['pyversion'] = pyversion
         data['md5_digest'] = md5(content).hexdigest()
 
-        comment = ''
         if command == 'bdist_dumb':
-            comment = 'built for %s' % platform.platform(terse=1)
-        data['comment'] = comment
+            data['comment'] = 'built for %s' % platform.platform(terse=True)
 
         if self.sign:
-            data['gpg_signature'] = [(os.path.basename(filename) + ".asc",
-                                      open(filename+".asc").read())]
+            with open(filename + '.asc') as fp:
+                sig = fp.read()
+            data['gpg_signature'] = [
+                (os.path.basename(filename) + ".asc", sig)]
 
         # set up the authentication
-        auth = "Basic " + standard_b64encode(self.username + ":" +
-                                             self.password)
+        # The exact encoding of the authentication string is debated.
+        # Anyway PyPI only accepts ascii for both username or password.
+        user_pass = (self.username + ":" + self.password).encode('ascii')
+        auth = b"Basic " + standard_b64encode(user_pass)
 
         # Build up the MIME payload for the POST data
-        boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
-        sep_boundary = '\n--' + boundary
-        end_boundary = sep_boundary + '--'
-        body = StringIO()
-        file_fields = ('content', 'gpg_signature')
+        files = []
+        for key in ('content', 'gpg_signature'):
+            if key in data:
+                filename_, value = data.pop(key)
+                files.append((key, filename_, value))
 
-        for key, values in data.iteritems():
-            # handle multiple entries for the same name
-            if not isinstance(values, (tuple, list)):
-                values = [values]
+        content_type, body = encode_multipart(data.items(), files)
 
-            content_dispo = 'Content-Disposition: form-data; name="%s"' % key
-
-            if key in file_fields:
-                filename_, content = values
-                filename_ = ';filename="%s"' % filename_
-                body.write(sep_boundary)
-                body.write("\n")
-                body.write(content_dispo)
-                body.write(filename_)
-                body.write("\n\n")
-                body.write(content)
-            else:
-                for value in values:
-                    body.write(sep_boundary)
-                    body.write("\n")
-                    body.write(content_dispo)
-                    body.write("\n\n")
-                    body.write(value)
-                    if value and value[-1] == '\r':
-                        # write an extra newline (lurve Macs)
-                        body.write('\n')
-
-        body.write(end_boundary)
-        body.write("\n")
-        body = body.getvalue()
-
-        self.announce("Submitting %s to %s" % (filename, self.repository),
-                      logging.INFO)
+        logger.info("Submitting %s to %s", filename, self.repository)
 
         # build the Request
-        headers = {'Content-type':
-                        'multipart/form-data; boundary=%s' % boundary,
+        headers = {'Content-type': content_type,
                    'Content-length': str(len(body)),
                    'Authorization': auth}
 
-        request = Request(self.repository, data=body,
-                          headers=headers)
+        request = Request(self.repository, body, headers)
         # send the data
         try:
             result = urlopen(request)
             status = result.code
             reason = result.msg
-        except socket.error, e:
-            self.announce(str(e), logging.ERROR)
+        except socket.error:
+            logger.error(sys.exc_info()[1])
             return
-        except HTTPError, e:
+        except HTTPError:
+            e = sys.exc_info()[1]
             status = e.code
             reason = e.msg
 
         if status == 200:
-            self.announce('Server response (%s): %s' % (status, reason),
-                          logging.INFO)
+            logger.info('Server response (%s): %s', status, reason)
         else:
-            self.announce('Upload failed (%s): %s' % (status, reason),
-                          logging.ERROR)
+            logger.error('Upload failed (%s): %s', status, reason)
 
-        if self.show_response:
-            msg = '\n'.join(('-' * 75, result.read(), '-' * 75))
-            self.announce(msg, logging.INFO)
+        if self.show_response and logger.isEnabledFor(logging.INFO):
+            sep = '-' * 75
+            logger.info('%s\n%s\n%s', sep, result.read().decode(), sep)
diff --git a/distutils2/command/upload_docs.py b/distutils2/command/upload_docs.py
--- a/distutils2/command/upload_docs.py
+++ b/distutils2/command/upload_docs.py
@@ -1,65 +1,38 @@
-import os
+"""Upload HTML documentation to a project index."""
+
+import os, sys
 import base64
-import httplib
 import socket
-import urlparse
 import zipfile
 import logging
-try:
-    from cStringIO import StringIO
-except ImportError:
-    from StringIO import StringIO
+import httplib
+import urlparse
+from io import BytesIO
 
 from distutils2 import logger
-from distutils2.command.upload import upload
+from distutils2.util import (read_pypirc, DEFAULT_REPOSITORY, DEFAULT_REALM,
+                            encode_multipart)
+from distutils2.errors import PackagingFileError
 from distutils2.command.cmd import Command
-from distutils2.errors import DistutilsFileError
-from distutils2.util import read_pypirc, DEFAULT_REPOSITORY, DEFAULT_REALM
+
 
 def zip_dir(directory):
-    """Compresses recursively contents of directory into a StringIO object"""
-    destination = StringIO()
-    zip_file = zipfile.ZipFile(destination, "w")
-    for root, dirs, files in os.walk(directory):
-        for name in files:
-            full = os.path.join(root, name)
-            relative = root[len(directory):].lstrip(os.path.sep)
-            dest = os.path.join(relative, name)
-            zip_file.write(full, dest)
-    zip_file.close()
+    """Compresses recursively contents of directory into a BytesIO object"""
+    destination = BytesIO()
+    with zipfile.ZipFile(destination, "w") as zip_file:
+        for root, dirs, files in os.walk(directory):
+            for name in files:
+                full = os.path.join(root, name)
+                relative = root[len(directory):].lstrip(os.path.sep)
+                dest = os.path.join(relative, name)
+                zip_file.write(full, dest)
     return destination
 
-# grabbed from
-#    http://code.activestate.com/recipes/146306-http-client-to-post-using-multipartform-data/
-def encode_multipart(fields, files, boundary=None):
-    """
-    fields is a sequence of (name, value) elements for regular form fields.
-    files is a sequence of (name, filename, value) elements for data to be uploaded as files
-    Return (content_type, body) ready for httplib.HTTP instance
-    """
-    if boundary is None:
-        boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
-    l = []
-    for (key, value) in fields:
-        l.extend([
-            '--' + boundary,
-            'Content-Disposition: form-data; name="%s"' % key,
-            '',
-            value])
-    for (key, filename, value) in files:
-        l.extend([
-            '--' + boundary,
-            'Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename),
-            '',
-            value])
-    l.append('--' + boundary + '--')
-    l.append('')
-    body =  '\r\n'.join(l)
-    content_type = 'multipart/form-data; boundary=%s' % boundary
-    return content_type, body
 
 class upload_docs(Command):
 
+    description = "upload HTML documentation to PyPI"
+
     user_options = [
         ('repository=', 'r',
          "repository URL [default: %s]" % DEFAULT_REPOSITORY),
@@ -72,7 +45,7 @@
     def initialize_options(self):
         self.repository = None
         self.realm = None
-        self.show_response = 0
+        self.show_response = False
         self.upload_dir = None
         self.username = ''
         self.password = ''
@@ -87,7 +60,7 @@
             self.upload_dir = os.path.join(build.build_base, "docs")
             if not os.path.isdir(self.upload_dir):
                 self.upload_dir = os.path.join(build.build_base, "doc")
-        self.announce('Using upload directory %s' % self.upload_dir)
+        logger.info('Using upload directory %s', self.upload_dir)
         self.verify_upload_dir(self.upload_dir)
         config = read_pypirc(self.repository, self.realm)
         if config != {}:
@@ -101,30 +74,31 @@
         index_location = os.path.join(upload_dir, "index.html")
         if not os.path.exists(index_location):
             mesg = "No 'index.html found in docs directory (%s)"
-            raise DistutilsFileError(mesg % upload_dir)
+            raise PackagingFileError(mesg % upload_dir)
 
     def run(self):
         name = self.distribution.metadata['Name']
         version = self.distribution.metadata['Version']
         zip_file = zip_dir(self.upload_dir)
 
-        fields = [(':action', 'doc_upload'), ('name', name), ('version', version)]
+        fields = [(':action', 'doc_upload'),
+                  ('name', name), ('version', version)]
         files = [('content', name, zip_file.getvalue())]
         content_type, body = encode_multipart(fields, files)
 
         credentials = self.username + ':' + self.password
-        auth = "Basic " + base64.encodestring(credentials).strip()
+        auth = b"Basic " + base64.encodebytes(credentials.encode()).strip()
 
-        self.announce("Submitting documentation to %s" % (self.repository))
+        logger.info("Submitting documentation to %s", self.repository)
 
-        schema, netloc, url, params, query, fragments = \
-            urlparse.urlparse(self.repository)
-        if schema == "http":
+        scheme, netloc, url, params, query, fragments = urlparse.urlparse(
+            self.repository)
+        if scheme == "http":
             conn = httplib.HTTPConnection(netloc)
-        elif schema == "https":
+        elif scheme == "https":
             conn = httplib.HTTPSConnection(netloc)
         else:
-            raise AssertionError("unsupported schema "+schema)
+            raise AssertionError("unsupported scheme %r" % scheme)
 
         try:
             conn.connect()
@@ -134,23 +108,23 @@
             conn.putheader('Authorization', auth)
             conn.endheaders()
             conn.send(body)
-        except socket.error, e:
-            self.announce(str(e), logging.ERROR)
+
+        except socket.error:
+            logger.error(sys.exc_info()[1])
             return
 
         r = conn.getresponse()
 
         if r.status == 200:
-            self.announce('Server response (%s): %s' % (r.status, r.reason))
+            logger.info('Server response (%s): %s', r.status, r.reason)
         elif r.status == 301:
             location = r.getheader('Location')
             if location is None:
                 location = 'http://packages.python.org/%s/' % name
-            self.announce('Upload successful. Visit %s' % location)
+            logger.info('Upload successful. Visit %s', location)
         else:
-            self.announce('Upload failed (%s): %s' % (r.status, r.reason),
-                          logging.ERROR)
+            logger.error('Upload failed (%s): %s', r.status, r.reason)
 
-        if self.show_response:
-            msg = '\n'.join(('-' * 75, r.read(), '-' * 75))
-            self.announce(msg)
+        if self.show_response and logger.isEnabledFor(logging.INFO):
+            sep = '-' * 75
+            logger.info('%s\n%s\n%s', sep, r.read().decode('utf-8'), sep)
diff --git a/distutils2/command/wininst-10.0-amd64.exe b/distutils2/command/wininst-10.0-amd64.exe
new file mode 100644
index 0000000000000000000000000000000000000000..11f98cd2adf1075b7ff7be7f02ebc8e743bb6b9e
GIT binary patch
literal 222208
zc%1CLd3Y36);L_fkp>d0SsEg1kVXT|5(sKSK)axtR6{oe*`mS_jYb?m8R!-r5rdUz
znrkcbj<dY8Iy1i+9mi2;-WdqEr4z`;P6PtD1aZb{8Z?3?VXfae=T>(TP-ouneZN1x
z=lOWZ?W$XMIrp4%&vtL!3f#3>un2-+g+E;vgi3+`^9cXOKa(I_H+=hb!ryxC8BuBS
z?-{XR`GadSR<C*Zfi?H6$|%0)p@$w0X54#!#+uMW84o^`A<vzkvFhRb?jN6)*2`ry
z at tc&fZ~UWV`pLxKBbmoeehj~x9I=y8`hEZ8XYhM^SoGwl^t<!qC-i&Z<SD8%<D^XG
zw3Ex}x0#-Aa(qO;cRX0U9NYb-AryE8;l8JBLbZEiAd%N9j1+pCdkMl!vmgvIQQqzo
zkT^JMC<m|Mu?-WU^H*rG5HiL8W5Jw_iAsr|Ywx>V3a5u#gctFm$|AJ(gWne|!sfx(
z!d-R0Ss3!I#JTEUky-HAzWMR^;QfyV;n(jqbAWK{*6w98pq24!?z<;=k02~Lz}plK
z!tX3|w{jl%Kb{v8%9daT;3OS>hghyIS2cb$FGypAvC^O>UsKLAe$Co7#c)kH0o(}v
z;kV%0a{meq|Np=4|CI8E;Goi6A?Oshm`ZaeY)5*Da&?7C(W9Y%o~zltd$$r^;<78@
zl`e-84!Y78E9&VCAL~%qF@=4hlphq!eh8IH^8~SM6I at Ue3fraqbUpqyE9F(ekiz!X
zf`oBSzQZgqP3_P_6S5CNrtTaAIptNM0ZO?Z?4v}Svlg0#h+^}zTK!18m%<Kj!}+Ek
z at wDx9ghp)JiZ{;7^UOk`!u3!AN^i4Kv0BR#MXwRdSLwR0uqCc6g{^euC at kpmRANJl
zx+7y*%{60^7Dx+WTm=gIh3iEq=4G(}Yf;z*7NctAXSPFHCCZwj-sj2^yx9%j>?(!r
ztCL-srSJ%v%Fvxd5iZuMzyQVaUlOQ&AxrJBg!=ngjgP$tRkS}{(RCQ|AL8rOj)Gt>
zR<Aq9LaF#nrTloXSYb!D;e^tg0CBUsc1Iv|=@Wi4sHF4v1<8Ixqp_8tfEZ-~BBqWb
zrU`L*WLpYdXII4z5%G@)Dc3@|;?@^jKSlCyeb%)Ze*F>I<<XsYLfig`-{qluC9(h#
zB%F`>-0Lkr6SC{h8E_YW38BqIXtNJ`Ba&6-Sed{}DooRzgYjCutcRS?yI8gc$rN#x
z&o>LP0=$L>GK}F$k$Gl??a`g>bFuy&7 at +Pvj@RXFM)ho7eLPn0Llm#|N0zt>eC%#u
z(G{6Kwl>ShPD)FqCCh3$X}(z5cp4EXvGc^mF-h&Pi{<Y at 7H}nuHA9X}FVw{E3qmB{
zg!MAsL at o#e;#ryN4ML911HBrBXD^P-Z-u8h*nE~YX(4j{TQ1b5K*Z~iRVM+QZNTgC
z;Z$ck3RmsH#e$Gm6HHI=^4m~AW>wor9UsX)PDM4gikeB5dh+U0h at _v*K{EZqh2ug_
zyW0T>NQc2MtMLM}9rYJ;z_nZ$6^$ld$LF?V;UeOHX_2&8iM;A6LPTyn{h|p6Vf+4g
zi=brhP{QTJ6YS5Z_I<3`%T7p49&*9!zHdmImz|g0Eq+$5gcrCTmDJM%q>bx`pDLJb
z>!F1GE at gV8e}*4WQxr at A-rE99>&-rc+~Fzl=B*t5r5O1o<SE5x70WrLc*B_K5$jF<
z;#R-q+{W7qW}D2R1_>`L)=-uB?wky at dc0CxtyqAhva3LRcjholJ)}b{`+e{;$Z|l5
zq~-x6GTbg2qCj@>4#m=_L>87R5!pV>$Lf9V{aAVRCR2sA7s$G at s?e8;+MvUvjyzF%
z_BAT2H!AH1O4s+%m*BVxgHC*grOv)4ZnY^eXG_BQz<_~L-PtPu+)!K(?WdJu%gYre
zyA(yu5rVh-p+A<Zum!FH-Uqbbe!w4*bRX-f<z%1)6wBHGzdn6ufbH=`PgwmHz?)Ca
z6+$}#I4E8ly3&;ONQafKLb{uB0cTAYz}b4}yZylQ()FYDC0MQ~SSW6tnJTk6=}3dD
z5 at ch@xemt&0wTKsb22myTLL~C0|mX%r5$SY$8J|+wM?L6hQjK#zh6S>1#=IiSfKn&
z at OqhnaDWQ(@Gn7_NP2Wz51d>2A<UO3Uynj<PhPzk`8%>FP{t3~c@&r+mU0EB?E;q)
zu$=L!jruG$_0$|DpR#9H`B)<o0#J^~^67M+eNftDbtrmug*@;IQ0)ss1;RUsqX0_z
ziVr9jK-byVyzVICVv{^tpSmPCXzGOEfMh8mqB at rov2@CkpsjSugisG?TGHzgw}Ij+
z?KsSq*bf0lu02=;XMvKvTU$fg?H4W$r^&`0I9sG;(sxMId}k@@&Dgt7g5e0iI{&4)
zh5~}CPzhCNwZe{q3JtDP_voAKWevfHRNef at gNj~NdVWc0VQEg*`o*O=*&9Zd<~$Tk
zE6rIGQs7ywB`uy;QfEm6&aG0^8naq=B|ZT~bCy(TCphc1KB^#0?G>^^VbF+{%M}*n
z$gH at zqBq?GsYB1AcJ$Q33<p)2W9UZDd;|{xV`<MS7P1j++8UK>^;!E&f;wu~D$p59
z*tQa%L$$kMz#uG^Qt_%#iW0Fk0A{(&U2L?s4Gl|e8*fNq9om(>Cb&$Spl|@Pl<>5X
zcpaV#ayrETXSbid?+f2;_k~wDeBrf(JkaW203CttM*uJTM$FI at cIE7AU<QEvZa*Ni
z1|@Q*p5353SNOo-sArmDY0z$`o;wggYj#!K4RYH=Rk9n9!Ex4tw#xO9LDCB~^%GBl
zm;{|&hv0b-SqhpGFpGC&Elb))s7?yFwDgZQq-B{4{RBmwCf$yhV#h+$l}Oq+z=`gx
zQ_O^=>tXE0tD!=~d1($lxNV6=i0wrBMVtrcpwa`=;5S%0Y`buqg*0*oJo_s>+od~g
zPyy%S56H5ab_mJ{!9Swjm^S7nMCt;Zv!WJy(1aRfuwJ96bq at 7nuQi__-d9rJ1<+bN
zA1*$>5$=m?K>I3|s_X`tS*wYsbmtSdVL!qCbPMB{NZ>yFkVS|OhK7FiFg5gf01Xa8
zV(@N at fcDX|91SpEra#8#OA((hh_8elwh*<B=L%_^Dl_5Hnwii#Zx9;qFBQ-<SS~<P
zNSBXNT0m)$03fqtx^v+yq}^jf0GPgHG^AMoG|-j0^W(b!x9?(OfW$(7B(T{Z at m3(s
zJ(#l`s_a9wk`{-IN0CS228Qb;fu4!Es|_Z3_AW$72(?+F%>q)Y{zzK=vuGEj{pPP`
zuqI?yV^sMI at zrCg(9vzsQEVC6D}Gl2Qnd(jvwnjRn{<a!suj=~%T1J0*un~Yy7@&i
zDyYP3SYlw85}UC^L5}hG0esv+@)eXBNSVP#IVe+Tlo^R--ZNzIax65G3dumnLh7%g
zv%kZBDEyL9_|dCcRE$DlEc6r<LRMG}*n3ez^#qd)?N%#diz8&e7su;|u`?5>q89;G
zdO;SnlFw_hw3(}juTuPI at 4!?TcBjRt0V1gf_3GdNbl&UELYOeI;wv00MO{l71#VS{
zK<TrQiC<ZPZARWO*!1U*a5mj<CN at QOT*_q-h#kcjnVk+oI}n+j;S0}h4n#okM4Y?)
z##DWzkhlVc%Q)THIupSL5O6rl5oK9as%0j1{{yJS_Uq2kD at cSYH89{+H^8+%>XGFZ
zA*nCcyV7Zb6z~c12A?1&U5N?8?X;s{kcuk^U8 at nC2q`M`5D??K^X{3+Ozq)~0v8{*
z$s~xx^4~zV%+hZ8E>0HPxd*77j at jJ4h50{pCiej{{5Tm%2-HQPU9fvDNXXW~k=Hyn
z)8pg(F{0#ll-P|rDRe{o+K>{g5fyO4e#vgwWCaBkt&l}j?`OGn^}-A+7<tj4(pN!&
zj9o+qn7Ux*J`VQ&$)#N1bhT$u^F*AZh(bqo=K^de;=DZDZ0I1}De<g>Jj;(x#(19f
zdZH9$4dz+TCQ3m?JI}f&QA#7T59mIf@^ceKTXg3KJnOnd7C1tUkOhJoZBVf5#j-kb
z$lAoRci<v`7k{S<c=RegIwO|-j&eQ`%YH@|XAHp~N&7v>J^cvRZNa;tr?Od`B at ZJ%
z(DgphA-9!S1k4)u`w__WUqRN%2T|tl0<{@EVN)!7By45?6!)_#Nk5DVqc%gm*kjEx
z)P7{tf(#rN1P=9wN0l!`ZEdT)AEmuNJnjj&kJ}7WX$ed|P~qLIBG1D4U5K;s^iK)?
zm8hj`4rKo9ol4kSgkD+1sRQ5vb|O&Rfq{l_0ND5ii4b{c7WXK_UT{52dEOs+9wB!X
z&wAP at 26zd3LE<dp*>ygnWGiH+>(1LTn+5RETl5I%?e5Gg#k{Z=1jm5R%)5DJrtUOB
zCa9m>fL$#6vB{uI1Q``+S7tJ(`MAlT?;5<w4P=UC%P9-g_cEU45X%-)7I?N^xX9@(
zmQ6E}PYQ-t=#oibt?1!rX#Y^jM%ds(g<GRUlp^f{OzOx?Yb>3_LE6a at G#6|#l-PdS
zf)Zc^u&ch%j__-TE}`F?_S!8#w}Vop05+pGVg>Yc+*_`1$nr;S{vkXHxc}*kSl^$;
zQnOINrf6&0bUkhc!#r&L5Nt?a-bd>{^s`X9KQgKq%1dmYkG%(mKW}D$kEOoPjmMi&
z`SS{=K-6cky>DX7LHofIs9Qn-nR#U?;<1qfC5cL2bX_l{vQ?*lqN296YB!Wa6YdtE
zW at J6G%Ms0LN71suq5KrswWQ9P(+kFz!J2_>*<S6~d_Y%CJhc)dBuSnO6e-zzv at NR<
zefK}w$(naB{rZ at YAwvp$>IjgGXZ`FvDl#AYBEYn_u}STrQDz|-q><T9m~|AVF at iMU
zV6}9{X)fPp7T*1e6m~P)r#q)jGYi|k#CtFpe at aEhOhX=P!ud+!m%jX-O6gAPG}0Zm
zc@{x?|2(!sQ+^mYjb2vkV at J^P{|Qo;?Zb(%dn(v=PVMg-iC^By$J)Rwd!9sO at Nmzz
zuc+l$rkcrK^cX$;Y^s?v9_UNx^j(Y!=hdxEGxA149_zs9NO8UP&voR`E8!jpjLgF~
zR8S7TYK&_;jbng6 at +@V at XjAX<^8nEwrlF?%1wBw$4{ya-3w81t<onoe-5HsN`e%u&
zfb9fvpXFmKa(ry92SYmv5(51gsKY{_;Bp|~>U1UiXa*-CDgi$OP2&7B>M?dgclrsB
z&JSi%2P89cdDa~~3kak;Z{%5X6Imei`|+$75?N4DppmtrFPw)VwOcSwGZ6%Ka4e$Z
zCZN}$A`rYyFf*WzRtR+SvAy6QH^XBy2-zdRs1~(ezuL<HSH6%$C=Icun-7@~qaZ|E
z2yM3gLz2G7e##+U)%M)bg+aX$$z+5P>%W#m?*_8Ji5y|*y`N7p3vVMwuswt&HU$TJ
z*ie)q<8F`c{O%Ou%oTHhGpDx`hog at Jc93H#p{&8n&4~gs$9GLL?zG4kx(;KHohF!x
zfhUpiwhQ~~Jp~bc$Y4?%-5oYqv^^ID00`S(@wgoZC7+#wY*~rSs)FQ at fkVe3hsvR3
zEcyY!g$Dt$BS7xzO}#2oF`iJ?5c;x{bD=GJ9!FdT6rMkpLZHO8 at aU^4$go7LU6NWe
zR;slQ7POjH0$a-m>m&}QaN3W-zS90oxlk!1&*0{F5y+kB9PKxP38PkWdj=^93=Yh_
zf|%QoPFyynqrxn*60JWOl%#b5<e;l{;Z0ny0deakw<Y1R0L)RDfr8&A^huiDhjNU`
zZV;qKvye^bM~U+WJd9f_WDGaKQ{6dX3I&o;IJ=KRUMg^AlXik+NZR(Lq-X}CDG8Qe
zfka+D*o81!?g1izI7rV5Zd#XG$+X6ikPl7%{d`9tJR?02o}IA>hnd5NdHMR}Ff$;>
z7g?Lm&SRL7LZ~=iKZyEYgO{%F6U&?+kk!x4V%dKQJfnhsgR9`r1^4Csxo&JPqM(LY
z_9yOYzXX~w_8%CS0v{snkIT>^+F+N(t at RjmH$g8_^aQB?BYB92XI+H^Tv{m<1hi~7
zTS>mb!x(k!9G=T at kpZkc16Vos3(9UmG)8RWW*AR_)1_@$^k@$}ia!QzF5#e|r%iUG
zpOsN}+TibFpS<tw<5BVay_Bqn;B;{Iqti(QQAGIMA3_rnCAIaRfyT~2KRD5FqDAOn
z9n{jQK{Xr7 at mWGLlIlkf5{Zxs$bGx7lC2r26FrJrq at hev*x5Qy3&x!j(xtS{(@bj$
z&QxNwW?Gm)AK*b8c at eomCvM@>D^p0s{7GX#8)lsN7jEq|(f^6pFrR~OU$s79RZxo_
zxs at BZD6-##>+pC5j3Stx1qy{pL6$BDG3rUg8+Zgsoz^ysLNn)s^Wf%- at 4!tcAK=PG
zwA+rsL%y29lwQ6_!F2$1z)~+&S_Ljj!V7RF&A*w{Gq<l_gEn;M%Se6_4m?WanZK}$
zurA_(qLBkTC$I_G_*GXG{IY6qcAI;F{Q}s%@Y5CuhlD_QqI&8ErTCa)Il6JZoucYu
z`9LVWG4Jt3llunyp&w6HsP^7PV7Dviu^$vGzC=BnyVf2|SBhs?5t;6KxU%C<IPJX8
zBDm+<mB{1Px6wy*4`h3!utO<MQQXa1KQxiRKt}VF{106BK{@}*WFD<n`P})Phs$vf
zOhllG?tF@#2Op4`=tZ9(=*p5JiW#&-i3~THlxAp;e}Ym`Lk2GJLzjrcdhH1es`6kq
zyG%iH#j;B~vK_;OdwgN9;0sT7>CV>x>BO_~0lM=qH<Nm~a61P2w5AKXZipSjS8OQZ
z;syh>2}k5^;%W8t^7sJ5!)>}X>Fn-LTqd*uYDZdxbiREn#Rhi)WtZ0wU4f#_T>Z{-
zCMjA)IWhHu80 at V(3!zf%Mia;3YTa1?_uKf40~I<8?w}*Kzw&{Sk`m~z{S>RtJ{avV
zv-)UkxFrgDWW(*~Z1`Qvvl}2Sg1<ueE5MZ%jH|<64*X?tm2NWp{<q8su{z0cf%fap
zC*gWK?|3gwmPhcRv34-+FEdb(r at aC{XJ3mHh!jVyR`doQ_y+|x7wd!K75MsJvT~%L
z7u5eAum4 at Dk2QgKT`KpTWK0yeZkuQXOwuNCS-6^(u<~z7sEjH at FQ(m3v_lMYsu}hV
znCA- at OFV7}>b0^8bdDxGMjir?qPAZ$dMF~=ZS%;WIGWu?L8u~>O?-_8S^|oE2=Htd
zK%apy3x_D$_o(iC6c}q82s8BaDs<=fCZhNrH~luw9Yy}|su!X3PvPliE(c10HHLw#
zeQ6P?L_3vqo|r}i)}7j9x{s3O6L<q0H{H2oGEQ6Fxda;D)`v?L-FXZ4jA|5x-)Q7-
zfU^+CUVv8$CZ6zmpgJgef5iKS7k!dLz#TBbaC(7#HJMPn-I8dtda at BSj?zU9#=Jz1
z<(G=N^?_If>!WkkblK9R&AFJbj at wrBHBf7;1!sZ$1V6?Y#uJkb*2W%JPevmNihx-$
z6$4>8Bu`~<ePq{Uue(upFL33!>)o<zs${9*oU-pf-PH#=z(kxLvG${D<lKK`^H8A&
z!R@%0M;B107m$3d^bq~mCF$QMITf=U6dhA9%n{3e3xI9B-~jl<^0!fies&(CltbGK
z!Pf=DeF&hDtNTiF($POzg2<eiZQ#yJ7xh{U!<!M?6^R06`BRg!<I72AiqdCo*DOYm
z?T^`{_Wwh+2-`0wGGE}C9{{J28AF**LT3CXY2#y#9GGRHp<t&$a}w<apxp-b+gFpV
zQ9CIyQD}I8lTYrUiGp~zJ3+H_L+xOE<;70T^GAn)9B+Z2eT*ie;$t0t7K4#^r(%EC
z3&^om=-;5ZnB4|?d^|~YjCX$zn;8*w<zSM9NhT&4FtI!ZWQoT{V92pHk%8{exYFB&
zV5Xt`>lF79aSIq&TdWSrT_3V5dKIow$H68m-(~DPz=-&Bc{EjE#J`wmPUb2+_YK|o
z^hCogR3Z!C=nA(%w?*SfTtB`IX|8!5B*7@#Oi5p05swQ)!|1e9l%L!Gy#95(K1{Iy
zHoU!*mcBt!?ZJ-OuI)eL8UA8WbicDxp!Kg4Ije%*{Q6jK;p7<p7q at n}3BwL!Atkx7
zq6p;8Sgu*CjnK8CJ6DZ0CycW|0n+)>GHye^XzEmIiP&0lo at Ob0r-t*!R11*PYOoIv
z$r>I&-dGGjvJMztZ^P~vuzy{Ap at thzN@9^Ku^wpK*Bdyet_I`2N?uKHwlWPH4E5EX
z(rH7>6eT?LPf#X45m<XV`Gd}WQ;?&$OYrFgus0V$+4g2-aD&o*6qGv{B9Hd&TtigP
zn>T<-VzUC|H6ie!Y!~3EdcphzE-5|-*Iji02FDE_zp?<Nr*?TwLIl*LbuPrg6ZO;_
zkOE at a%P;}6^^K>h0ifVmy-_U3;MhA?ASsdaYQ^#o;K~=(91>XnI=Be8!f0dlG;MAB
z7SQTu at cOId1jpzI7#%f)p6g-V*>eKvi|qx7v}!^<SdeU|R&)ux>BBVR|1lmToIByU
zi9gq7z(Z(Ws$^&l9;QX8_1Jv%cx1U2=zatk)4?GTMVBg{rb7PWhR$+7gL0c}GW1$j
z6`Twdc#OOez7Pj}f&GCkMfd_`r<gKNz<Q}r&s+XUXa-ci0V<!)xvFx%@tE-fWyFCd
z&Y$IwBvW$|bf(rWjWZ-BmY3eLBqf-a?KXs%X*}sgsj}j#kv5M at M9I->SgJesL53G5
z%9U<HFglJpz5{jl=ZR5FrLozjVP<P0^Cm=zb2Q{tIOFpyknWsj5n^X)zOEUEB-q`p
z=@QH<J|k8BX9BbU+hagCg}S}@ck?iUUSTHza2UAwuXf0A at 84vvNHv2z!)QW))pkPm
zTk2<zRJrM@;l^Ov=~Wn{`1O702((a;f{KPaixP{yGZy<!d%l3|3;!I_K408IVFm5Z
zAh3CdIdp@}(pDAFLe3ao;@w*)G_!vydM9^`<;8znj6sS`w!T?_7Te$88FStO)mYk>
z0gIrmr5NH7KPci&sgrQKg}?s<7?iQ>jzQQg+?;_6q_{`MbY)2}9qmZSPwtSpaXjB#
z;bR5%ZuM}Hr&pIn9<DNz1bYNvj4w(mLVq?+iS0PIIJX#>d)-Zpf?SdcdKT{F$Xrt#
zu7Bx9ZZx=#h)U+>bMA!RM45o{^wqn#>4Vav)AV^fCmDRHN%+3WnBqbZH;a|X%Y}SB
zZZltxo8L2Ga+dP-IIshM-2>5Y%fdOd at jOX@$h2NGU&ft8b`j+c#fV1XYAY>0ciHa;
zCLJxA!Z1i@=+4lMq=xg=4qNC(7|$4zv5Rl*oO|`;ggr3^2O7(z!2j|wG$*d-j)sDJ
zkq+t3yC`>BUM{i7C%14DW_18permLiXUV(UnaI|jp$tEo%(ks_fkDPBH8Qm3C5fxO
zOK4-<vP3OE%qY~h+Rcn2CL88jxVf+SAEb;`bBU7&a3BUkJ#7+yGM|b%Pv1<TCv6Di
zGUty2$ku7|XIljHzLiL%lzX9nzZoZ2ohCiYqgaI$ib5Bi7Wctw_))20^LN8AqPGWF
z4F-A#j3V>`YfT<aIP;Qk$?GC&!Nk2`G}rHiAeUSq at liYH23-ZAp#b$S=iqn}P<=j`
zq`S6kIjycX`)N}CXclqB^jm0vZ%#IFMN?cWWl0AZX3A=roN7MLRs-{(eT{w<JEFMv
zTK0m;oXHotxqKM!BKU{t&R{0NfAi#|f5oA{FOzmfd=;<|&#g`X%cF&4XQMvC`K7)5
z0F5G=-JLZ)*hJZXNMvg(F{9Yoa5GB8w0r#+6|48NTHN82x)w3FPjh^aDtWuN<%fPU
z$=1 at I*>v^5J4dZgqEVBG{`!I6JTfux$8Vy6PtCq+;45xQ at MMxa9h10M4K1a80#GLh
z{(1>88-O1vH9`naFXB>Sv-w&nu}oTuw%5kfh1|TJW$V5Jh<0#ZzB6(4r{vXd?xe{w
z#$bS~<Yci|&<vR8=aVH%8(u;g9)DslR`tU?T$k8e^UsB34I%_zBd?Um@(O@&HHYsN
zYr_05O87;`O-a9~Y&BieD-7kQFrGTCCEtP%UPlXMT0EO>eoLEj?sF-~$>`_7Kyu-S
zn-hHD>Mu9a0#d~GC@}mctC_a!^`8skKAzYJupT3HxW|v#;^bL1DxfVuage_kac+R#
zK!2ogrYN{pZva-t%;s20M^m~0;E3H!6YD8xLi-13)a_<+>~-hMql~D-1EctEhAdP&
zIT+=NB!b=B%?UA~ojD0+S_kgC)gCD!hCx2W6#!g8WA`C8QQ6_9Tnq!BPH3-6YTmYS
zlDUg{^*ic(pXOd7 at bJmUFjuvmmvuc}2*VG~`Zm+D7RsvA7SF^8<pAx4W?fJ8=Et>^
z{88rQ4)KI9`8!u4L^issLs{lBcku|422aSv6(cT>?$&-XpR at aFQ(||;+6-X#Oxj^V
zaWjw=Y4>E}_L++#%zVcm(sV~=4emFXWZ?Nzd=|D9X7I6nfCUu21$gmg9x at wdPR<qF
zm{L0JSuYL|1I2d$2A}j2B at 4$HAx7Q#qmkU<%c5{((&IB+8^h}>8ctr at b`%icl8+v4
z?hJ4zc5nXe4w^9tM@?r4?>STV5FXA`45ht5?n~8h406Cg2CC~_F59}Ep;WlYG_A4m
zkVmv@<ZAvM$;cJ?;~P)c^FGFO_QCg&r)|EG_@&Pz8ZG*?e5(|HU4d(+XK%o_2r{0W
z03|Xf8WMvR(w at 43YWJSV1zr|61d!h!#f3ir=?w#<s(A!bJ&l=}71oFB)hVftP%mz=
zp3SbR8C<0{>ouMG@>(yGnd9It&`Kd;=HTm1;C8o2l^8t6{+fp&B;FPPF^!;!v|^Cu
z&t)`u+Oj&crtqvIS;Q#di)&Nw5fXL(Lb<!N(VbZvjI05aRo=?wcZHEF+(SICz4~22
zcyqZyH_#w8*#|ZMEP)hV0gQ)Ktb&^(jeUGz8`#v5q~TkW)&Ueu1b&GMGKN#VuOcx@
z!b{)aEcTC~q;D3IArP7Wh3?!n6lcTRkVfW<#QobS=Xa29H|z)985x=k4)h(Kv?CrK
zn!LO;3@;;uT#SDfaCbk$LZm|?EbV-cAswCIjKqFe?Tz1=gzb0pt`w$e={~&dpb$Q1
zXT`LADdPW%l8AtaWq(LK=>-?H at bCmaguz*AN$VWDXeJCQN at TG~+SbFEaa=HcH8`Pn
zEg8gye;b=HG8OcJzk)%=Z>L~}5}9w(ov-o=;KG`NLv-h!;Z*CN<Ga;**FcS;J68_I
z%RSnciv%ILI$nS)I)&Z$;C>B0Ui at u$eAtyveC+6kkI(Wu@$pLH$ut8W2l55JOJ_6B
z0G!lb_!gX;7?i-t=QJT~FS@&p?!>UGaI$$&H=JzawN8!eR_jm0k~k?G#BtKH at SAbM
zV>a8T;OHF5(S>^OI19cZ^-gbXWCiWM`2rnG%vbbLt|4ZjYu)!|enZ_)pSh-P3&O=|
zVZ0{hA at pm{&lD0mBKAQy#D|j22Twx7O62C=eJmWwO$wM`?!(^{CoFs3kd8d8R)~hk
zz;Rr!7t%gyuFARZY#5n?-p4pq(5e0YJ0wB2j5YSdyuE~L^Fq|-BQRD8gvc67gm|nA
zOCJIIe<)Yv_b$Lt)45H(D^iC6=;-e!_q`D at ii{=4&b8Bo|CoH&=H*9m at uCQW*E5O|
zk*l6K;Yh?5h_oXs`-~SI;7=6(dW|AS*7iavrJlD0hr=kAk58z7l)_I9G1Oh`9TM4V
z>|jAlP=ws!bAJf-gepVfKE6v~iUapSz>W6O1}u#0eIYFHKA<xG$~Fw&YW4+u-jH~N
z=eXSX>Nr|%y#FIzk1eurky`*Z|90GYp`G1qOc~r)+UfWg at D)A1K`D-+ha6dNog265
zyA*w&_>QQ(P);oMxl&xiw<T2EXD!f<{mLZp_xRSka`YNs*m}E9t+OKnq`VK;yCk(1
zx9a<f4=d4+E!yv%?*^<`HkV!z>k8ch1G at 5i;gOeJ0&`4Tjpkf&4QS(!J23FEKk*&~
z--e|vc$SRy-xI?)7mY<L%4O(T$6(aWJ;d_a^j=e&QfK>3n_1xg{?NbTbj}4QUwrNd
zK$cl-YCEpJxGw@{i(C5VxEn($z}MvmL!Z$Qk+<)nf<xL3la at B2I~#bkL;K#nJkE2g
z62Uz}k!h7T;Tw~VbAJe>LDx4z*J!H8)3kVuzo|3P#JM{sX2PZBu8rPjG&+RVRCZyz
zeYA at gX_|ar((7XTgsW-{f*RVHd%6_g%!|*K^qsL6uP)v+28zFvEFL`2?ddP^>5H9>
z4bg_52a9;A?mRvak!lX!p>|k;0ZHExSGv`ljWtU;Yo=&lVa<`<3SEbVq<c8N>^ROP
z0IN^0_2&hFAkRKbk at oet-D<8wciuFRZ)Jvo#3#Z0zdjLG;kGg~xD=fK*iSF%Isl|Q
zZykupTkK%<+LHH?mG*hTg+u_n<)6?Njy+%_%i;S_EgVaS8I=ZkKOnn#S2_uom6^$H
zGaiGTqVPmp-^Q1*BL&79okig`c at bZu%i`PL9#^_-fg{@-*L_eIX5iWnhNrmK_qR54
z!s_JlDckn`79m?_$8eFJortF>%ww1IDxBb7f{OdyREr>qTdTImVRlDb9CBp(0Aq;+
z{q1xLBW!>|$_Q|osTA&ij7%S>I|tI!afR4J8*N<1jeYIM2On2Yruvx|r%==A#F|;H
z?tEvUaU<#P(U!P6EG0)~7emS4BuhGfJkT(5NtS6f$B}$#9eEbRP9`w?#d|pzn+Ia-
z$cum;f+EH?*g*u`Dm%he{xEKAt3x9>;p+c<rs3+F5_n!gZvK+5+Xr*i9z&U(0(gC-
zsgLSTtv?Bi$A)!oWI4pMJ{xLewd&4lo)u4IX}a at up4FOZ#KBv1=P!8Ho<tT at 4EN{z
zj?-HETDZ at YkJ{^YrMxXT1$Q6b8~`rN3c#%!73_^(81avyVbBL at -W=Qrt{;&Y?MSQz
z8=p1nhyJ~7h~)pVM&os0=cqx*&yU}feDz at n-$qI#$~Z<FjsJW-mbrZjE%an2e8|o=
zPSEpPuW5sJ*uH<1+IW!4T+B_jVeG5ni@%mT6Z*5^oVn}buX<{Zk9|RlKlskGvGjBA
z##3K_fDTT^B_Jz+N~{xL_1QWyj}c&=<D^&1J6-z^AR|7Ivl*^ebCw^VJ6-TV`_l);
zYl5-A at u2XprhJ=M-`bx<z_yX(_kDa*lFeW5f6XHDeNHO-`<smI+>|*NGGqDB6?*s+
zft7<<3143<pFrC`Ug+N?5Z>wUmqT_e4S@`&Z3AAYv$fxB5%?aLd-^A%3CY0u!v4l`
zj+}gmjjf=@stDXsKgdDKG?LhA^s!5%?5CHmA8}<#u%8drEPv;t&j7wC&{-~9$C4FL
z5=C_6ByNx0t(9wBdzIiKi1X*S;?l&O0HxM^lBWH{Q5NAHjvx&KKqEalxxrz8q$2RA
zjrFy01b12wD5^!@)AihG{h$T0tS{+7+px}(mi`#qNqad1qnEZ{-imSDq4yp^P~HP$
zn?eiP-fCLs#I2ogjsk)oti>j)CS#NDVjOr{71R%6?BelJ$);cKM?lP at Hf^&;C3oaM
z-;dU1a)1Fead&b*R6pDYSFioxBIfMTop#X-E#C#b1ed}u_OK8dI^jz8Fq8N2`7P9g
z=1TT3j`wi*2I%3>yAqpng9D6RK=s;K>ICCO*Im7(;0KbB*iz7C&y*1tSm|oTpn&mm
z0&WU*$uJY{(~eI`1TC_wMtI+lBc3HnB=9#}QkVHFmRUT!_SY!_k8^mI^9 at TfzJ;JW
z at 3@XHny;p50xptm$cNm5^YAS at P_$qLaq9DFMqnsWn<f_2ICcVRV7ZlvjXt{b-b7&|
z)@^$mhTgRzZ+R89d@~m2FaO#8e9GuPSs2Sb)Y-B<jUqPQH;NKL1l{>8HlW_$fr(vE
z?{C3PL{$oZe>3og5?)$a=lxp-#TJ at rM`73tl7DBanfv>Ec^~oH#ossHOW*>p?}CKD
zYyQmKeYcBk7_BXgyOos2(AHsmFqstd1W|L`W$fqo<1XY~T-Hqjh~J^@8pb=GzZr_l
z6}6hT23f?}c(a8EP0<IzwStJt+^vBxQq9S__<oVh>a?D`?sHT(?elDWTZq at 5(OH}J
zEB#k0-lyFMB_kXDg70s-%*IOsy7M{yFrP<uwULP at VOzmaT+@6Ao<}xphc5gREkf9K
z%TQd3unpwpUmlqle-~(H5T>19PBuV-x>>`pc-n&$5pv!&k^tn;IeF>Y$uy2nhjfl(
z<jBN0I^VVXv^SOhDKGt4Mxu*k_h|pzK=C3h8M%287Ku#T3VHPIJecws+Wm1Z|DHh|
zSaFIZ&j#(kAUB55oJt$f>gGYb?%Er0`y*5ws*R<J!8^41ypm7bL>EC%ysC6sY&gCn
zd^6N+8BR4PQkW2`;=0$=>qyTyZ{T*y2y=4XYs_^dO4wi!C66>CS?iUs?X3xL`zZ;L
zwB?hK7JUg-X+O{AVfh}qb3dUY?FXGX1A1L8Y+Td0+2!Hpt#Nh*hMi9?Gxloc06=E|
z^PK_52YL~dk51^CxrS$cG>C}#7F5t~Z^9RBZ1ofQ%jx}f=M#i?=WT?v7`{KioPXvu
zjtwKK9mi;Fm|khLeU48+SZ2RRXzU60M^3B+7s%CVf1QL8>%lDT>7EurJ#X6J0LpLZ
zNk$6zTdice+yYS0u{fGAp9j}Qfy);}K6o8aELHX}#PKx#Ue`k-_--q>%o{<D_N9G^
z69}MLvh&xw>@sWcvtzQj^?($OIV82i6dEgTF>m`q7X;a|zfu%*UCukO#sW89OQW3E
zAU;)Y#%J}hCs6r=(`k=PH^sh>HiX*YSUb}T-S(BlEf$|%!)r-;edsgZBs68`jY8w!
zD@`et+D}AJi7O6 at QpDN^oCK+Nb!<GewT&Kb?0CZ|2;x&Za_j4VeCRt;drS0GZ+1c2
zSXBTVx&3b3y at Y+KH4bPJE@ym!aPrHuotNi2FTd=({HpV^t at E<I^RlD!@_gszh0e>1
zotKw7FE4jqUg^Bl`6Z-iGJ4T*h)V4rvnXKT!Gjzt2RT9#w~ZLsD8CM)3^<W{nK+ik
zr|?}*iS1XSr>r=BNv&%A{}>JwM1qHp?CTijU*iT}sqpr0lyKPuc-in>fu|2jtXXD9
zrD)t?Fj)(*codw`MyT&)^-}bd!y75Hx8iwqSYjJC`QSn1Q8!G7*LNklBCd5G+m63p
z%Q4w~d`6_~dd|z$YkJF;DE`9qh)(-hHwkNOwqe2*9kR at pC^|uQ;^``Yjo#MBvpg2_
zU$6^C3`?AEfohq*s4cStUNEun?bVx2 at LXy?hzJ_lR$~bc6Swr1a6@&Cl3gFw?BbRK
zGVA|iIeWjP?+Se&sTVWEr$*pRWEYj_=QcUJ9~O^l4spwVxRP1fk7;?2>egdUcG+`e
zkVLg~IotX)kOA|a7E)n=*)yz&D^`_kq3W6zqF>WOv`Y*2|8Wbc|Kk=M|Kk?=LnUaW
zvjwb~Xyw`#6tyNJ(Tb$jv~+2y<9`gxrK_sH(7k$<oc%(V>iw}g=23N$CjSIi9azP>
zW}%nu@<n52WD~XK5<m^~uD*(6{yWY4^oG!1z2(RM1*3jU69WSS4xG5 at z~WH&8)73c
zAKn&pTpN`~9)igPlLLeV$c0$C6#du^jl)D~9%L3q?u2~Va=@4{?zU=6 at J7&O5(7~K
zLyDyXEPP1Mq2(HFu^aFlQX+R<;*&?}I(g<>ubn;V*UX;&30we$hLASmGsy8R{GWae
zy{~O0+NG7Rp9BBhR=$27{C8XF|G&~o`Zvy~^lme%f7cn+*-~;=@zyT=Z@^@^c4DPp
z!}-Y;UP!dSx!++-uG+-py3?3kIID1W!6f_I$@Smr0w>sOG*4lY-H3W0nY-rOnEP0A
zvZdo>%ixm@>W$n9>eCX1E6|4NP$3$#kKBVXJIuAve9W#YKNu9-s!c(2wn<T=)&r+P
zU!1F<*qfg<`q at E0i~8LS(wpdq&S3pbKGvw!f`XI6f={io`Tzor2irQ=uwZUKiU*P`
zuU9sn&f>A;MJ<L0>cvy7*jaWI4W8%FbJ>=79VtVtJj0 at 4e^~~YzLo|>?Z{aF1%D4R
z5_nO2fR<?%zR34R-AQ+eXS3nX(^h8+rr|AX(r!TOtNDN)ys@*&jfq0n(LI#9bcL4+
z{XP3b+|nM%Ku=?P7WXu=ObJh8ZRhbJyJP(fJ>T2V^I#%dva4!h{W|Er%e#DZFhGvN
z9?X>4_kc#ZekM8mEKsPhP?5}5O=e3yGFvG7*$L)L_v!WS19D`Wjz9&LvuYpMfBHVf
zy`Oo<N^0#zjLf4S;w1;$VVnn`FmDbI)_?<>P9A{Y(%#g<0xJWSj;4?GdW=Kb^+qK;
z*%f|)_P0R8xI0o(FNkYFmgk$0&(u0|Q;QUtWw$hoTT+@@EX|Ty?Etiltd8H%R_zGo
zw^e(@@?#)EStIp>23S*zUO%!%vebClkc|?n0d{WU{N5Co-3Pp7$3rzfy$XwZE7D^X
zW?oJGSPZ)5yn}1|D0&_A-r1wwXq-0;jaZsx_rZS)RK9r!A+BeWpNro_ at S?~Ux0bo^
z;8E5{m}&wImFm(PM>c_`nfwD*>k+pc4*$)CF9Uah9mX7d3jmFN=0Heq;*cVUMyKBj
zKLDK=f~6JazFT%V@><2G$6>H?ue&~vpK|a>n)-G#9&IZc$Mh_4rTZhZbUZY34C54c
zNBx$1DQ}mkhN<DBK0OLJ)f=QuCaFRQwZ>OUY^NJc)!5p63$G)&_wY(<3!y^5T~8He
zY_d{~v(!aid~Ke at _ITYNT+`rSqw?Ud>5bI}SiRp}4|34_$gNUj_T|byz4FQ{?I#YL
zip(-en<SG at je^ToWsxd8SKuBbX3b><8mRE-Mk7a2!iBJ`!X~?rK`OxWxoCQ%7v!1w
zy`KT!#_z;KE9w<@J(lg#uF)*ENlhX&>yBfyBd=|>f3nedPimH)=UrJlJ&;$ob{d_6
z7CQs}dRuiyuxFiD=#Bg0Mu83gqe*5V?tqIRUf?Sxv*E&rVMHi4l-#sNue&1}vq&53
zaP^c$y=dqw?hdeGS}d}=U3TwRBEY$7t<4v<x_l9j$qNpF9b0kmnZz2KTIBFT85t(*
z#rJ}9x}1uGfz|9P42|5Quz8tytX5%o`jD^$|5KH)lp#Zta#- at Ko8AXr(v`3|JRKfP
z&w#(N;pvm%$D>4^Qfw$Do}$f0;ps*2SD0N at H@&|AIdb?Z<inau5I=g&*PrQYoafsR
zyh~w^W#U at Wyz+yO^~gTcempL+Q_;&-eW!XM>j{f`QpA&E)r<D^6V!|1lVcRNI0wP*
zle;W4n5r<JM_-hqs1M}eR>$ze_VBVyZ4h)Ew^9FBoy(gz=daV3;^16R*wFww&c8++
zmgY<p%YTGd>iI&koZ%?T8$$MobR|abBCGdgK=N3Y5OTn^2RDSA9f7Ejpf4#$iKKlF
zw_KR29fDM;0YVf}22XFcM+wi!(dTCwJ0NV4nU~@dAum%=i*f`!lwz0GaK+dUDpCb@
zSf3ALEY1{I9gOQj=eUB&lN5LF_To<H>g^&f3Jsy{2F-}!S$^ir48Vm17*3NATu5XA
zG>v+}@ub_!B-tD3?*PG=v2Lg#bG+esG6+Uiuh&Z;cv>Wr<caU$6otWlF~Ka<Ny~ep
zzLi!|bTBLx!h>dfpE)cQedGEif4%F at OmFrl>=f|8yQF4vi*rIF*z8PpL}qm;RObLy
zvk+0VmxtBGP#(*<#bZOMP|P1L&T9HJ{P<Y+L+R}Cu?kz{$oqT^m at Tt&WP0OIs~U-X
zSUj1{7#pAOeta^UJ(=yyyDa8kRxGn~Koerb_~%f_{dq7Q>+`xheeV5Q8Dxi7Ope!>
zpxz9qIyNsViSmvxT+hhLi>|d<>cTU!FsRs_w`g at A*DjaTpjz#A{1iJ4BQNx3A7{t>
z#Q9=b4e4Csez9x|q2W#ke*@m1dwr;voO`F8pX|(1WcGlEt&`P`-rG_U6XB)EP2m(T
zo0A>@@B?hTmu;~7!wXyGaG=m1UZu(5CtAE<&V~a;+i_z-C7#F3MD at HVK0l);?yUYt
z4?)PQ7oX4Rfp=Ric%p|`wh0&78iGamMp_51P{8jaCjPtI`2EEAJq0R}PcwB#VYd^G
zyf`R4pdQq?7u1wb-w9l#?<2 at 8Eo!Yj at 9dgma`*v<RC>uC#JBI>$9LC at fSIKB9YTvB
zQ07aRIUA)7o11~`4DR9%P_1f<DQs%bci`5Spi8c}zgdc&1`lsxGh82KbJHa{j7fW`
z4c~D)9?nnqvXc@!SC>L(G~Gb(dA<!k^-9K?qYBH<z!<7k4i{My-Q5BpV2{`vfWnVy
zsPG<zYycu1%yxKsyuy17z|d~I1^`?kC5jkO;O4P!#ZqGE{h`#3uw+M|B(@vO at UW7a
z04npFaqzpZ5+F#C`Hln_2sBov?e|X+FB)U at hYKBbDYh=p%i585mMK!+N0ONT5gr<L
zyt4*>+u6?)M*tZJ1t%*=XUY)wVkKhjmlu6xt-CS)JsRvD)4v>Seg?3GlE8ZUzd_{c
zFT3M7b{ickB(o^4`X2IG8noAk^U+{SeW0d{=T;xmDxfA*8@)_nHM0An-=aY~1W at iW
zMJyj~!nw9gsY~f$V8ageAES|2a3t(FzR3X~d&Mo8I at +fSou17KGEhm0Y_5{0WUft-
zE5`QG^A)hgf;K?nn%xOloC;g0ad@<g=MuvpU=)*A!+jLx|4G<grNz^_k|=`%mSO<r
zKr&6lU16Y1zxyqKWpx6U^KSxn at 7DuXwhz(6Rw>{)w6di|-tY#nL}ogew@?btguc9*
zFWe)%PR?!vih6R_jSclvZyzK^*5f*F-gnZ)vNdqUntW`pw)Z?=g2GKlbt%J8iOs(b
zW&SdIXmni)O1)U_MGOM#LH2DN^kG}R-5k6_+IVR=DDIGtUb4<^(0+NAyuN16GccAC
zIedRJPEi$})TNksE{qd62>3{5UU02Ima>JdvF&(XHF4%L2N6J3JUVn_63bo^h@*FN
zxfDHNx71gbJEq&)Pq3)F`haGsj%wBwRm1b at L*IuoE^(?oH~=Ku8M6LnX4Ivi?H4PA
z9)P>8YV9SM+v*8XjoM-GnW0<5b2GV4#(^}oWH*HK`)d#UlZxA=_V;jJhiCdF^%JwC
z?(QjvZ;IUt{GT^B^N~8}CxGVWk4fOb-A&zl{q#H^SAwaskk7h~oGmS=OR*;;mcbli
z*&iT{Jq3vxvj=0S3WgdgVZQOZ(fDQb8|($w<p*%v+yiW{dLl(?I_>_#5P;h-6!NWN
z7$vK?b$9!Ikga+3q!?}kUXM+JafatA36Tc;BB&R8h-D94Mv96FttYdG6=K+_I6v|}
z_lo(Sd-G!O6Qk^$%XDt7=EWo58YT9DR*LqTX{nY#gV%l8i+)g(Jo;e;aRhkbiWZpT
zn2BbcSk`*!Uk?QNWIM(wqb-h+(APO|j}m$Vxo2cG232;zkPN!krSu}(XIZLPW=b>I
z0QbXwqU&8LWk`6cfldd?diA1BEV~P!BCO1V3uwn0%wu~AFLfz{ARSpx#E7-D)9ez<
zMt}P-ESw$(PV0M73+G$mPHnLSr|b2>;qW(5uMbTH3YAUh%4+e^;ep@>v3=TGUm<b&
zaax7?!qClX?UmSn;U0;UG>QiBoLLEgetPj+079i9Zp}}Z^IC{8z8VjVas6eqe~~K^
z%5xygcSJjSBE-^EWcfOeCpoJCof|$QP0)$I1YQxxfZN#CHax&%mBydO{tCD1`GMl|
z>&cdCf;r-D3@%2N|D$0wt+eppeOCUv$M`+igMQ1ap^4ZHDF*ZW*M)Dz`gNRnqNi<Y
z?OBPvM^`6?Bkn&QzA=jaqS_+r)g(iztl_!A at Zv|q`KvdcABHd6J<|XHsuzZd&s4!h
zWgjvkm#q({Y)3}$M{K_uYZh4k>fHSGYm1C|IpW(P0zP2*>v3K}pBDJFdP+t%mV}?p
zr?b%V*Q>Rc<FE1}sUDEFznGhN at Z|b_YyPQ3<}Ozv&!8*mk35gAWVnwnY*NDc;7L4V
zr=8wEsW9SEnY2KTTi~RA+K)w~+wriMHW&fTPmJv*)uanZDl~<ct*=Yzi&@7LbJTzS
zTL#7EE;m9(c;o^2FC*)LRSKE4g4Kt;?}No9ZfVHdyYBCJUXr6EuW{`H9_GpWV(l1e
z{!B;r=AlvO0a}N=53r-W)-{L4ErAcjt=<o5-m$ssOTuLd)Wq-*h?3leABKv>Eek)8
zBh$?WHGbIfEr3hVEK-9ty3azZs7S9+G~hjO;9xq*;#N);^<#@#ZNb at vHk*u45i^wJ
zdOr-!lp+NdqdV8Pb%%2foWsh?7{F~h4c(|8r$D>N2yq!&Nikaau>Id?<$RY`o>Z%Q
zLn|qgyUNRUSz2LCkyJCwf7Fs6%&T8F3v8EukO$n9WHY at nbcVDOFNGXDIflnNCZr=U
z$ctmTF-V+j0o$f-x$5mh6E&#0$n<uxY!{R)k#m2I;l>cM+W77*{oyS3lOIen^6SL7
z;b(Yg1X($MxxvQ<ms6OUK66ng^fcHzL#s~h!qcOnqu=9e;n!;8E`5)}Q84NWKzJ19
z(@N;E2%xDm^+ at z#Y%HOkmB<T(G&<!+E8soKOyiyQgih0;(|DMae!qk=9cBo=u7K2~
z^r!HM-eb-8q>bmzFr+oh1K~vuZx|fX at OU%@CAJ?7JGA`31k}dIKwjS78=Y0|w35SW
z__f$H;k>H at 3;35KceRS;`FLvQ^AwMY<-v7gmdfE at W2T=iE9^31C1z#usl<InUv=j`
zsK_THRR<1iYN3v<nd`}kURh?m(DpLGQAvp2k1H_Sc+~ooo$Uv?05*0tp5p?lyy*mR
zw4^t9NA8xIVzQ-v27p5i%D5UOZfTS)(fCpVFZ!hco{R#4?S<(<fI%V2(tt99WJHU^
z8UTC=X0pByfcB2ufly0LFpa7Z<mt>>n(V at h8x3mL{R*2T`4T3~;m)e#d{`#R;IaqB
z7#L7xRiWN>Dc2)Y*#KuRX9W8i2sgCd=K$)<9 at 4LShJt>59waQ_p)SRVh&&;N=N7QV
z1u!}D^UkiliAHzw+&4%<l7j0BKwj}!llv@&x22Ig03=hsV)_Zen-9Lt0MrT3wBYUB
zl|bgAtA%qHS_jWvP3x8aiq=I}(fa=l8h>#1e}%?H-%ewbLE~!(3^YTbWg5~=XpLy^
zZaOj`<Un{p%;1Ny14U65T}#yK&i+3ls-F|JE+swTNq8|*P(_p3FR?1g9nGs3pKgMx
z?)tpBS>n?#p>LV{Ym6j|Wj~|S4Qzu31MA&(j%4>t7hJyu;Ha_m;9t<J3UE(j3|@a`
zm|z&~!C#GgBjt0?=z1lXw|Z>W88U|LV%b}rp_mC@{3`?A>yCO&Gl$5g{2{n`U@`_F
zSe1_*#F%34GDk2)oBRnzpS7LMh~#dzIauW6sgV=l#h|`p;|cTyFi1y!0QUh#VV-fH
zZmGw1CDFS(Z*Drx!0eGQ^jps+EZn-3!Q4TBvGgIVEpx!gP03N++4`?WCFeabL at e9O
zUBtI;faaUOK-(KIHv}qg%2%WcvkyO3)R6FcxCV&*Ar2(WpPX0!NKdwSth?TQAZ~R>
z*?yS6ie+&Q<fp}Z!VO{Q08E>_21(3sklhXLsLy>6TMOqa(>GcB@*ebt&{=FgGS3l_
zQg{?5KaQRObvG3*uTnGQ&Kp`L7KG>0+h~@=9{9WyLHMOdiOx`u6+pJ+{!TiOrp4=?
zW0y?d8R9j~Ni{7S0>HH7uCoUxlphbeeW0j-xcK_qewo$eu0zt^`7x39)L|lRi{US*
zxAzO$)!VO=S#79?REh64uzV{!+}>P?T6b`Rdcp&$Pn7pd5v$#@-?CVi!i&HoZ3tPR
zs~+kT1=dh%<we@!c19LuO=3G^e>|n at UA~V5F3c?olQL0LkMlDrCjb{Ng%!|hND3~5
zNcw(-&CkRogT#74c2!~>gdckLb!#yaYgI57f1V!(%<jy at lf`?hkK2Xda5b-2aQHW`
zq`>3QsDumEbO_N>tFS|?UaN(hycy}i6fzRyQMNc8oxe{%rG2ewbruZq&{T~79)s_B
zYsWq^L}oL_D(o<RFwJsEyVx6L@!ezP at ZDMQf%wS17teaJfbc$~eE?6xYqRQRq#|9j
zt73N}kob+s1e*G^dF<w3ZzWuiq2BAk1&_p%)NYye^kyIQ)8>KTR7pK=U3-hTr59Y7
z2UoR&_^-;V57{I=8t-4$5VU!-8{)m`C=1EmAhQNZuU7PGZ{GejJG|lEi9Jclv*L`8
zP at ShRe=P+{zn4iLWY~tf=rOwxa;O_*``TVa^cWruq24w;xPUE^@uZ+0!_k^;R8OQd
zm3Z6-!i!|}f_=>>HpfG|;y2CosMQ at H>!k{lPmfA^Rd|kv7g~E#iOg9~TjSLcg67o8
zI<+foAm(c}xHsjej?M?eYjG;8S4^V1VZAj$q>(b4I|Qk8^d!^^FHV)ibBEOR=uP<T
zvY^&|Esd`yUJo3Yi5CtvH!bAImE=%w(gfeQ4rqJ_6A*RG&rT4o at Cy|5mCwnvg8hBI
zHgXf)OwXcF^B_77=KDFI6-3IP?cp<<FS1GO5Y7TxTI<Cn{TT%RjFS6sPVh!HHxo*D
z*-l(!!fBGlUxW#zb}qEV>*=)pCaJOz&E!zeMB8*?{9f(8p4{d%O#W?T_vbaQnF<;2
z4W{dLS$_9Ne)myd^rCrIr0iFGxpZbBYI4P0r?{g^w8N}K%APi!6d88>*FAii9+aO6
zIstlI{*;>jq2M<dc4|lIeUgWA at G}`fS7sLydAfZ-EW`M0!ES?6e116UN>RNc@`(Nh
zrLqrVsd0%?E;UCC*;s)RzfR3b5A|f5(I9gdD6AB9I_NM<bxkFH(m6rnZr^xZ>5Ac(
zglH1j{`0NG=A9JqD4z6Yx5?~8IPg+{9rcF;@A_F_ofMhlP$Ey%N#a(JBxjZI!q?%^
zR!~^K_C_|CO3wYs%LCbs;9rPaaV6heBAeEG>wNAbq0c0Cz1pBlv<eEI4>aZd2l#JU
zp;Xy&Kv6ZbH}A;W&!oI#poNZk%MXTb^s(M`Ryy8 at SzTe1PqkPfi(h!dxgc2T at P$*h
z4{AOF#+0{#x97F&Q`9PGuW=2ucT{3WBnE1B`cYPAIVf)Rd+Xc>#EJ at BVzTI}E<W;U
z`N0i+z4%F;wb)?Z5wZNcbQWYd6az<TJ4P?Xt#Voe4ap*>eF`Hg3Cn4*5GaHzIP9@>
zv~}*J;6QP!8T<IOL<+ADKsAnoPoXPCtu{+}9cuub-S}=W=xjh&<Yqb#B;uS2KN7xp
z84mp<esiUnj#hELF@#<YiQx|jUw124V^qlDV_yOKf8t|@q)PM(eaymkdD-X4hhgvY
zxC01m8!s5vSMb1X`V?y_CibxR8E at XFp`Oyl%L`zrYeh-DWDfO#+XCo!4Y-JPu?KM*
z(7sp=ttCK3X;V}hQ(GasOc+w~OL<jK^h7tcVu&k#{f0gmO!9BC&Z)4v;PI?@k6Np%
z2;VDy;(4&4rME~Fxc4%|oXZR(m6|@0!0tXJv9ILtsy|7VLz4SF$^E4iw*DmarJpT*
zSH?}@QpBf67MYqpj++mhDnAmsklhA)wO3 at iKC&({)f_joE6ne*N-Vk^KVGg!OH2#A
zb--fQ&<NlGv8*?~=g02<wZgow6Ob|_c#MWMZsqw4aA#fUCvx5{@#z61nO8j{kNjND
z1Cc0}>GXnl;Cbc+4sQc1;G7ak-RNZ}yzYN0;lT5>n_xy{@{K^(rjI2s$%g<3gn-L{
zuTu3|N#9{P2-$05d^~Ko;VsFQ4nRdJ^S&hGn;iJ+Mw+xyM}mmz34y<{jyXsZQQgNW
zoCJ4fh3jRwM|wJ at S1fti1hWIi_`D&fN~VY9KbnbhI942KEEk3XWCY51N`N8E20hF5
zU=h*@zxU>VF$M=R?=vIofWpDF0LzmZNP}G!OI#+T8Uqq4Ks6u>Qp(tFl_1X5q$$@!
zuNlLxQ=%<qp9u!w-5O4hO}%8i&0 at T697w^Pc^N$gdijmc;@P+Z#Z$L$N1>m4+yuJo
zeu1BJR(t at m#^4Dt(T^>PyINs%){-Q?zMnP5=JgQ-P#KM}O7Ly;QQtjef^-R`?;OGO
z4N8AY=?j!TP3fbQewWfEl+K~lL+K<+hfsPQr2?gA4`ccXrH3i4r}P5#C{sF<Qial4
zl=>;1Lumn}cTl>3(nXXOQhHYx_`gGG5vBK1dLN}FlrE=~k2ly%`IHt?I_M~-sgz!!
zoK{Ldru02ZYbmXy^c6~fLFsdpmQuQg()%b~M5#jQ6iUZZI*d{WrDjUMBwYQI()9N*
z?M3OOCQLu0w1v`xl<uIkjnd7O-a+XCN*|(hHKmif<j<ruhnJ_mWa at o9rCE^1Q>Ii0
z(-b|r$y8PqIya>{WK~$SCL7=Nxb|O3i8#DW5J+D}eQJk&&3tjoLEko$@y{o|egLvP
zYlbQ9N5Mi2_VB|*3_HLo4zPNk+H$)u8tW0t<u at sCV+r;tDJj{!Sqb+6&0@!`!C#{D
z(5s at 4f*bPcLv1zUaF2k6;J<I<dE8CBHVey#=YhpG&jIy3 at Y@W3El?kRH27<Uzm8CI
z`~?76#{Eq-ec%sjK*FoQMKdN;34S$9S~2Me?QbnjbqTQreDmwqj32CXa2ds?eucYd
z5fS&aMN@*ev_(z9-kYqw0C4(pd|T8U6iXOnfOanllR?lHwFc98mX&g>h>mE?7MjN|
zEa>Q1dnxpgP|}Ln0<?teK2}5cfIg at L#Lzj+EaCqW at O8mg2H<NtHt1&ydfB1L3?(eJ
z_z_J^?$wI99fUWj)sHxP4>}tj`yLFvYkQlOjTdkof6d=3Gtd at DxAqd#<z60TV-!t5
z0OPc>F at _~7J%pcB-k)Er>FGzr`<cI&1GCcM*5|;ybj-`ZyiBAB=C@$JhWQ*Yy&iL0
z{X~^ld>b{|K)$hqwiKucB&XE2D+KOU<A=Y^K1==81XA>d1dWJ5iW)O_ArcV?@~lZB
zB?wf|Ngy?5N1PJkOq~Qu;RF)8bn$P}NAA^uBW{J3kwEEwWNpX=#P#RhNOpg?Pv{Vl
zXRUtKc!@r(y1tIn2WU~+l}wyI(Ju7y8~q`EI}pFEn5SVL62YfoUJK?mW8Qv%iztNT
zo9DoMf{YUg$=v7L=(8Q@!{Y^BmQGGpgQTA9klF;$$_Ik|B<8UPiVLjm&3-V2i|hR(
z5BQ2}X0iT&gBcE{*cHocdz)ktgQ?;c$)dKjDnIpG>iyY`KGs0-gILUjdQLr^8NgkR
zxVh$l7S=mo7tOp at q;;Fmf!^T3y$;vNC?d+k;FC0kQ$lC)d$NAE-?vS_LjN`dER8<(
ztRBcdKy!4Pzy;vOK>2}S6EX+Xmhf}xp9H7C556t|ITLtJW at pY&o-+V`ct$GEu)$A!
zlj3e{t4;}y*<`M;_9?^f4(rvxQ^6F-4V{Yjom2(+$Xy^mtsp?FfhWztvi3DMc7lp%
z0?;|M-63u8sa1Bd4EK<hVN+sRIpT_U@@Uy76|O$PM~vGCImA#ZSZri1;w2UsxA~nV
zBqM7wFEPou9hEGQVdV7V1^Vz?v3x2JEIF!g(?5A>vDeH(sE-njI!fB3x*js0t5Kp2
zj#!^Lzz5(Yj-AgBz>{6e1MC2OfHpwyBnI%MgQmo3;@X}9C{Jg_Eu3%ch4iTRX9?>4
zIq;VOs_p`hafJqJ_uL~0Z&KtxT?@>kUHEvo+1*QPw(I2P<5^hRM|gA=7?dz)ZWo at o
zPIGtGitkY>^@lw_#D#4oH|5Eb+LpV~$q8g>3zy-sUt;-V<n;t{w4jl32hYgRerRO4
z=~NX_*?7M6ON+3fNGbMaD3OJ&^gW|MD{j(ly_*+Z3i!<RW{GA0hvE^tw3qmUvKR2a
z*qcN302QOXt=gMLrA(+)H-kR)6I*FAVhg*pUl@;j at -~5YA#*Wh2Kz8?hEc@=js7%l
zC7_CX`zpf~{2xH)V^vCfOo165y<k)5Euz~M%YHB>lobc3g5?^vlvh30Q>~f`Q)p_~
z!pr+3seOFW^EMyDS#vw^Gk(Sieta0*Zt%6oeAl!{%{7K+Tgw|B>!n7g`mnv(R;<w;
z3q*jww&8Am_&3HE?Xdair738-3cm{lKhT%2U4ur=T^fy~-hpqcL{ET`eIPvFUViYg
zUXfYpFyYd}v+cZ!AD9a~kIn``D{Pp^W`Gl#DpdZ^<@=BJnB at Sp%c`T=aLfJ`2UFaQ
zvS~(Ycy>Dc3;~z^kC%1*v396}*;2$Wq<l?1HY1g)LbdX$CwHn<!|P@^Fc=obI;E?C
z6407HyMO%8UB4AZvC!iIl9X5F?)=)^*D?2+J?RQNudM>E&TcbKQt5Aeu at IwL<yDI4
z{m}UI*j4+$J7dQDh at aptlfb_Stv2YsH-*yZm=SaCy`ogUJ^lOtIP}81hkceNrTybB
zlO}p<ppv&=5$7JjNU%i-_d^O9pUvoOzg9}8_xhjIM&lvT;TfPvHsfL`Rj8<>tJ!uX
z&)H|YSqKhbrFb4}xvlB%AXV&I>q>kMewwZNZ{Szu&amSrzCjaJP_eXEu~<*-kHyrs
z9Urw(3+7ONmCBfFXQZ3rDWb!CPJGg&kfh)+mOhp)fDytZhx#Ixyi8{!Mmyi3=HK&J
z*nNMt$B%LdJiS1Rm&F3CRdc{R#8a&-f$(hsa5Asgs+R~toq&=?d)+SxrB8GSu}^4o
z$(dlPq+T|!e;-oUlZU;VZt^p4OSbNdEHg=JC5EX at 8`ANZS==tT9XHi!Lsp|+^tQzN
z`dF!l?~UCpZnY|EiycUAmp6 at 6^qP1T3l&JEm&S!`>Rxla2VA;CJ at _-+z*e!CUiZIj
z;)`I|zxezN4pb-;N at oS_(%ZO=ES^)E_h>M!G_MeI5QO-R(%ZBd8G(0%(y?@?FP5 at F
zsSrR=3^sC&Ilwl1=m;M0qNVn)WLA%$dNBqgv3m7{HP}-U-`TCkvf at LejV-u4HaK32
z$gW>w_SEawS-|L0qYYBtp0xwiy>=<@{F)m=*1X0?hNye3faB00Mc?IVtF?!&hdZC>
z{U}?HF98SpvgN#ihKTeQ(BnxcWDO02)D)V^YSk8V(7q8>L+QGnU>=T^@-98%(gxj)
zbh-huv0%`q?$hJfc{bI$%x%qs_4bb>%OxVLFN`gjgXZ>+ke0|afmZc5#5AlfJ~%;r
zPtFq^_|V&Ga8z~`o(}E#<^%HZmA&jL{#Hh=?N__a0v#E|4&bSmX+5@@g}51J|AUul
zbtVVTI?Ex^08)<ELSBRkpPwkf&n8i)&D)Lp7!ySjpNyksU*BRh+c#MW>s-}jqKbC<
zQnG1^4c|JSf50}Xu(U6C;i2lfb84Llk4hV;)#15k__eK9YEAh4yNBT(=I=Ff0qR!n
zGSe$F8QN1%3Bop9>(SD|THc0q(ze`=4W<2%3LWPQ;(pPKk!Rz4*Zt7LHS+MNqMmPA
zx1L at ZfyO}so`+Tf$*u+_yZZB!iLPezt}=Jgw;gaeA#9p25RA>W<sSgabRC at q_7rK^
zwD_O24-1iZaLcjQl)O|}ZM?7c0F=_+NoFQr0_h at vyTrg3ak&DL_kKlCr%n8vtctTB
z+Cz5y4z0(`-z at 5@ttd>2l|lt(;|Ub3%jC$KX%aiEP2|Ujf=S2f-_-GAsP27A-mWL=
z at pxO-r1iv;Nb_peR^sB#g69&i9>GIA at cQTYrHZhZw$z95<EoMQkY6AFJ~ai^8=u1;
z`b>F?_V#nQgmF?-m*Y}GUX7^Yc@(oEOES#HQC_<=UuTPAS+<V*gX)aWD)yz%Z+I2y
z9X!<7TQS*+cRqcG&;7oi)%qf-R{WxCoWAT3P^d{wq7#0D17Yqdv=H<W_%hlGVBy%I
zD|GhFmTKB}oMsXP<I7g}dyK=s)LlA}7QZ~(pgaFjV-jTicoAULxfroJ23ON+Vok(0
zZ9!L;Ph-h=z+o+FVcq#^4f1)g(HptXYVsBDrbB(T?=Tvw2a&g(iq~OrJZUr2I9zWn
zRm5*w1w7gom{IYkv7g)M{x<xUI9x#05;;6s!fQpZlHDyz#3~t`cWrGH2jj1R9Z&W_
zZTiL}YCMD*-1DpzKrb=0Avpu$`M+5pcqn+8oQK;`nQNo}Ll8Fe&${1BXD{+>JU6#f
zVO}%WKo5SAeH;pu9~A#DYi|M{Rdqd%&q at YJc!OpnKq65FL?Rd)(S!lXgBf`PGZ+Ol
zDhe7!6s!?uSZaX8muM!}r_^d|TUxE!ezn at xY6}4rvp^O=6XM3=0=T_lK%z(%mc0Kt
z=f0UtLg4Gy|Bugy%zO9Ud(U0ZJ?GrBJX;05bEpk-y9x9Ec(8P29IvbH*8oDl9qS_M
zB#@x~9<s9(o}mnYMVk7cRdgSs=t?_w6qg)%f!`J_elg~3jN2!llnTCwyuKa{8=~GY
zm)bODZgdNUFU8PXEpBCMCT at tgj%b?P)de|6 at tj?AFemEXh0nkwm$eDypTn<f!o6V=
zu+%LkJe0rjvG2UqXRJPD^4(#)Gx=(SfALrOGnwVsRAH+x-6m2z7IEbJLg@>5hw;9;
z at Ha3HGg;!X>q`Td*n)QT*=|4&nb6N};w73RwZ>==Hn$3*s}6VsE`JZCqwm>^VBmIY
zj+xbjUY~=);cOF^&nIj`Ax6Zy3Az4-p&R;zt_`iQ!-`sATNs*e3C$lMh33N&nx78;
zQ^*HxXnu0|G&B(#gyTGhyAj7#79~D;gJgi$zGryjNR07$Lvk4Ky#XqOYN>uIkJ0pa
zZhy6rxEmDQ2^**PbC(933jzsAPE<ItCT&3d)zI{QIrE%>U?Tio8SID6iY%fy3P_U%
zG>1X2<W^GbnZqMu<Z6xsRXklZ(p{Kyo?F;B$9Wt4^*Qt1m~t~F+=TCWGLpBb8|+3K
zboK3LN#imdU at jrZg#ejNPmkOagS<p at Jf=hV!q5})LOs3S at PCIql|xPenD-FmMLOhp
zG0695jzoeGxIZ3h>${XT_x}p9`5A&ZhLt*zSr1K5#;FiCs{)RFXhdkfJz at sL2#a#n
zuW73eQ^(vyi{E%tbWN(?iLkivQiNNO<HblqD at L1K?|gx7fo=z~W?4L06Z0{iXO}{f
z%@@i|@r9&xvUKErRy(uWNFji4&J^|O8)FCCS`IG!1wT0T4IKE?r`+RQpenG^*R at Sg
z$rZ{Tqut)5e*8CF{90hF+|d;nB^5Md)E3}UeTuc|Ym-4fGy<5=e6Kkf&cUR#H-PdP
z3=hd~pbxm+km>J`scmZZ+TbXxWf<1tz{ujr<aVI;ytKFxiYHdJiP^=03)OG(Vr~5(
z7eK$S0a-d0TN3y^#u<&qZkvOFo}1JU{s at V{*?$74^|C(@3T#sEG*LhwdD|GWgoN?(
zp*sa~;Y!{xVB#fp(f at SI%li7hB<{OD-qEq<nWPkGiRy`F>#GjmPpe~8G at GPY`~S&g
z(9aKM-PL9?Y(cFnl(|---A}{{<bbahhLE_Iko8r_qE5mH8zF1iH#|CvQ^`a3*P*m0
z at Z$*nagqKpp%N`lBFnQHCB^Z_^=K at d4D3ZsCW`og{txsAyzhd{k#BIM6~}MZV>~{|
z>;>voaqRsP1IktDv*%@&8k|8Nx)YI4YJq|9w<}=v1L at SS-h|2wX!i!Sqk#V%iW-Aa
z1)%e4!K)YprWnuofK~nX--t at A`PxK75&r(i9=cabQtKb#i)-)F>(GAxd3 at fp;ulEq
zR7OP{QpRqn{jgMh(oBmqJVo&hwyUoLnImjooFeF;m6 at 4Q5;yH_qag-kpWK<e`a-$d
zuKucbi5amHku64&6DW?ms5v{9PJrfo{bzh`SaG?q`C%xPu_LZc?crVx3ZKG&PjYo8
zRQEDehhUS0%}Y}RfF1rEKO#VF)Z-l1dGDv>Be0;7o#?OD=Fi&iQ_$l?Mzdd-`oX<E
zmO2XAO26xaWfv_JOAZ-Y{mLIvdM?(PF*Vo<)8_P%&l!1}y~jR5%W2(W8tA+Rn3{cA
zEneJeop7eZIp%LxKgXcnust1Wra!i8(<T#!0lZtbKVU`q;K54d7=1uXL8%6qHi>;)
z?>R6PvHbKs6iH+Cp3oi5 at YA50p2J;^#fEGC=9RD(Jq>lRTn9?Z+y>yOCjO63Gv$+w
zGwofz<+6F`HxhQfK^jV&r#j#Gad~*asY{^8RG4%D at t55KVv<6C6G=o-Z7=!r@}Dbz
zE<H>B96Ve8e0NXz^X#+b&$&J2&sUu#e;(0O{%ntzKU06qJ0zG^xx>EHgZBXxY-=!N
ziF^<JOJ6!P{sJ;|V+vlY;fH14LYLA>1m9o3)5H>0Hb^oqO`u!N$Z;;*_Aw-MD)1Vw
zv?|yxX^mc2W5AL<IQV1sV4vWw25i!YuL2%{T3*n{(vzCKEUYd#6kUC9&WNqP=O^;j
zx2Svd`Ow`ve4|xJ&VpbGl5^INVfg_Yo;{VMWJS(QqR=QN+#}CMm*K^l&pBr002HvN
z<3da%M at 6s_-*}l;B9Z=ViE|NB)rESDYFv&{kKyV_ty^|*?mnKxKEl=rclYsowdf#;
z*rAW_dt-gvlEeEr4g2^F9(Z4`#ih)<xrw^zs-}p19|+T{qhYPGz0qz`7m<+BKI*&q
zFlV27L$mGv(6khPXeRA0l=v#sQb;zJwC-=@|KA&$rmADQyNBiC%lJv&0magJv0I at S
zmHDx&N15}&+Ox46*4te_8P;Dm>afb=$`Fr5?3LW4>DL{}>QX5-w)3+MhJp2w>)XT>
zIWSRec!8L0)}davgR|Xre?ldHb#Wt}$*V}Db)m#&lG^0}b<%eTt6+>lE=VyTKaSj1
zoJ_)wra-o+ECmY3(P_!*;pwq<d~&S;9gU2JcH{>7$#<m~BCYCo9h$Zd8!-WG>pSpi
z8JhEc%oRd=`c+wS7E=d6VNLll`1c`lfYA~dhDrzyKa9ea>XL5gw_Y0+tK{L at Sb%F|
z5$Q0-Xi)6$E)*6uXx{c8eXgn%TfOYGSNNAEwu>o=be(c6(9gr}cSib&?~u<m@<)M!
zfa_C6VI<waBsR+i^-K`TAE(Q%uow2^)c0VF^4VTDO27uGtG<A~Vz^Y}#g|`ilQJSc
z^YQT0$n~+$Bv)kVJ!N>C2t;=3^F$`OQ3^Z=neFXT`*HSJ#=eLNazciI>ruU}7GS^x
z_G{*J?O at gb1l9DNQbyQk{@zu)Y@$3XC0)umgEiDc*TN at IlS<e+2=Ima_6xk!7hbJS
z(%zHTICY(Nw{XKRol at D+@G!!x_2GBBP^Y4oA2p==xc?O|+v~*{{DIVNTLONZ2nkoi
ze!dzmP(Ss==A&@}AfB-}-;p+00zMLfpprJ*r6!Ti8ZCx}?f6(9G4&9Mu_CS~jKOWm
zAv57?JBs3YTn0#kl(4-d=d;fYhM-kl9-$o*?+31z|Cl`5W73|iqw2%oqUZ^rWodr)
zQa-s^^PSFCZ+rxw5>KP_%ku~xclDBayQC~hF-fwPuoOr-zfm=>!i9oCx&pt1oLOyk
z=81l0`4JuEu_h^FCt%yljo7)#EBUn?)8${^{|bK1fH3Q+i2KKEER#`-w|vT+F-A3!
z3Irw0ybUwMltF&ED`Dv$fc_~ia!Tmm1lCrrE>7-^3~`K$oGTG2QXGt4cSet7^>veU
zFQ#TShO2P_{Dkql>KlFh+{(Q`W4uLiMU^!G{e}f<;;;A>D2$;IALV)*45Ak*#&Hbp
zr!jnYMQjX%cu!SQ2W#5^qvB)Nzi{?I{<xeEq at oYxE34uL(#QJs8piFEJ?O)%t5>00
z!)=mW2hG^yl}{%weeVCsP-gz3ub~`<sW_JZ?PDzC at fr@NCrg77trXcYqDyH=_2Cp5
zYztpkw))OW>~dlkj_1Eu_OT{?%EChNokU{1Pty!ktc=aT+LduL at LqHV*pt}+LcN>v
zJ;^;J?ons+SBlt*5ay+r)G0hoq6wa7Hmc)!LS8H(4HJ~t&DA8Meoy^6NVSoO_jPnp
zQ&~k{KBn+Q^rGIn4?BC at m(k`^ewjTpR5ZT94>U6}Mj4;r)SEw2jlsApcAyvjODpCB
zNhwM&&J0Z&@5it?klXwb at zepHdyt;{@fA4h^<H_qjY at cNsD6t<%Gfa|eKqV?XAf{s
z>lIWQc?H+^09Q160c=-T9Wj7+>-m at I`7a`X+r9F(D8Ms`OP`fOTQW(%_c1=maR4vT
zD at fBT_-J`IKq!{Yi{Vc<(4)(EnGbbA$6tDu$>n8odz9I<EFK3nsSoxnBk?j)k1}Oc
zCU`wQPmbpIVSbj!^V9qT>k1vo=Kv_WNcTqY5lNbOCG3XYiS6V2NIcY6;(L81R`!+n
zQeTNrj_+%SuIw}QZcKG&16JsX6!5YRwrXv6pe4Msix+IcUU!^^y&f6juITS6ZA2G1
zCSV-g<u*w(c{SiKvJJs6k8}EOfRDAf+1^N2<$VhmE)?4%-FgERHB|>pN}}D==pMUQ
zEUwM;ln=$?P!-!(*0QD_RAgLH?`0SGL#TFEVG=9)i{-}h0mLE!i?VxZ<aqS1y2xqw
z;N`|%cg`H=n82NWX8(ymhk3RBUackuG>3o!v1|8gI}qpqvD~Bs-Qjh$ER95Nl?rOS
zF5|LU+77AUq;i`PsQha=Fs-IfcwT0RfpnLrCP-S7wi7 at G8@*7K(crz at 7%}@V8LWGk
zh2H#cv8^)Q!d75MI*IEF>r!_4<gLO}m2?MmFGUbI=@p)uj#6T>bQI;o7NPW2D?RlW
zN}uOXDMIN7RQhl#hM3zCxI|QDS>3MPLfO-pgGoRF3gye;S?(MXe&2*a5XGE)yYR%_
zRKrU9K;fxd;L%$kp{gL9BJ7!lX4-;2XJKTxyTar_8}ad&hZ()*kKN at 4zY)0M{!-4+
z;DNBis at It!JTVBKm6`p-94SS3%E)U?(QBR4klm}w{g!i7S;Ifn8Af5*Li%J2zi#R7
z&|fXoA>pa@@POi=vF+jAC-s?AEH_mjFl97U;!z{G8^WLQ0rU%{ZOFr+>i~DgZlQD+
zA39TD9{s&mL`VF$QJf}hGI`}-dVJex2+a4?J1iVerNVFc3TjktO4fczDjx)Iu4>__
zev~CJLXot{u;}1?kCrktGT)l1Cn=DgDm<|l-%3`dqPmUn)J~o&wJ5{Ga#KlZM{HL`
zb90>9P7T|)xGKS&QRQ}37nw!#=WJ)V)4-<z0Fg<Kob3{xS_4mP5XA`vcorPF#bz8i
zR~Vi10o3GYfb9{Un9JLc{L%<)!*sF-%1y2uQ5LxopjV%?#y~4GF5HZEf{Ux}fd(vY
zyhk)QgiH7eeo%PoO<J+*_<-Lgls59G1fg^+KEVK&;^M-kx&;4R$!7x>>_PH4E~R2C
zx5INuCm#`X=Acz?Mz3;_;gBIwbiFS;@e<w}b&e38`hy9>k|X28-MOOE(n6r%NmTXw
zQ<@fDM%P_SoGX3o9%muCKU?A)<HJaTIqRuNU=rRzV>A!CvcbUgIjK&e^aeVk6L@~s
zRA)%{8L#zfiB2l)V|C$g&uCg!OQbfssgg{wO@)R>ahqyRLt(Gw|EcjD%O5R;qKgL2
zePTNb!^X$$sN{xTHCCLf#)pYclk7OO58w at RCp7RbG#RfBS0M)`A1)M1_Zgyd^}0Sq
ztMHGXwgqb2sI!3lR&UJ4=H=X(&UOmVR`<~iGZ6|2ycsZJv1T0R>o6Icfigf^U+v-U
z<+Zrwo{Syg at x*jN7qj;F+Jn*gvcY_Xmz~D34==$VeYBo5#Elj%N;WG6vmQL7=dl(2
z5~jyCWbJ+UGmxOHy+UH^IMsvQ7{a>|$n9e!zlx0Yv0@^1*c{C3sj%TenhZp&-(2S|
z?@!$wAmt1TekGDV#j<N-jOK#NdNBU^Jg_aC7>o4VZ43xVI;1_^Vi%%~VXhRq1E$=X
zU5Z!6+og~PR^&gPqxJsRbwtqY_p?r4$O8%A`$7-G(c`zfS&N at F00%q-C$hhn{Rzn-
zG<f?H(ovBFcp#-L(o*o`JUfrJ at 7<)QwJ|r@$0j`Vve6))H2DP2gn96|X-NVaqtA1W
zS%@Cfm3*SIb}kHgQm}+Qt7V~Ru36{~-7%WNyupWI_#qJ<F2)DjLUe2n4;Fa16do`x
zc?vu`MeSqmtpzvXdw6YJWuJ`R8P`sho&)Yfz)OGu(xz68{t1$N5YEqPb*>7_CF7t6
zgOMXQj)D+e2=xiO0KrFwN(Bw-uRkRRe>x*Kpx%JYIItUb6hhu3F^>&f0UcrG`J at Eq
zCf72oouqltGPjbiMTUFjNlwG^p%wkSz_e&}Xq}vZ_(0Tlddl{%Js>GJw8j{HWq&k+
zA(}(_m>>QJ?LPLPjSqK)88-`Bsrd=p%%D@@l*o3HX7O>a`3KRw!)tEI?iV-?Btw-b
zciba9l}}SNn(%7JWkTt1Y1ej$fs5d;6qpNt{ehA2_b#FAm)!XAl${5r{hw;0mc5d)
z%o at 2(YYbcr|I^^VfUYCZ{r8(w!-xjoygR&xu<^+^9}EY`#YCV#{I{X~BqdAXJ9yoH
z)a#zf>$X7M<~Iw&Q!roYj=*xsypMNuu_ at ZoS@1OJvcPO%Yl9c??xwA at dOgZ)BS!A_
z=OjCq4|iwZZWKzhAZNuuF9V{hw%q174#B~OS4cDOizQ(F!I#7Bi2cm_!pBG}xf*!r
zFn8nHvzr(X_)Rg4MmKNX75<%(_vfClLQl=|;YC2~AdWn26-txop`TEC5=I%e&?rnT
z8$u}56tK&k7NM*^)^uwa6%*fF6~3M(W|eK=THJ1#(Orf(Lv#Ti#Srl{43Dix>SXIc
z9D)t+oO1}Uh6*#Sx7u=JYzTx3bL=gAGFE3R)k(v8_qpr*)X+zrlz_u(j33rl!swq@
z!$@O|0c#{3$7*)uo>+o_3I51zc$oqJy#QHc4eHl##{*9z;6o62px~_eq=fkSjAUY^
zUJN&j0(C!Y^0N244{h}Y?hO at Pqj^Zv>vL>sAPKiv_zgS`sv>5LFTwm{q^$SU<Yqii
z0DUU=X2u&qavD8GpW}UhFMZiU(i57S?_*&}@$d1V6z+R3+at1e_2UmvG;l|zADzV#
zCyR&&y_<Q;T_|ZR%^=)(Z=S#GE7YCx?D4S|NC3s^AupitX6`(pVqj^bQ2Gfx6?cvb
z+=@Otg{_V1U$zhtIZl#SHyf9ac4t2VQ}=7iFJWW at 975<~CK`fh{${}UnGp*nRG4XA
zAyc!YVa5i86`AQr2Mxca%duLK)fc-)25sE1MXRm2kVk0rH2V~&5<2T=b-tL^mU_i;
z(s~kjrL}-X!&6W#E at yS~aw~B#p7Pa(vbJCjCauU)AIXfWr$(+poO=LU<}S~XGFCUc
zvsbs09;&MAp`u)Mq$*{`j>-w?aLVYpJZcYx)Iwlzv-?y?<sl^WYsxX4aaM<P_0TPq
z;&kKGQ$6)gd0C!;I=w&cd(8I*KN04T)*~)Q4?Cc1lf~aQ6kQqX%l#wByF^i(M#zDz
zs%#T~{74;D#pO^K8y!^$lGG_w7+ncP>WZ&31TR&`#i|38o2YYV>FRBObl0te%18KE
zg9nx~S5X`O4wqR1T7KgINv)CS=ox at GlhYa^S#pKbw3t4CmsR=L4*mMZp}sY~TPg1O
zi%HYQDU#b43EiJHs)ulZLuPWY3N1-cOP~ZZ#Qd?$aoXcAzV)4zC&~9V^NTrBK=ALu
zn>jVSJ$fbQ8Xp_LF&FbIxtVk&r?1auQdIe*-m?d<<mx>tzh}JT0Q_%Ohpqyo<=?~h
z;2pOgm2K&cyE&^-y}4Y!<IY2qn?7|{s^WB4dftQK4OsNL%v-BpgZFhuens?Sw2oN$
zF;KYGD;KB+^{MVmkVpTXN#7aeQ`IHC>*>2K2e+N4E!(zr*FiW>vh~)Lk(4~Ux-G8X
z=gYUNcfQ_wH at PY5x}T6|eOw+|d%04<ULJsE)%%<UNROHoT!b;4(>Eh)f%k+{@Um$S
zUJjB`fm_&^nlF}oiJyy$oY}g(JX1#;A~&(Ry*3I*o_y?2NWK*84PF35bym5_AZ)bc
zkHYeiTd4_IE$WZ&owpI<&uv7nzAEPcgGd#??7NPGvG)KYe`)*)FyzSz(SAa4>&(Y_
zKjj0)$j#AS4mv;h+kY1L-hF&^SKmNP97x;bzJZv2QXfaIkL%-ok45`v>h9y%^MhaU
zv%vT6<My3>1F>)*7n}o#<tO!V${*wUD3?Y1XzA|b_2&own at K+heD6LU+|f6XVh&{d
zq`tQVe*S6u@|Hiu?aM!w>iZJQckj!2=WoQTuAkY6UVS~$*f$s(2Q$^x_kh}d(tJMj
z`?&dhOODQ`t$RL~pC5ef#GeDccOM6z1Bjgix$_)A>_4fG?76r;Ha!~cqrJP2PdA(w
z{1-Vt2Yl~7jyngC1dhgkmDBffN%+ZU$xFYBTeIJm=xa8i$64}9{dpU4BKv1HqE}zV
zbAY*pgL(2CU~c)zeckxmxW1k$*86%(kG{TLciu+y|GACm)z`V_05gPxdGXr5!3_Dy
zeckzNTwjG~Ux)PQYxDN=HX`lkHlkNw?>`5abiPqGT+{bPN&iXv^vh at B_UUD7qx&?y
zd!HWOc3$w;{w(mjvZ_it5h)8#SJlb~*P_Zy?|wgg4!}AIwspd}NwBQOY at ai`CvZ>M
z{-9MpH9u%2-?ywf+7zAlVSCm6Cs3-4ajPgFCxd#~26wk_ckOw%^~L9CU&7CBpRl1(
zEj<-&VsT$hjQ#VmM#;4!kdE3<!+jY$Fa)fyAyM~}AeOraYvnVvpn6;{CAoGBkG)B3
z)Dm5_jdbZk=xq;JU&#l5@@6Sl8~rToWh!uQK6bEM-`C4N^|Cgft9?Z(_m at K^ccS(Y
z8gt+9xnw>ex!RY9Njvlt$@N75b-Ds0q>L}Pe;sHaH19&*ymI%2)Vjk`#u=~c^okdK
zoO=x*AFI3n%a3{fJI>|iWRX~M#11r%pB;oI@=#R4OHd0eRsD8EjEgSWhMCZ!?2d4Q
z0NG)TzQ7=2`y~0KNqCgVkkEQ(Cf){y{^QK1-?yE)7WCo$y3>Zg$^)7Y(ojb26aID7
zXAXO^wC?dhozv}J_P#fxPHI0PDTPK!?y{{I?PoAG+c7#%MHg!DHwoot05^*TPN&ae
zub;M~B|?p~`#VYa*9ot=O=2I5+J|LTYp&snwLVu{Aj8kz_hr1_!ynAK<`*Lb;XGg!
zSsb$8bs{hZs_<vL_mj#?y~=yByzeKM|J=*YEL<nKjxQfBnLm?UpD(+R^lWzWN+a-P
z#YOAjlh^gxilm;OGR{b at uH`(ji4xaB{x4R*V7v$GC~%37)%r5(g%MHsTo1bu;M+NT
zSam^JV#mXepfar)>T6#%68-D&s#D^s4nWoIONZ<Jo^a*$1RaQY5o*1Zu at h(2Rb4b1
z*84L1tPsrIjL_ROcc{+e`b>~7?IPu&@Q-I;mR+AMv(E_4gBcFJ9?b<s1^M(D%ylgM
zKK=5QB{9CzB&M%C##f?`@zoZ;d~46PZQRFQvjzu9Y=`<=Kv9tg(AqXZJz1ln?SOpp
zz=~-SOFI6f$-o7GW&0(;y at yOceQc-ZD5;3q5I>Y-HN!y|$RoSh>q#b=A<3r>EPn at 6
zu7wo!$<%Y(3#$*O8n{*UoDiA)4NXO>>c~fGe)NNje=yJoG(+A3`0nN?0?PEVJ*dhV
zMr}^svEg{7rKY6DL`2p^@{oH8;?=6M7UB0OTKl|P<1^3#B|gW2T8WJ|0nfXxZ5o<l
zRT#LU-pq&3X^Q23qqiy6)4$S9u|mI!nqrN3<NsocHAKCAc&zc#Kxnl_az(t3nxnlB
zbGaxmU7KlJIY?q=VS`Q5sw5b*0oc-UZ=sTO$md)jcWS{we%IH*RK0j4MJ!KrdbMpN
zxh?J-5HLmlE!J6_)Ww%~aakY=|L%wyZ=J_}!%sSo8M}RKhj&ZV<N^&DMpPK5RwVbA
zwCag9!CTM-VpeHYV20FQjmEISgEN%m{tHVEX~M#ilO4i}-4Zj-V36Nc6WmU&j%3y5
z-5j;;SUy;iTQ#4##hX>*EvpSwM-rv1s#<Ayl_c-cYD-%JmzA~!MoQI(?eIJto`>kq
z0z41okCxK5V7bIy&PC5kn4h6-MuX<q^0<+#%ZEyeqx}S~>;}#8+sAmK1=f3WFB^ZL
z12$5GHO=w(<76ka3E8gj*14!N$)BH|gU>v_y83clMGdH&xM3<^P{R`V at 7-_n-=&-Q
z at 2t1zm;0N#<SkV3a_v|)u3LFt_Z7rQq-w&p)!G2zEj=2q at ZOyrcN`UfT86-W1<X1S
zwT?~N?r6zy4^{c7UUG1V`f*BZ5!PbV9DIUx&8%W6nX?5xlR`!^D;rZAU+&M{<yen$
z#y-n+cTJu={$FT6xEDRPCXIw=_2aFCQfxTb7hr;QD at nOWm&5!hN$oKH>L3koAA+}`
z|A%(~=xr$AR?>FjyegA-!B1pRUjrsjuKy<*z>R={Tj5E)p92$6nXXY(@=TiJZ;&3v
zT5)4b_|%Qk;rP4wTn{_I_PJRntpW9)vkiuI^5jc_e>V!H7^0}&ItX9jqq}^R86E)v
z=~|FUPJpC2t}ElHmF`>cs{1AWwd)`FHJ!e8kl at zG+OQRH&Z_th`1F{KV+mK+(n7WW
zWd?Nr6f{M?!G!q|6Ew$xQX{Fz9vO}FN`eLySkmiMa~=Nz at 6XWt26*?mjt8wiml}8*
z&M9s}&3`jvF!i=X{s2?5<uRI)XW)nX>`)w)Jn2<Tx*C$!p+{bUk51u@=%D4R;OKhm
znG!xI{KG9b;#F&tIve9~u_n!NDYRu5PC+3a9H_{g8>hEOnvdayr1KBYFm1+geizcf
z7%pk5F+7t#?IJ=Ll2{EnXzkw1UtCAj_{vEX4U7C{U?u8>U3wgHvRRqD3>(Sz2CeEp
zd4cJZbT1oxvmOAtyV8Ff#uBpH(={!C!OW$Cq}+50*l=b9QWp&+Ie8vHf?rh*G+|CL
zCAc at MO5TJhb<pzuIVBi!6wajRol?vl0QY5-DH{#q76bwd`?V1in<woh_zhUH_D8Og
z3al*zroJSbz#QJh!AL2=FS7Q_l~FLyaWJ(&!lLh2wRs|4&tED}R)CQ;LLYZbhR$K!
z0Cj;Y>P)2Tq^7A~Ulz at Jx1RNR%xb55xmeZ at FzaE!Y3tP1TghB!z$OgSpgx9Xsg4DY
zqJI<X(AQwoIcsn&TCGr<nqIBvrG;=Cdcm-6)sx6%dpaZ$^P_G*#T_jGWq`qs)VpBQ
zx4E55jA%4oC~l&tae`-uk5%C%Qj_WoqTvp%R$!yBSS>6_^<(%G8OA!~w`n8{K^uJe
zFC^|#cjAJ@%dz#&O3oDEOvG at cI=_ZrP=s&d_9kdv1k*(!yOgA(YjGQGEWvGM-BWC$
zOT&D!>YamnJw9i?T6>R?lJg|F$eCvdh!Wb08K?r?S3xE|<?<^_#roV at UQarzvE}*5
zHitoVS&iz$P*>zqiIqBe%rNUc2vgBt<to4p*6*=6v(BK_ShuXfw^EAr4zF*+$9n72
zkl5d1sH(R<v4(F-C~$B-2fGNKKhvKJHAhXc(GaqphJ1WVOf|T{G{=j at wCg|k4o_DF
zUgXIiqrymV0MEA%W?6ImxY}sgjG*Yey%WonY{SOV+D}>y*s-?zUUe>7*ekC)?J(^y
z$gLC-*DB4|U1XFUAWh2-_5<4sbWgyl2CK<cN+E5XKvs)biM}S(zrBhE{)kExk6lvy
zcGN?nk<QZ`{h<*)_E)rzBF_b0GI&>03pg!sE#CfSlX4e1HCTXCo{3NSJ~-Xs1#NTf
ze!S44Xl?4Jcf+KlO03LAuI$Tr&C$14Xmsffx>yLfJ0OKT#hT;(wMH07)}c9WS!<*Y
zNSedFmfWn^%d}vkd`g3rzmwmiF$Fu1-V40{;@%5dNgMa}F<!PT6Ys$1&A%g_CO|To
zC8a)!3-tXpxImkT(7s?T?Mm~bxGrjYoOvwiD4;({8};WkNbunL=YESe4}lpJ70IaP
z(ayfO$jH->-hs^lMdUTyZae<|JzYgx$-d%o0CNBYNzxhsCq at mmG{<FYjNDmGJ+WKw
z;dB6N2TR|F4k0k+L2sx3ne%Joz|9~(yU{!T9xC%I;%r3w`hE+2 at 0ED6D^_1Oka5wP
zVrNT+fLG&Z(~rZ?kv_0zy2Q54?xF3M=gDgGu<u0H<_;Cw;6D%{g(;#kD?!bjiP*Mf
z5b}WsB;^U(*J at 1?S4SR*OGM$0E>ypsc*x8X5wEF>^u$e&sJa at _2G<>$@MbakereL&
zp~<zd+2H4O+;d8jH3DaP$Ge6oJ(5e*3M!zuvonR#a!$6aC?@Yz7^#JPc at 24&YteG^
zl%#z9vsGR5ALKro)ZZd!jmzoYsf3lTp&U at +F(bG82)eO@^%9)WP{9y9HU2E}N*AF<
z4ccAC&C^X3+cfFeS`H{tbpRk=Xu{`fsTY?KmcASoE%0SR=_N#?ZC=YUA4{^q)8fWS
zAwHPQ;e&TLawlA~7TspCn#EO<%nkZiOkaxWBbjw2{31tD&t3OmWf_<`R7ztVfm!<x
zeZgOTzLz=)9UxVOeaPH8#Xx8QHnGLYz1FZM;3QYALAPW`4ljO$oTntabN)kRg99+D
zyS#7;>XhMA=GoQq8r`_-VpaYsR%HsW(h;k2AmybxZTe#->GQy$NbBpiL|m}&Mhk0F
z^o>^3HT1?^AU!&r91WE{hjLD3jTs at cdgW%ov58LA`L^yB)QC!YTJe-|!34MROCuVI
z!JPkl3kga+_wTo3Oym%U{Z?k~hMbCoNf|<^3a=Aui~8qItP`HZ(A>pSCI;`(OE24k
z`skC~dXwGeJ<%E>HYl(bIMw=!go(AQf51}X^-_}w=Kop*EnWwT?fawOg{=v?za|*R
z at qX&%=3Ekg0(qdixYkx$?`8TL&`Z0b0~{UOt^x65dw|{|w*lyIKUA*jRmGx{Xr9_D
zarVixGfwFvEdvXag<y9S`)<9aCC(Jx!%ZgO!8}0Bd)(}xe9|bCEynp|`%$Wn-XI5v
z+D=j4d0NzJx1#zsimV;14lQTmw76aSf?1+cj>^LDEnIyvLH~At3)%*_b_9}vzTKIu
zY2Jdcn?3Wdz+AH-asi}m>`t2mX`<GkFjS;tb)r_&4(U6@>dpj_RYP at da|0yD+b4*u
z%AK*}_wpgLxu&|qBw}dITG8Bif7OGuEK6;p)&r5~a~Ae(Sy8>XC4o#UYT)EqDP~le
zYuv7ywFw?&j;S+ZcAJ~!PODJXVnEI&uH!qZ!z0YQdB-nP*m?ThpOyY=C3ZFe9&+Kq
z?P?aDEHQA^`^Y1#b`*_sg4Q56oYtynkkLKa&m80XF2wPyhVgtnHpa8N({PO4=4YIE
z52I6-i1Iki$e(a+-e09ctIQm^iSlV<aI`z*c>GoqkcVaXH*LkONK?#1a&?LBt__x0
zEs{2QkaY=VeE|Nd2m29!F^whN4zI8y^7PspDh=~STSG~1NM1F-+ at K|015c4eS3}XD
zj0Vj*2J1)~P2f`S%Ts3^+Mf0vwyY^qs4#Ysu>h$eMY3n at 59Qm{jD8#;6#&_qvz|I0
zOywGe3xKjp_p-(4_A(o(D`G?0iezq$?wY{zO@?5iYr=2fS1A1pB<7?oUWLyW7?BxE
zn}IJIlWw3ND}QrLfgd-dUb%`KW#)y at 8yOIqB6}~G2_GD(JVTnD|5^v&FXYHZhMaWn
zQ67;lvX3H8{C;F5<#QZbX(EkvH~}y_Iod$odpE07Q%|E4v!sW4R_nbhsYUnDkK<OJ
zn&e&Cvqf2r(1%~(N2-%ePY#YmKqGnnv^305ZJL8^0#M;+h#A}HFzIcHYer-ZMX>X*
zua!mp-Ei{DU5i%>@L&?zc2T*%pGUdN2pRK`PRF|@WRWO at J%WG@&OU-6qS}bgJ4GSC
zlFwCwkJCNa{r9pOp|F|)C75I1&Cqye{StoI4XL85dG)2P9l{g+(fq~LAUtJ&2iJ}@
zBjIKB#TcLN`!n>V=(uag+GFsr#)kR#qKm=lHryK1E%-NquU^-VpxtF%1+@!*s%5p|
zw;-SXzP>i{UH2Nr2B)j*f8<dikj|DT=d3{H>2k7#Qg0PWs5FYw2CDl`z)@gLfj9nn
zSZ-8n4$Jbi(O5)%19Gn82`8rLnYw)?Qu>)(^5V5q-E*2eB~oI;lx|OneZ|kq(#WMJ
zDTJn|FIu`4LZ5_QKwlq46RbGj<s;XV^O(Q~J~qf((wPhN_3A<D{oMs4JEY2{(IPox
z_PH9?ekpE2G$&PVD!gFl3F)fxsDth5j+AaM*dm~Ex$1hrd3Ydrlsv6H44Ahwfer%<
zCs`}DAC5l^YU0iU#b-PwD!H36(oI2wbbsS-P;oV52Rs$u2wb7Lan&Ly;Vr2y&N^uH
zuo}X{+*D(Ae=(y5(6MN)L7#5~NbQ05;gkrb>)04R_l1swcVXQCDl!)Xf>OmC*PpBQ
z7^?p%wVOqDQhMi>%Wr)Dg$7TGJ2WjB2)|eFMy$NuOMbGF;@prI)P!cIimXMtzpD73
zT^jmBSFCSA?lR3MxU1N-RIeggA_=0o1*41P7>iDb87)%5j?iqom|-aoO-m#nAminN
zbOXOCNs_p4bqNqT9<ETVr at L{f(pq%<fkU_MmdNWkG%7SR1==;BSG#P`sMhZ_YE;bg
zdtV;fL$fW5TPDGQpH<}!4eT?1V;?@pJ1u?q9Jib~zt8b*+4qaanC$y0Xe5_?4`9|8
zZvvzk6MA>&U)r62etiDr=g2>`JO7pO`LFAl{~W$A(#g#cs-xqT_Y~Bao`O&2I?f*b
z!h=pqM7h%#ybQ=JpE3&D0VMhn^~^PB2~Z`4`k at B)#aUI630S;ZMX_0Q$FFb29UmDk
zxoVduRFZnX;AfU2bl2acp2#v7dd~wZ0+wBOk%DojR^5nlAH^EffA7_QkK(USNjh;O
z3go?Pw_C}zxdsF>v??#qT^-|={-B6Q<&MEC`c)>O6se at zt?2_KcMcMT>#J&|=S1eN
zw(#*(kC9)TD)bv|O_&V?gGG|7?A#Y1es7BV9=S>Xo*aiafnR?uE>C?d4~)dqcGLiH
z{Ocxu<6-eBd3HdoE{ydaGDR8uSUm-LJqcu$92u_O6j$*B(TeS%l&BZKcz at G)m#bcK
zOw*KU7e&(4A#p{oj1^^ukU3U31~($~g1b-XF5GrwcZbdi_to#BaG#GWx+PY$2i#u!
z4fol}*wJwxVBF|Jn*ALe9cXYEe{`tN@~{^lxLJZ&(xD$6<GTw+c2uq!XC6!#a!9vT
za`Lm+6Pa3kU{#0PTvdrU-0i9=8s*NY(rWN&I6PGv$_^R%YXbaaR7JS$N@#X+WrAmX
z4XnNucbE)Ow!j`mT#EHMNCu4QX1Ax_-+~y^4am9;P-O$*aj)XFMEYqph%4PWLyJym
zJE%gAFg+QmA$REZ#P%!ALl9p^YgT+FOCMnwD!0G&;;#usLPG#WQd<T_KO#Z|9C?2W
zqDW{(w6W3SB8n7i5Gk5_qcZ)z@}ne!?)xMtsLenNL~rjS7fbTWm4 at Jjn`k<!Gf}iK
zZ6&U7z?0Kfp3|Rlr}`K4*4!Jf9{FGJYDxHII06GB<*+4?B8QU#Nm?V_t5jMn7+UoL
z`fIV_- at z6V9rqdIS5j_Gl~{PIk%UM)-RO2&{o`-A)u*!BE}~hmu(8%1x+BpSy2G;Y
z_-nujot%Z?AkS1-MwFw?l%%~MJT55;dOF#RGMx%b4n at e4v>ouF&-10H4cS~td1WOR
zU>9=%_Ty4ifL%z69N#mqg&gE+j`jB&4O<Wlinb<^>H at M$h2=)T!dkVfcIk-<xAW#Y
zx3e%EO<Qk{TrO<5#po6`Q~^P-;vz8v`P~_c&r*ojU~i_Ye}5Xqll7*Ggwm?u2kiPp
z5@(}IS|Q#vu<I>uwv*p9logtEFX~8=B4PdS%_L9HH9$6Yb0XdTDV{>4sp)nCjbjSk
ztTwBWDA<b1KC+h;8aWl-T|y+!s(PWhl_&|DTj=9CrHqe#%AX3!l5|#@FQZOuGaCc_
zi~HLv+ylOh41!lvz+T)xU9521zAP`n!HOi*mGEl|t=cQsnj~#!upu%fs|Bload;kx
zymYx^=n5NDqfAZ5xDW6)2x?KL9_UpEhB>ZweXz7%VoISdWB>YhT*h9^W$ZwJE`w9`
zkukst-chUH+2I~?3?$KLG at 8fffDi*0N^)ftUhklv*XQt3DY9e}9#*P6fhh0idC(9X
zAy?XKc~E339<sw*wShqlWWUH~BHJ$b+z_y;-se%cX?-*guVfyt<d-#pJbpow*{bow
zmP0UJO^Q50n=&(9HGGK$YkT;v<GPDHYzk_1CjU{><WbunKu-#%x`LzXts5TTa#77;
zzt5;EsLrP5=!SX`k9_J(@Pc~l6S171F9eGAL;2L{U@~b!)>{kpZ!Fgm+0us!XjB7~
ze522e>G=SqV7=9&?-sgx{z3I3PT9{o&@2uu+l=TI{v!0}pp09618{OXB^L1l8%beN
zbFy{AX!9<w`3Rg%nR2IfX}CmF&!EjTYK4|)VR~*yN#4dL&2i;I?iTwS1HTeV$NOlL
zp17S7XQkrh5 at HtB`;?}I)>uM!Cc1Ng#S|WULchuzojuPvIxsFf-xwGpY{(WiNJdxZ
z3P(m0)Ol?hG^luh#cTf1o3Sf+0;B3?rvyKcl<P0v)P=H4o6T$9M&H;hi;fa6LzFli
zQKA4S(SjbX2`5G_B%~NgB&-;*5?TyhpXd%Pv_;IJJ8hD(#txW{csoFI<c&Hf?Tbag
ziI!miWb{z|QSXiwK8cHd&Vw+pX{mq}z14>- at 1W_(4T^iL-OC!p?3BP&*|!=4R|p#h
z3mZhEt9ivx*x<iN6D!Q3`9slW#8kg|m#caC5sXooJv7*aUQ7MvPrVsOf?HtRN{(UI
zu%&?Uk68jk<YP&Jfm%~=*cRTkExc=6c-OXI*L)ct!*D}m?K734u|IC^M>A&;^hk)_
zj1PmYxHOiY<iP at buySA*k9Y<*0QVO``UKI)r$oz3(LG>)jw|qvLDvI0`L;j`tXelr
zW_Dm?kA?5xi9HrFQ9V-aS$+r?q;thJ)+x&GY3h-FxNTe2Dm)n2pK%uhsr<{+D91S9
znr0D7gD?e~($V2q9w`#-0hSxr-`#YY{g&_h2C<T|Y*%0nx-fn>+eNXGxXXmH0hIYk
z%nW4x2sn3Iwf at 1udXm?*3-C$jAJABnn$W75+a9AJLqZuEkhfWf`%#Uh48w_UMT`Q2
z`W~GB>)13)$okeo*lp8nA?rWsAu(iq6(2qUCexyIX?RB`pR}%a0L3G0bkDRe6hoy_
z`F&<Uv5`aU6Z~Fs5|`TQ3n5E|duZy^@={~-49aj2wOUFv#2TwFk_wtCN{8YZj5!X>
zgdFt|ARnwnGqFoH>{3!8Jo7G%rY at z;r;lc6bLV(iI~j6^790)ZFl0Jr{4{_ryVaAw
z*EIFuaU^$$t+Hmp;2jfDtClVoNx8TP at 7?dwjb!hrjml^qtU!58 at +J%<uA<ba-g-*~
zM|3(<)~XpLR$@02ksL4+b}mWp`I^%6H8cKI5%a~$ezY?k&&<S#QF&wlZ6^k<RRgAC
zWe4HXJX?2CRXWD+1ctB#ZOdD=;sx+iOOZ5wN5a}ht<`PpAJ;MqyxZcM7JX0Y^`6<|
zJ-&5qGxXLa>aD{p19<b2qRrFOc>8ul+vhfxFQA25eKv1iGKRkFMWCxBC22A8R<7#6
zgA$XYjlT<hl+BYE<E?KDTqNfhf`io&w2>Lsp#Ez+R>M+y<~Z}a?i{OYC<j(b=Y2GN
zFFniAo=-<$Q{f}Id?^VdvR41g^P>ZmcL}>>G^u~#Y24XdllnA&#cI^Y_%ruBX>IV5
zGxNYOc at qu;w(D}T)}{>Vt(aMPB!4R(Xsd$RbEdZjE<iVl=mi)1VpXrgeDc~3q&V0O
zwzw}t=u3S%(z07o&#))W9d7?^oX!)f3d2l^Sbma^4feTO0#~BTX|_Whe+DCiwFE|Z
z;pHDF3za8gtVG4S4c4a5)eL)YB6;emC7-DAe5cw;6S*f!8`S_Z3Z%qnqe1Fk`u-fg
zMlv>0AfmgkKmti&RfOyu?*bvD-i+7nY!A<HNk$xflfIABH_>}^AY!#qS$A?h1Z~t^
z_{6MFLnXDlP%9MD=3*M|WtQ|SNJk}-B+W4$QspEhyT~hRIBRToth#u0OvO6+GgO`^
z!5a|yF1w*#OvMSTFTpP2Q(Z{_ex}uxpd*rLP+<L3q|-_e*>VbPZ3fYRGDp99;tT-D
zJGg*8hqllNlxe|1fb%L54}@esC^R<ev!_tZOC<)4jfz|3xOg+X-J0X8+l>a6^d!`P
ziYBw}Fh*HEynf%@fM>~FBcps^Ad4jxATZXfImS}no#<f$&d65M`xuRB@=Ti+GDi~B
zH=ZHF3}~gTw;OvYljv*UVLo{X(56Us^}#)HQ%3mdawDgOyW?LmZ#LH!$fM(Xro`W-
z^0$2cb~S%n#NS5qw?h7w!rxZ%w*mCVXqQq#=Wi(C1-`o$?>8DaoqZ6}-%a8N^WMv8
zmKdkhkraobsd$zSK^ahP9D&|XedRZ(Le`{~j)~6VA9(TTECw>jm*q(eH8uG#Z0Eo*
zsHFtCLRUv%kURy$nn8|ZCu6gkJ%(!v`>3(q1bj>`!;&_6`2u$0h7dHz!!*?|A+`YG
zp+$2nqFLFgKEvH#aGo9Z#qGEU;5R=On?cR_01mXu(R6LS0I=>|G~H8fN7b(z5l)8|
zkZ8GZ<*sp;#MaDJEa^(GzGm8PBh7+~c_gN{Ph%xN+!k9iJVbqh`Uv at F>DGTi^iQf^
z<Q8IqRM6>WhcG~)mo=+Pfhu)lbitBSxW!fghv7LOv2wJf0vd1?#V2O%z)>Ek?y}_y
z8{StJFW1>xXv+n;<-zRS^3^$Yo{0vxGQ$`d2yfYSo*aW4U0nDN;O&}E at nkbGnHXfz
zf}lBv>`CW*@$X-w`^w~OPw)76krZL0CtV!5?X19hXt=@E^0qA?<t%yfYIK-{w2O5c
zkR(z;BSt|SSySuDstUJ}t`V~yDnWb&>*F(gK-4 at gP8Js!j^<n!iIsSAs9R+q<ww#a
z%k8mAj>-L25MfB+Bt_O-e8|+cZ+IhWm0bhuW{!Ny7)X~-nF0>A<#3c7Qs3Q2+(9Hw
zln<PVSVXzO<PK34kpwyEG at vt05l!85$C8F(SM+lmXv7)xmdoEfh<HlSEG}gA&NS&X
z33@$>-ANGwyni%pn3;5n4aa?U5xpta+b8qGvY#rh!`(sIhmFEvbr}Ma_-+}?iw{)$
zlY?&3eIJ5n;RR5`P*1dmr`lutYmd`ls7z}8$7Xa}LV-7Tst2Cx-Y4PNJY;(}E>$ll
z(!GNgmNG+7FTXfWezq<gCqKJg?d*X4^x-kI=6N2GfG;#$Vw`seV7v*zQF@~rPQ;oe
zLbIYcXfFRg%?8H=ypDDndg0jceBMSp+dO4eYrO85Ba_*{QgaU=MdU({{Q&ep2P)m6
zdu39t^RWbVM-46O!CI|rp0lv%5URBSgLM1Z{-awz(eEnHapwT!#XhkT6$Wtcf3G@=
zHLciX2qwVFhC{<p>>3{weabYWSe$JLTuav7lJX?(UD%YGYI}}aVk>{_DO_reXEop<
zY(UmgAUqozIa&+V7`W2dN#b^#DPqMWXW7x<G)eBr738lVHMdwB&wUyyb8~$dzn~V`
z#6SLy%iD-??+vIQ0+P=dgSot(^}L?>Lg~|-Va`?NPT_T_H&I1_>1S0^{V`Qy3f={k
z*q7a&TdD>6K`mDV^YmWx8fYBUfmBU!1ZEIQcVLL~QcWmD2j^a8p3|sp4_o?DPrRL=
zG-$omBIDfq^rWvdV>d(U4Z{fLd`X#>i&K(@a_<JCL9FCHPSJ at F$9;bxEq at ss9nCnS
z&x|Y2Xj&W-#g#LAxA}iQ>fTpz^4mD=M_5Xoo5&d{33OC(7^>`Rx+z-P*#R{&<ANqA
zi!57i#Ilv>E7V=S+TacWnwh at H$C93_<BHg*WBp9Mk)lDq$D97nX%u~oTMjvV%8Et6
z&^}ae<i at M-sV{SN#xg`>UN*?9+zB;as9yD3oW<iDQdyP6%mkSrcm&V40A)N>;+40j
zP(6O;*L_OeK+w__0W`lWQuJ#ykeCfLe7?L>L)3L4t8EpkjpkY;3vS3)r!ySb=?n0<
zy^!sMZ#MHz`nEvLV5sM{b^-j)lR_)<rO-pL3byl*k{FYL%AT|8BNg;{!P(yysLk~4
z at p8gn90L5$hyPM|c^8V+dwQ_m^#R8bxwGS)SC$;<;3CVCt74H34^YZ~oC|0~_xjNZ
z@?pF`*nR at nS~<#veM%*&dU~?HLINxoQUjFwN;@flQj`^x^PtDI7l>Co3f!&{P1f3k
z(kBt;Oqmv(<<7p(7?fZ_|F#|Gf-s*tdkC%lG?cp9+ at X;R-Jt>tDl3 at Xq0u;aHyL|+
z2ZuGRe%C^3ML-)4<;u5{W$4ASF|Y%?Q0K^JI8J$)x`qv7pQwZM#HS40xC6H4C$N;&
z4JYwNL?}}!^BiX;isva at UY>fWj+fa*-_SMyYRjbz=rMCMLJb)aWI7)2*;4|8yd|fp
zEml7}9Z8Us$xqHT@<#ZT8;q!%h at aJ$pQdgv at G%@b==)&K%zJrQ_J<$g8XFgq>bqEJ
zp$5FK-U{h{wD_g58*&j<V)e4^k at 08k?#A6XNWD|v!c>&YJ;7%_YnNJDj29%^aB0N3
z<Kyz+^!VkYyzWHa11-AA6R&mRmC?%-1FfDtzJf!zbSjSHrt$&eQRbixQ7ejM-D0I|
z;I~2De(dHUp2Enu*dzsO!500nmJ16PA()bF2rb at GpqG707c(%#QuUWs7$cXYj^`tq
z0Q2OMB5zU#b<+ at CIa{)-We$8+apOKsnf%HMGiF;vh9Xm$Wh0*hc$+g*ajyk}#WEde
zY5crE{d^TF8d<#1BO~45con||wY1cA$s8xu8u at Zt;8i?yr-W7xE(rrGO1$Q&A<IVf
zS*XavnnYPM31xWI3Jc3k(-WF*k=T>yJ&BcmT!e~n(=CBZB>hDSJ;8sq8d2lg{wJ+P
zA4Nt0y%8AZMGM(z#>e9Gi*kpR+tsq^$sT3FuTVS7$orWIJ%auCXtmLx6WIn48vdw<
z?TTJQjeUX6)rt6RlZN_qm)KBZ?$ve$k4el?HwpE+{eb038uLGOc)0|_ at l18-$zl_c
zs(&jc$4=8N&~4r}_82CG9!K*GQhrFlK?qH^%~ULFfv$MCii{+*<Qf2d8E(CNFP#rC
z(c8<AlAh<BgQ|+xhf+7fu!Y~DgE8sowJ4wQIrFj599Mp;HULj4pDSN|5{h}Nzk$t?
zc%52OMn||S&mh)&NLt_vEpg?C-#ydE(O&%iS-2Fo0Qbpmz4nS2Cat3V3x|3qFbe6o
zsRxieIGlwGqo78rJ^*XgZIi;6;^ktSTUlr%$CQI`6pFKbLYYWUD~;2HvTOLGX}(aF
zL9!}Gpo$Y)iFF8BC3>sWNQ>H+5fMsPBA(5538fEVQMyR?DWk@}i?}w?=|`#R2kORJ
zGTj_RTHt?3Mtv_8(2QbTi23AgDWX>Aa~)U%T<Laz`Qy6?^F8&I${2w?pm?>x#l_pA
z++|&RHJQp04Yi#kw|a%P;$65+GDWi1FL$SAs;`}*%^omeaGKA6Bn>1=S}ptvW$5q_
z&x-#TxY5BPVjiBLF-44U;1R-6<f}XmL-n4jk9NUST at rwm41dyb4`#yG7~)ZncJLOw
zjJMDa;S`ON*j#SxryikZ2ZmC!x&BP&NsgYZaP&o>*&2Y{4vd<0%{Cwugt8l<*<m+@
zMGpJ5^TfabD&+?jmOHI0GLVfN&FLwTeJBEGLA`%)Y<S10&7XGjFXvI- at v;v|W~p9*
zg~{V%kPOmaepJ&UoA5K;Pb3ZIoR0o|pj!GU52NKmamXl`WEppj>ttXkx>exZY-<2m
z&&y~k{;Lun=VNv3Beml+AHY;J?`5-XOtPrkz9hrIQOG5#mpw|k)q!FD`#<!%QxzUX
z0Tr4BPqPsjsQ=W4hvK+}YrEoU(E!q-<kvGAqrt}xyV=34HW<R?L)3rlk1@%A*h!;*
zFSh!Eqg=#A2-_HeE->Vl?ZhYY!O{e}C8o`DnK3FP3JxLu?l)XW)Djqh!!fLTI1Vn0
z4aeWUjd6%0E<(R1+hG>*!)L^kk|A+ARlm`I1klmI<uJr^vQVq*J++*nm5a%b)++iM
z5Inm=Nv%GUA<~bh at X8Neq{q1CB3N}_nA_{T3Gmxwx+n_z+ at +)1eqk~IpQX25NxBFo
zQ~gI6+1<1O*CJF|7YDpNk=}H1z%?$k_ma6hAO~JJ*qIJ)I^LvuzvTeG#tzFbAw<CU
zb-KUw0BV-^bd`>>T-b=4G5lFpBb+jsi1szddWo#u96qj at b-Ctv6jCPjTLuH1q@nPd
z at WdtyajcqS9(?6)FyidoS<*){(Q-(bjv}m4^)pS~-<fsOOwv`eUcSvpx at yg?0f9jj
ziq$T6T(tCiGz at -DGQ$^ll`SflwfBk}2S`1S(=~UGjv at 72Jgqv_7vhv@gwpSzb;>NW
zdUzW;sW9>jLrmDajWA!5Jo&rJ$p(EM-Ep5b;2k%aU at 7Aq&{py7Wb{F<SQl+4{0d7*
zy=t3&a+W0%aXs#0%vfo`BR4c*s2?ZqBhB$kH}HE(k at H)CGZt!SgD!Kjx3!k=mm^-c
z8TzJH)sv|U(8UQ{qfqXcw0t at yT#!JGcnzu$(FzR_q33OhReLkGOS?Oyj1Hun8*2Kl
zcM;YL#TRVD6XruaCLCOdA^I at x4W*cQ$}rdiM{1E%wWsqF<q&Xk;lCQ<iF;n{V63)x
z;_14$M4lAJq)k7f?|H}WsYZQQ2j)sBAiaTojH at cQVxU-VTbPp-7>rJ6pzF1!l9NBe
zkS_h2B4X#3|Hp}5&DE!pa45*S6pc;MjHrs>XpU#xSossQ6!0vX6XXghxLCN+XD`zP
zT|bpZRIRI_H4+%YUpMmcNRub;x(uzklQ-ewP?rGV!40|ZJ`;;a7fKp at gKm=>vm>Ql
zqHezc*J;uZvv5lkxw|b&tKgZkz=rz}zN(K5?k%dqxI?e<vnuJ|v&hDDqT6VQ*E0nE
zoNB(*&FygQ5<2BT<8LlDHucso?5X?3tgA%W)de+KNAW(AeNX$QB{0E@;TY?Ykx8eu
ziXP6)3*|{GCkJvC=3KEdkVU>C*oEjG=Od`+DiIaJ_DI#I%<cQTkHH at OkuuT-U^d7T
z`Sh$i%)PLJAUmA&w at Wz#f#8s<Y+AL17l}VAqLJJ;Vnl*(`}1>wOEzqZ)L-?z8xvrr
zNEu(K2K4<KO5kF<L>KB%MkG2F>dw-nBV8KwwcImyL}u1ebkg-b`;2>Y{`$k%Io7fb
zNC^_3u}l0wTToQq&6A0y1RiaBlz9<KcVH&h0im?ofYvRGOcI-5%SCI7GotWJz2ur;
zg16v9*z at mLHHM9~MQ+15cCZ0*1_e)ORk3cj+Rp0s+^yJc4^8}VDdQNb4O(mBx^B4=
z^Qthpp(`oQU1&mR3gY%Qq3o}mD!zXTYOV*oSchAkvW?c`dPr1H(fVJtN*&9wN}+o2
zgXkEL_$;O((!)2rr%WSv)?Xm#k&0wfHzZJ{+I9R?fn5TJ!~_FxNHCo{H25{obXd>y
zXP#+4zOwI-!G1zw{rnk6B-Z8KeFlBn7y1j1Vph*q9C{*}n{fgjs^Zu=2t-oC!l^k|
zFA_ at sg5y6mCvlPP#+^nd0b2-bd_oYRWOPZ at nz{W8Pu9^gO(;hxr!VJ0I1C=831|o2
z<b*-}VI{DH(8GnkoFyj=fiyr(C!i{$R!?EdL+%q8(2+g{RjJ?;sglRs(11>97Gx5J
zvLwrOcwSJyN7?v=`6H2~(2~gHSWCjo$dK`#69#{1d}JN~70OPb%uHKlYX3r+ZgSNN
zPXy3WRzX!a6rZa~kne<4zHVUuZcESwz7h%q3YvT&X9EmhgAJ;M0bd0W-8oB~D+56s
zyuU-Ktt6sU68o`_)nD~9#LzW<ub`pchDc0F?x$Y%4k3pdd7v3eoW9T<8Y`JUh6Z~D
z4;+K-*O77lAbF>zKEE4R&{&;y`0ENjm;<rq=imjJ1Z3umXL?G>mcSA6w<<arcc~Ba
zY~eqgA-q^EY_ubfyAaUOk5Wc8o`qUN?XEubY^`f15vn6BXV($k)!m5h7{~VlAiCm7
z36ld?!(T&Sd>ozwO5B<=sRy0|JklG*4Vk2)xPxc6;iuv_v-PaazG!n#94FQM|HpB#
z*4be|a$*$AX-zRKcLZ>1_(&X<`zRjEZBF0~L~j={5}HumKT(35y~qfwISFW0PYl&1
zz*{gNp at sf--1so-CnC3UWarBn-vim1Eob+C)7i+*U41sP^M$TNa<>q}Rw2HdsN*{f
z<qIT!wl8N~8KecSRF_v1UVA|8-}HaMYaCx4B)N at s>_m>Q>U^OwP;&;n28Z$- at A4ce
zdXATUgwZ;4Vi at gdi4DS~*Cl3b^A)H#vr{Cto1})j)CE;KImQyi;v%bIGRI<K_B^X0
z9*d!JORxcIem>_XW3ej&|1YrE_?#FPn{STCVvd~iVzHCGvDjmMVzI(_EY at YxvDj^W
zVzHO9qgX6}W4FYtUu8>*WKuU6V>s+){5s3rjl=Rx>LYX!5xj{mWtzMhA4=vq&O&$j
zSV^miA+fO&yOG$wUGYflz|uG*_QBF968mo-NbKMi9f`fpvxQMPNT=ms@{<rD+57+|
z)m?5>m+k7d`I!GU+I(<I&c_=484Y5EVOqJx2$XVZRltgB_D2y#4Jse3PQ-#_V6+|9
z>y9`d8k*y#93w9Bl3KF7OuNr*G6>W6M5|`jo84$BoaZ(f&KZl5s+v3wvLMm;y(sUZ
zE0aY_V at fMyU^txYJ<ah|HgG(XO_0^C{0SktU0;YSA_~)wh^`~JYI}-H;!r8Kc{&$-
z-LNu at z$u&sN!fqDH71)Gn`33uOoru`qN2?m&<wZoJa0hSvS}uY79~tSExJwztNxcp
zoVyL&LMO}z;1g`X>;H(2!IdbofmT>~E8f=}pInQr__N-Mqf at aJ$DtKJimo3~;q3fF
z(dXSCZw5JnIgARkK6a1}vyX6*UDiDs(Z;Nt8g0ys9*tQLYs?AJbt1SW{#LY>Urt8-
z#l|^4?Dltv_KWR%rB~4^H6ScpS78U{wX`KL|CNN`ac^bRUtzZ|L^y!`C>F1>`OG_{
z_7-o}Ztuts0;<IFI-uN*rEP)fx~sw*c)n79z64zu^2Y(CZNW{F;x=lv__vGxo}s^|
z>F+7}dy at Wk(%+6+3M3P-7w4eP37LvWu9~H-$7|1$XQj;LYBjm2G;}hmRg=1yWD8~c
zgW2kb4Y8xL8W2}*cCfdSOHcU=TK4B+=%l%7&Qe=2jb9&~oUa#ciPM3JY!@~RTnHE;
zOW07|=C-F<07YxHx!GBP=Y$PrVPj+ULEFFvS7$IuQl at E<t-{7?R|jH&S}2OoLfI0n
zk2awYZ=r^WsVba^h?#xr4c%_ at h8CxIL(9^=q1pBxKKuM^mCettVxq;%R%QD$+Wok|
z4#T2<Wg%C0_7*%Wc|$WB{Gn;hKzX>X732~`x8^EInOC34rgivSt-_<|FojJ!jnAYS
zAU|R;aMb|WWef~ubi0#@?s3ia$i52YA^5f?P_o)ku<XGD!7-9Nxee8T0vF at m0X(UD
z9;DNI5XbX~Z9ax%Hq*kLFHv1h>WjDHqZ=5}*%n^`ze*-2FJrvsPsk%LzsuGf&t(}6
z>PwJas{@kHjy*w|CY-}%#%~beE2d{1g`?G<QU6MMz?IdKGi3P$Nx8wsMCe=9(gbFN
zpXG^U&SrNFS(Xy{n$^HyFkihLj_H1ENqu6(>}FvcH;H}jx^~%IG at q*e(ju9^VAFnt
z5n7tVM{U_v=s?Blc4Y*v!Uxyl(}6Lv%Yb~%9Op{qdgH&1BD7s{!^ry0^`h1sZTiyx
zR`NTAdFZH%q8h{RGO1@&<FnR0$7?=i)a#c5a&ODp?`5auwKijLv{X>H`2~T-MoBD|
z6zfD}nUur^DI{o)xxXL<w$UhaueZymoJEaXD%eejvLYRa%&V0OYEix?JGY_M&;GvT
z67M?c>`rq+I~dR`8R+hMxcrFCh>@3Js`p>TMN<WfQ3Ny6fZayD-4CHq`z1(W&FsJ<
zbs#LSU_Z_A8s?`wO~EhwG)LPd6*NM>-o(OYAkv|0+Nkxvz+x!V+>OrL?togNUJb{D
z2fo&a96Uw${9UkjE0>E-uD=Gg*M_Li9Mv>sR+ at T6Bq~4J at pn8ePDy4|qR0WjUb*ND
zEO85~i>%r-2D3cU5j#)>_3mwP+EV%C#ZO&m;BE<c(cm~fOOD!1B3FhWikb3&rm3U5
z%eF<5yrFq#43U1S^8s{i!;<D*f-<CkLiZwaUz2u6PhX_y!+mmjI*!zSNuKlt>SCYh
zqT4DU)d#EZ&@q_!MK at mrV=2*;o#QO^vm4QB$<Gdm%p{?Y^xcR;*!vjlS(#U3LA{}g
z^YJ=yxSP$jkVAtnO|<t%)`-Q27P<xZ9uM$U7y4Ke5qCrp3`YkR&3#?XaJTQ>x<0++
zV*AP(SKjAJdgvCDVcC4Cpi@%Dt+)l(RlEG{2&uZuDlOIkts|i<PfE~&E_w3bE<`Ee
zC{&x*VC89zzzCqsGm^Lo9Z^KAo7zYMT0ag40!xNc6JRDUQbRR3IpoCg&+sUx8+7%g
zvsY<69Y9Tmc0TM%s=pc9c|T3exTc%2ou}k4p`9AEb3eB8jG at h)0^7#}%}vn)*U6LH
zFTmzr7T4V2eKZ%P{1@>CpMkC>nl)<iC)KeQAF1x6#d>4O{-d)C7|S}IOZ{`KV8jni
zzsi-Ah)us7eM=}w$<*{3bQxXUVMVvmz}Ddj2rcgikM>BaTBO%Br at IN_zYz;GaA9m;
zHbpn<%ht!f^j4p?`jiQOpKCJU2*K#gWLJOlE-oawC at awryjr=Tzbc at AOa49#j;1WT
zzONR;P_*wE-ZJu}=FUpwTd)?rZE68wCQJMV@(#6Yj(OvO?yc{&lh8DV-w57G^GH3u
zbZ%cghHC79t45`cHyX~u(fU0btcdqvJA4Djk#c7u?DJ*h^)r~j>cYtJpwIEs(2Fee
zu)1ZA2_r%}Wi3}w7+zWww9jCvt#qmVy at 4x}XU<@jR>^8W>rB at kL2iWfwrMt_Q1%)f
z*)SNBc$ZsIk)9GRk(8Oy!I^ahA)SG4Ws#Ahz(&m4G<}f%d=j~&qrrPHzvghkIAYa-
zME;%y?-2=mgqfz)!6zw{<x{LCX!y(wXlUh2Z2V^RMK)e)kNDUjm`0#UwsHR^2Uvae
z0jt}5fV|g4k^$4_V_nekn%O2pcmynDx9c0B3|;VP_2CF|miY!$NNrG`JC0UR+@)|}
z88Ev5^$95D4OyCH>x1x=?q!M1Qb{!*nCfN2>T+!`V3~Ef{RhYk648TbKGhKUxcXZw
zxfw2K>gB$iS*q&XHk%O`#@orTTX1)|*|(T^(?A at c)t%_kcbl%K7eGC|BGS{#jo#VC
z)^!j4(eFK3U%5jI)V3O%C~Wvt#2^}iXOFP?(4b}J;+ at 5%Evw)MhPWz&X2+p9`el&Q
z_}N>zMI&me$sMMkwRmT4#3px`gHXVxmg4P3K?k%@k~NGg_~kpe;V`zM+5wO5P<jLz
zFX+)GnB3x>M$SO%uHU^kb-R9NmWJ|qb{qZ{-($}%jy|ldhsKh<Ym<5u-RjiG6d`*?
zTg;ss at 9L2Va}4Qx?*RSs&(oTvDZj^n?0!Ji1wVvVSB6%<9a>!_pSoUnVjhM>KjpJv
zNOZgjQm)tJj)B7CZc at 3?h6s;OM7!962N#L*8JF<*74#M?6y+{>yV!)vwzn8Pt{UNq
z!DMiqv at I3*C33vuX1;%)W{Lk6GaAwT(cMueWIY_yT!fxy&T>IEl6yNlhgTY*?62 at E
zcbSB;^`yViktRI#H16x#>59|%lc9__FO;ASAgnQa%!kz1H=tgQzfzsKnXB26-I(Hk
zTYW%JI7~#Dze)}13EOZBk&iiXGYtkXBO<GDhwl9<bjPRe(CTJ)=)qm?P_Ti!pJO%L
z16^Zvc!b;B$bI#QtV(wV)YJc*&v*<eMOnQbF(r3HCz+eQ1>4BmjRzQv#GAazq$W6t
zCwa|h at JBLtz~p+(UGnOc#*k-EU?@Cj!C~_1N(1_I^EarYHgMm_Qi1<%$=r$YQ)k6r
zVWLWA&fk08Yht3auS5Y8)yB<HR*+61VC3-f at soVI9$XpcHt>$xo_u^aJ})`4j$i5`
zD{}7`qk-e62O5BgY5NX2wl>snLkbJ`>|!ok{0c7x31PGMLP<6F=4xIBXM9b6NuJTJ
zEv%oa83wpROU>|frC~tb)T{7qy1RVoG}u3X#R76ozNE}(kK+A?rQ2E3%30*gGvK^i
zD81UqH7Xa8_-!<u9qC&PHe at drS^Va&b5aCfifgB!JWf5Bd<zt&)*}Hn at jI@CvWPiG
zA~dC(z=RUaAB7x)slnCDL`lix4KBX>%Hkf4&KwZe;Doaq+sGU{{U#EHx;`i>kMv_{
zTl^@@=qlU4rU;{sYk@`h(-pW&Z1Wh5f!pxM#?`7c$KOX2>*A3Lj-h{cC`yN!#J0;{
z>qqj at e93%8HFq`YF^Cl&+ywS=j}6ZGQQX at 7el+~?Bx?0uZM#?AW^<h?D)q2$yzFy{
zO`bySo8;00gYl;;Fre7yvK5ERP?`(qTB~!rY$fe`Dv{nA-Y8d}K!qiDgXZ|_NF%9_
z;WfD*M^Pew&}{@Y;1V`eNueuTh`ST8%G}5R#NJkXw!u<zMGxlxI(ai|&d@=a7)he+
zQoY61MH=$8`J%Q>DmjHpe!>$H25?9UpkbfmZYQc~;2rupVyel#A2865kn?1IGM#<b
zqNL4$(pz(B5s>oIwGu23n6pTlyf)Dg7ywK&oJq+}?4TKDFF!h^9ZNq)Wu%HbVvL;)
z8N13p?=;A%zdfq9wO6f5!~h at ae_!Luz-Yy*=H7=jRb>K66GZv_h3a^ovH(+75TmMD
zrvj(hJ}m`xY=Q;A0au{fbwLNLoYRJ2#wJvhQNKH^X+Ra6#$A{qDbv!W&@|Y at W>V=7
zO>>5(*&;(>S)Hz*=EMT^(`@)7g=Rvofh99jOoI)E?rVA8p(5TPF5^QtQzWWwpPE8N
z**?_Y+M#|j2#&CV6b*KhT;MeDktwi8V+C{hZrjup;PUt2t<taThM-l{43SaV4BN^i
ziJ8h_7)`>4>WB>^WHUR(YzbQWn<FO89JSvmYgyy#iyuNRjJ2|TxfNmVW;*x(qwP)L
zo2s(F;iT!3ZoDECi-1%uTB&HYs4Xd)Kq4=a2nuLb&}yN=h|0i=pt7_km8Q=qF5@!e
zf-}zinQ>Gcl}&{%(uK7YfdZoxM7{Be7LYD1ecw6fzPzLXoSFakef)kj_uYHmeRn<g
zoO91owN>5BDqx{_Z&sz)iv3G|I4{3)et%ngu~HPFvZbG at YR4@ZR=b=jC5zt0(EM1V
zMVY`J{gkME<(ewDf$UIrtJ_&BE?RY?*P;Sn?LvtB;hw&{_ at kTI&&Z0ZOSZCWsmS0l
zvnxI&g5|dyY>8ep-8RbBE<G*cgO(OnV>-g`Mo7;(m+M(KbA6;1V at S`s(a5y|_oBl6
zOp%0$K>0Mg<)f(dW|tXiFWbrOK2ncUNke(vorvpOP{eo@`~4 at ni1EI6$svzDf7)v#
z(OafT^zblP4(B^iyBL+n6-ZsVzDE@*{%qiClpiFLLh2ykO)d3OHU`(Z%vAy#I<*qu
z&^v{<Z77m#?uV<3+$LXBW|hgHB)Met=rjXBY#rA8C7x_}`C@!|AjS8I<X4=gmuv8)
zjxqUVQV#p#W4+D)_{+K53=GPVc+ at 6pLCmn#UUh{7iH6BpR{UeP$t^Dbl;sZJVZrwi
zT|ZA-WBbfN`qT}gf6+<@$_HPK=h(BYuxS1TPGS9*V}$k3nyrU`>O3f55c^H2$BQzZ
z{*6%da#ArA)trolFBHj}Dp~|zAq<<^B>2Xg`R{S<`Cr=apS9oLX}=}$^jpyvzYHJr
zc1;(aM<2g}507JSmrd|pi!@u;Si!fAh-!!68%jCj1m6HkOp<1MyNU$gc6z!;y3pJ8
zfZ&U#rxL-3N*Tdnv50Boo!)xX1eLB4W!OFy`=!f;4e;T0-zCqx;B}y!(PZ9`Q at f)p
z*iNoNCTC3yevkKX@(>@;sln}N(9^jw7rF<yKv;Jq*(qOaxAfTL26QmLM6lQ3CjcbP
zjGZ6{{1y8{HH(6Mh`ldzr<;QZ4QEvqep9-_A*{ZwOAJgQCroy?T*uVE)BKX3Z&=!d
z^8{PfEnV<r$EQl9-=<Xu3!ssZw}A93%U~yZw_35lCLhPULjToBqi;Zs{NPL)<Qc-V
zaVAVWw0NhtYnI^qg+}^OSSyrxOz^!%i8)e<w`-o at OF$&m<>AUW-mV2g#YU)T%@x?B
z+to%ObNWhV^oIgiy<N=NEbi!5GI?09A%$twe<ew6wCDE)qEW2 at sAD;sVN2VCi>PgA
zi-toYtijt4+}bvZ_~Gy!d7?P>_Ii7kE7umd{aB?v%dJeZ(cLhX*&WG>a<fyu35Sv$
z`<pgkg6}{a85&q^9UC*HxKe+D65~$@jbiX_oK+Yk9>qhRoF%R?l)>~@Fe%Z^7mYFs
zS4qm;cA6xtWgz;ro&!m%l;9RN+|s2ChB<?ubjpi&mq0q!A>Yy!226EVR6k*McD7>Y
z%uv54iC1fK$ki}6Pnc~aHBpjn-tRgcmQxO4!YMnT)nfEJ8h8^6#m?42O_yy#@3=OM
z1Gl}RX-OOg$I8SAf7MRdo}EWsa&=%#uD7dTvB_qtM|WbIl^rg!QVUdIEje|fTIWa8
ziwXti(@1jv#4<}RH(~^M6$<N3xj_XUJ$-Ctryuf+)>?PH)-qeUis6D553>a}Od~D-
z?Q96Tdh$D#i^LGft#YRlZ`<$}B6Q+KIkln>%4A^-h4rV!k`4e}qo%JJjA19-Wp-e7
z(Z*eNWi4>Y^;(1rpi_3*ku^}8ZStA&A5fD(8U(|Irn#xEK1fqNPBly^BUL?W>_u96
z7M0%_Szcxt;W5(`;5`AxwKz;C1dfNjU~<+}q2d-~z;Md0#R)RcOTaZZ0_LS-qftu3
zha4IUWaX8<kQ*ZrNT$N at 0JO`~vnG?s!Jac6D$V%;KvFyxppK>0g<gce`Y4kf?Bs?*
z6y3vxD&~9GCBSe4tXax{zp=gF$YmeG8&JPJuetzGiZrW2T|7gSkK2XSeZ;^YsyTPL
zf}7i at +eL4E3~T(WwhKHt@{|=7Em9W7aha)oH-PW3e|A#;VZ=VAMk~YU#|9 at MTJl<z
zi$cxdH*5<zydAd`oE$)XKwG7YdiTy00R$)2a?KH6Ba4}YGG}}>k4_~~UbGU<TG)3*
z{7iyl@}|{2Djs5RU{&1Rjn-vT=)iL?)9&+t#TDg1qh>O-;Z|-km1!cAspcq?DOeCr
z=|=cFQ_6<Fv!zt{JKysbp<U(GvYTgnlHef3#}uU!P(hmVH2lpBJ^_fXDuGZ@;SHYt
zWlM}BJ$=xp9c2aYf#SkE%D+y}KOqFiVE%N$Hwu3NpI(Q*fJKMnFQCm!@ppmXy9j^b
z<hlTP2s}k`iQ0r!Tj=CrBW|E=c?sT4%_N0hTh$g;aze$Sf%ejI9&6;5dtrbvC&J?!
z{2O|dE;~Kkli}cKk&b|OdJv>1_&WTK4Ww+qv)3M2C^iR|qB*5}GPor4-XI&tfJj*Z
zD)nRJD;S&D&Q?W$k4z4vl;PU}yV#5%!CUx?nUW3uUIzQ8>~xNFDf}HF^@G2;LPZv@
z!5kc<RTaE|CyYVze+@&M5LC&>%hs4+#~D603-HfW{4*K<hz>M~=;23n3x-yD^&dKw
z<ohGuFXlU53-0OA;-+MCWvsbjp!@&G{R^06+hARnzLz{u^iNFFWy6_nIp~(#D9r59
zybikdrf80y3^q7iYa*{TxSy_+059{1kN-xFW8l3Q=y4nddVEIHba{|Y(sKrSy!WQ)
zK#zYnYk?k at n?r#fZ at B4y3G~>H&Ha10|F6TRx2Y8!o@{K1;TZbh#z0TSq%HLoMH$_V
z2C;i!%YS-|uC=zapJ35*b-3O_#mulBL_S&myU`}976Y*aQZM`!Cg`o6P~e+$!i<AM
zf<5`$Fi))nm^-6jC_a at 2@WF9X5uzAf=Y#p?&!l$G`uqmW1uHqsk7sn4-uCNxYG8tq
zS>WJU7P#MpwxX6Hi4$TBi)M%=$AM}2?k18 at v{R_kl=co=hF3~s-`>xsJ6>&|tAkVh
z7ha2gbx0*Qr5#A7Ts8fU{>Z_n{)J~AWi4(pXL;!+JUO$D8`L`GdG7q=jYGWzyqcx^
zS+WD!mVu(Ky;-Kh7|+d}whSaor5ogeoF~%Y1R25pjdo4)q%^zS0Qh-#uEAhw at CfqQ
z3}5vVg17CAe{6=5;2ocli5CF!_%v^c*??;RB?lo_*CF1tx4&K<t8OGV_8|(JD8=EP
z%j_JRVX#6Y((yQ%hH~mgwrYa`FM_JW3iju^r=iie%R$(JYTz~_TXP66WcFjwAU+FT
zcZ@*@Ad%oI`4$Ej{dU~yEo?JLGjEmqw*g1*mF|PD{&E+s=r{|O%PDO%MR_)KxNrfx
z0Uak>8l=nAdiZ>nG6?Tb1^`G5%;G>^XcO!zGz)f5dS at Zl(f<%sn^6R%b-_7mC~{n9
z8)C9EM#0|0=c>2<3MxcS)9y^uD5%?A5d)aOx_U5T9Q*oCYVBtBMi0i7qgbAIg=Rk_
zzo8EX>v^oGkS|yscfv1*>fI#D``C{s;ob2WVo7^P&C|f~-}Bed%^yuOATX3scGLjP
z%5I`EQhqy>r*_mBrGfsZ%pEmpg3nKAY;2nMV2|iG`NwC#nt?KJ+b`b67+5ubC*jXE
zOqikzjHEuyI3+ABN=Ccx*SX6L>{MK}0fj~+HS-0K9M8d(ne%X(7#L%OkH}-Q)JFeU
zbH$Ox1MTugc>VIL0jf*6%iEL*EePI>D78nGF7x*ENEf3|2w19t^ppZ*V>K4LsYo=X
z)S`uY>SPmOP at 6eZx-hRr-ewPsiD7S|mKOzR`h|QKj8ChwXXREJl>uLH1<1)jqHcqa
zv-d{er!8lI0Rl*26&cCne8{uITQc+hbLdVx<)frywokMqd8WGy%%0JroV*UjUhHo4
zP30$5dX%n>M^P~>n%xcDRu^p#1?DP5tT4!J+VAoY!bp7Rl#RQ>U|D;)gt!)Kk&{vR
z!k-+iJ`%c5Mwv_*8p(xZUc!0`>@GZsF=xF84|szKaEv)NQvi7Gy9v%y)k*Pyjl!xl
z^3!fq5?H1MhNGF(0J1}NKs-F&)9XV9YiH?i9~0$nH38Kf|B6D=R>Y4f!m37g-&1t?
z`t3P1!p|WyD&sPvGA=WE>lb6l(J{%4T!BZ at Tz>Z&w9=OkVO)`ks6V;@71v3Y)Zkco
z9~uKXe5HOzB}tG9QTa22-TY_$$h_)Bez at 0@>+vS(Tf{nm6s(?w?6pn`K^kX7i at wyi
zZiq1;{uqKMa)zs<`Yf?fY?ESw<A%$Eh9PX|^gc@%)W3!VK^g3mcl4&b^8(&&HUupK
z(fo~Q-MnKg<W<FH<?XMWnpI$zkHavHw95+o%<%yid>W%!1s*oy;2NJKY&_ACbHZUd
z0i$n+DH+KyO1RvLtr>t&`=6jG_!{pdH?uE3HyGTe?=Y-+7OUn(zYwQ at jwvPvuZQ|S
z8fME+$r36)Per|ISC&!mEl1-r*boy*wFDY7wQ_P+e&w_>NMbm|VrVHexCs7R;eW2R
z>Uia}751uc<x?)xkMOl=c=28~pLFcd at yOUf>?#bIYMc!32BfjgN~!nMaL&ehPu(I-
z@}6=EzPAyXopK32nG&~2h2B#$rE91W-cz%sB=4#D(xBibl9DVk&h{ib)s3c;F27@$
zGQa>Ww8tD$QtgI?S^18bALz9z;7zT*4#77aRw}Z7fWr%M9Zj at XJyM1vX!kV<6)(|7
zbF2a8mhn)Ske01o$QLV%s3xpmS!t_s7=f=C;0(B9$_hq$QeAS8ih~m8Ec)`2>pW&C
z2`(VELi)OJmbAC<F=<!f0%=EKk+gLkH{o|IGo7@?91EhKLTo8z$84&EWbhVJ83!f|
zQHiap6<7yPT3P-i$y}B{)=~9?$7HWMWEWQD+PvE`?S4<S&D-;+G#mbwNMqpdQ&J&k
zXW`FCTrH+!tmBjx;j|FfOJ7_s at 4+N#{?0smX+_y(Pqoq?9Yf57=^DvuB3=Rni;mo|
ztuV6~*AQyAWB6q>hCi81CiagB&tHbu%sw>M!uANhA4p!)0}R%`QOfq*wXyX4(BfO*
z?=0yuY`ah~D3)YCBVk5-o04z|!Wy;9?ZJ*DbPzDzpt+Fqsw0GoE8`3X7$|FS82Q<5
zU9XjR$i?mg`5S9xz7pqEb39k#Ql5znzMTfcDQ~ssd~Y{(u<uWXx`tg*1cK3^0kERl
zDy-V>5bQrFlWp>s at DlWN5>;;mrrZ^9r&%itO=7^|6HVVBH at 5)T!IkJWlUz}J)=f9W
zzCVz&k*)YeN&h0 at ONn;mUtsA0I;iCCOO4b=YgMjwR4438T<rMmgIE)pm6(pAE$na%
z(uUzl at v|EC!<JbqM^cNp=AG#qY7yCZ!<M{KYZ1D##=iaE_3PU%UdtB-y<cy1NA~NP
zd7*x7gK>1>+CU!<UUi0)=v5s;#RJC3UQN<2R~P90sgE_y5KVij1(9E#MPHWC7}%!P
zv&;3bdb>t=7WS?~?*i&ZN7ON_OG8VZNqPI}h%IpV(9?h`YXQp`gM^|gR4huQwKxZ<
zoT|xL1-=%^WS6`0r?m;b8_>&w>~7Tr8^Oy at B9D;cL2Gj870n-Y%@gO4+mycAj4kL2
zwU&ndu3n%LS&uC+9o0vlcmM3spV7%jAE_p794_vP9DVa#8vW&Kc;)T1tD#ep;FNa(
zKe%F*b^(W at 08@kB1MT at h2zlTHnytmqwpYgH3G0b4N|jF<Vb!smR at 7&jqo#jmMs{b)
za%gHJN|-jQ&9qg6x1o;3XBsw1v6+rzaIa!SvVgq^M0hR+Q9;%5;2F|8>6s(={>72O
zJi)h(=XnI*r#x?g;7h_F--ym`qzd40iOsS!2o(YN7ETQ9R9noRN}MD><(uLWakv at M
z4#6+rLH4W&eVuv at gWn-cXm^>~Y-NR6_j$}t^-Fstu*4Vwz}*h?WF~v(S`>*CW=-S0
z5h|ABHvDv&+w^U{<5Xr4Rj43cIKuOY!*@iQX{$=fD(jvm-4B`eQNej}_Npc&-chyH
zUKMn}^A!$Z)h=lIRyWWO@=ou;1ZNF1IbxKSLvGW~G3Lo}?Ep6SYXGSM&>DnkBbchj
zmP5S!x+BUEirrAf;4c&dP%j81Bnqbq6(!{KepH>{yBK)k;LEi0ay$caj^a%4aPlE9
zQB`|!%17ep%=D_co=J97&?#@hi5|%sPK1^fioQ at m4n<!<gSLF2z{Th21HPE-1%O4R
zq?~sAjwdFj)wcdIT!N_bhqw8 at Z|Gviv&^?&sQ3)8Yv9{<q!MTHdeTjyHIZ!M2#Q%A
z({?MM5R-PiR2;@j5H(*2OvMUozBdKawc2=3B0CXtf-2BXuz+X`_D9)W4x?h+7D-O|
zE7%q<d~7gm$mKl&N}-Vaq;R)180OjZGq3Mozed!@dn|Z=j=?V5EFFtXwwP~h>lYwJ
zfPVLcRpHgg*OE<`a9lCLq6B;c=km1WHo8cmmJA at VAhab8+Jfc$6&faeeEZnsjgA}z
zM}&OtnCNvnuUY!9A$2u=ShpMa2`t%hgL(RS)x?E>fm4O&cGGE@>B+&pB~&yJ0n{Mx
z0UFliJ(M7<cg3{}>+P^B8il{?5WIiWrWo-A7lr{@B|VIDWUXBE8hh#zl6>~1cBpWO
zGyic_t#rJ;2E)`MrT`@N8dB<X*ah5`u97n3HCe^SM0+i_3#+G9Vy8>(7~r@%28k~|
z06~?wy3iw>>`qf1(PoJ}$7$M+ZwB|FG?I_ml~ehcUJx47k3I?^C$g0S%F5Cz_`16_
z<R?`89(CM|KzZYc5n2&^===#gnh1?D1Rq6+N<*+TMqAZuLv)<obP$M<d?hKIjkHKS
zQYZ?Hc#cqU5)c{Rf}Ui&YN^^A`~k9z`s5WIi&$B~%_!jsj9ev}I+Rf`%$>k)4R|C(
zQJ0D}GnU25+pNO+1MI at tI69tX@+t2R2cX>h3$cHva2W)~H4}LUq?`-Ij3(foJj?h>
zinHhZDBVE&4=Ft)5WYGZ+Va6!=z>>Un5n?5V9bG)+TcMAFlJW4hd#8#&Tp{J;4$R=
zrL3vAyZ0KRceiu{?rbTScJ+*h^<Di3zC<7M^r0P%D+ at NXA_B({7->+fTGt274t4z@
zI47s_p4YUYN3*GH091!xmQP{te>f010EDUn(oM}qKvyvOQ}w>HP~Yvm at 2%~6-^Z(G
z^?mM#)OY+0^<9eZ{06I&ITpOdCfKPzD>_4`=}_1PbFi^W9IXl<8I}VYL??NUWx#%G
z<Snc-B_o{1ck`uK;Lc4LqJnO9NQhxK%+4wRW{x;F<w0cHfB^#Xz?g4#3HG)~rZ83S
z3Z0jsxA5G2)}Ue5rXk#Y6!P(3|AJC{U=nr6Mvv2mnk9G&4ihR`I`BYTm}LYqy}l#F
zv?7bT4xWNjk8-lf_m2)-ihRRa;aCX1-oeFkNyv~kva2AE0Luw*x3Y(xJp2h>O2(H;
zJMgjtXbm8@=nkn>zeC!Hk#@8 at q^ENE9a1xQyH^%<hx9+lZ(gteFXT7R4nM#AW_rVa
zFTd#}v$=QX|17haedYONHrxLBzsqd?G3)<cX7l6Mkun=cUPpw`20!VaoHd7pHZJ)f
z3T=wT2FD5%+5o>=2^iH=X2T012 at X=ki(GnBzDyUHJX*%3Hy@{+Exp<I9Z7G-{eo^+
zQ`@rs|B&8vJg+z9+a+9jlbuG=n`V^W^t%q&_V~Oed!+<)C~iD?FN&scTl_4b<YpF0
zZpO`wl-v+yf}3=3Z^_LiGr8mjsgcdh^d6pSCxlgfn3)$GMI2F#b2=w)fAH at lxykP%
zRNMfm{M(FzZ)hJ}s!$vywedl+2*cglWkvK)tFD}yHMy7M=3Py4a|}?x#qjNh8FVFs
zx4&Zp_V*38!0jlxnP?Bp{{KR9vzSY6>QQpz{;wrBE-tx&?%At6KBUFOD9O#rD9O!h
zQIeZmG|A0vA<50rXvxiOA<50r|0KC_|3}G<`!yHf!8x|7y(qc4z*aVDl9UL4b=eKj
z`NQ$b+U|b at mg<>DrQgF}lHHuqWH-e`(UR=uNA~mCvYTIK^pf4oM%m3Hja+t9OtPD`
zy=6D(pnzJ%1vpKJ<xu1u65y1i7!1B9&je~n3jCdiu|Cf{g_zQ at QnN8Nlfg22n+lIO
z4Y>O?NLGuMTH)!DDa1Wb#P2AHuF%U+*JHx-b`lQVlt|AdK=l)^cV at ca8=i>5p*#5V
zLyI4Wzq6zw92}vdFcv8a<n`owXye70cEQo`ngd&IreJDxtZD);SSYk%A`Va3PkH-k
z0|oCuQPmgIL&Bsi6edm1vIa9rn6wvZw^U-t;k?iVN!chGDyFkMEJ!+pg0<UE(vIOn
z&E-g<28>5~fh%ibNR-58J&5Mh%6+}re@*=2$|~wD0H_QJ09NP%fGkaj^8yzup#We<
zH?kUy{QE57K|&aB!GJWMN368Amssh&uvlqn_iu`oD!DWz+?ZE2Sx~GdQDRjOXxC`y
zXd?6p$@SlN&!N@$FN5B_W0CR=<qf=y!%3ghOQ!T-FPYNh-;gO)_WIr~lBY<wXy1CK
zD^jMk_?$AOvqs?ssDr#MP0 at I@!`?-e#*k2{?ix*~^fxY4ni(ZjvgglWg72+vk}9=@
zq)N|qbE(o57=`@Hb$qEDLZOmfKB)91!P_ymr}HeKQW!KOR5}(O^nIcJ^MMa_pt*w&
z`slDwX;EjSQ0e3Qe_N<D>0Mo@)P!^Mu^AoUxR9@!LwD5 at Oh0tpUYVlHmGYR;kkhKB
zKiq+HHRUyEWwRzv3R+In_mWJ<@a6|TCZg`lbElCXt2!3!BuUYkIfCyn#}@Mh-&Z`(
zBlr&Syaj^qVv-&KLLC8T8 at gGkSbaXZ(J7L*uL+X8+w(4bj!TM;xlAp9x9 at WyHRDNj
zs<kLBnoN%oBBMu#B6SFPA8SG*TmD6!Bzx6yw`nKJjL@%ZRSZgH-X-DD&cYF%ryRgq
zK5nZ at 8nsz^46>+B`>3P3{AioK>Zk*ruY$v3H}qgzl>F#;r2OdU+^_kO^BY2>ye3E0
zQF2GaMM>@F79|DIQLH0BN$_2D28RV|4f=FB(lMNlC^^zT8c)KwBu9c3q!T)Mz2rzo
zG&$0D5ptv=K3o6b>xb~ACPxxUj`RhWBLT)IY=1gJj<naL@#17O$m_{7g;vLvAvx0V
zsTxfq_yQ*FB&tAJBypWjhU7?jChe4=p1=mvJMrkR5hy;GK{BN9F3 at C1?ss$<QWMFL
z(29hgKqNytq21X<*2R0P$&f^w<pj!*zP5cqG9)vXA>nF-m56eqcV%MLr at h8KJlJxY
zVRpjOqhe at 9!*bGz9myeF@{DRa&`s`~HhYznHCZ3xbU;s{Tw}{=MCDW*o27&{fqbx;
zs9rYzcyEbP4?o6Bq_Mc^A|*<PHHp%2+;2j~u5(G0Y{L3_O`!CtHrE_SpcH`oYmJQM
z0+&ZM$<lImi4c}76_aG?+hZtMdM6}VY6f(+ywvX~qw_A{E(=MPa^4}L;5C#imEnMd
zBuji?kVJ$b2_E6XC2c at SxKs`KL_sEMel$$2_<nFBY2itsp>;&8fD1yS?|d6WNNA`K
z>m at nUVUjaZUyBj3qEy7x>L=j{5<%lTF>*(Tlm=}y2S;~m-%-}vE6u^HwMQ2c^hkWd
z!bG70<Zvm|WL?UHia~sXYEq_s!6w4LA(HTKM<dtq`{$4{t-L2h{`ZnHeROv(DO1yV
zq)bJTQYKtvac~rINlS4^%5-U1$~69LDU<mvZRk+S<oeH2rpUdIQl>K at DU({H at A*Gy
z)aQSYGJSe?sO#sDGOa8MOPQK}L&{XdrA%7i+d_TUq)eCprj#k=P3k+BGP!z5nGi>!
zl&OaL)2T0~6m(PoCo48MsQjue94yS268y&CQOGKV-yr<v_W_zDaEmeDEDHAaNM`i;
zU&5z-JP^u6CgXXzHzY55J(>35AoQyAz%PiF`si?t+|~vqM*Yfe8YWbn0D1x#J)ql_
z4rG#%B|eCfqMzC|NzqPCQiNM(z#D+-Y9RyA+~RoH0f~yqUYW=qFAMqW2);{lBo!k@
z@^=pX2`PAD-~v#_ZY{&9JIuiy@=qbD?PbB=qco}Vvf!+cC<<|PBYWphnkdTIfi%xo
zbSgUJVDP36uKwk at f}L2R3jhv1h9f?Mkvu9yq#-e<WZ-7bYsz<1nWHTnrZ_CBY98{N
zqN-kgMY^GPjbEU`RhKH=Ey{7G{xOENF@#=?o<yr}4F-eqBw4yWLprR*M(INK`WG6}
zEy}IzS$x-0CtVEnlwlgpC9nC3*u*3?Jrz=Ns}h6Z_t+<&Bh_+1vskyGGl)R?OZ`ZX
zag+Pu{Y7Ky?E}q*iv1EgSGar$SHRT`_rh`_RD(lNk>+Cp143u8-HW-GiVqftbk&08
zNHjDpm|+<*5WX^R8oGXwkE1UUS76vhkcFN_9#+v@{#Q6M^3C3ZM(IZQ_HgLQGR*C;
z=bMdEGRi4Pu}<m3Zqw`cZdak;Z(pFEoid0`(Hby92VfUHN`2sJePs1^|9!gcpe at 5I
z%6p|tAz?<FLuVR`&r;R$l8nw%6nBmyex;#z`mjIY=$IqT->K at F+(GcIlR)^3aFWPz
z)tf?+vdoJNhCEnj?JoJpOBQC?VXz$Nup+NI_#N7LRkV19vNsp0>LvN?@kRRbD|v*A
z!fNPx^OQ^eRt&`b*cT%$pN4t+VJIp at lIYeAqi3s<gnSHiQ*4dtur~Kt%X(rkh*S@(
zAK;%mn^zd6KiWF%f;m%4&1;c2lNQ~ESIA+;!rybcZWEdL$5r%2P083c08cQN0cDTw
zr;DD$J4V#2n+hCewSge-1;~QC`(sO-a*80lT&JdA803|qnGmd^L=x#>#CA137K&g5
zV5+}H{7RIao8Pwx6-aGXCFfO_btefgSL0P9eBfjnDQ&jdybCX!Xpk_h`-QGbSJneu
z3R{V0N8agBgbgcJoM_~ED4x(3FzfYVPMy=VQA7{u&%JNthUV5#EUKMM`XiZx0_TZk
zYMnAzqZ8zv1j#0a0Fd*>SPuF0Hy5w!reesLVy at 9oJ29`N!Jd^JXP~My?^^qUcwV*P
zc-*EDS`&Fp2<Y4pGP6o)M4OBv>HrR+L;g}tuVs7?F%E}(%9eA+v=HrHre_ri&&DBH
zzA($hwPm!J<Doj6gcw6Tv at 4ZXN3V)`-_-O{t?qgQ)l*~?o<+_ZjfvC-<w;yKv~prR
z7YnORfMH9$T}h>AV`39t{t_LOqrVXszvFO4fR7SZ<Dgysy1`It0dUVl-i8>w|G314
zs%F5eZz;uBt<0o at z$fv;)D^kTmb1}jsh at Xw5Oun%fbmZ6M$@1M=*%HorCo5rvOHvK
zuqTkI9&Bh=u$xxa at E;Jx1%HasauvRkKkLKwhH2r$N=A2 at dHdb+ceLU*<GF!ra0u`K
zfk~-$G}{papJv9RCuQKPwdP!bcOOpm%fcj2a^(P<+90a+=tEDfsf@>DdAHinV3 at m2
zykshd^r*o1?Q*?6r<&g?1XA<*&`j5$iIg4XnlvF=0HQx2yqdoKdp<3IK~xhO=<<rh
zoOZFq4v&_4;n|cJl6b76(WJ%+PowZLcpQZ>W#~1dHPk5)U<vSi-MY>utcHGhzl^~N
z_6Vi^0XCR0v`9j`K>T0okEh4-?jG!6-T8ZXd+LAg;gRon58XZI at 8NLc**&yi5BnOm
ze&GRYTa#+wyBQeraF4F(-J=v(ZARXeTKca=fEUY8u7K~(t&iN%xSQwXG*aLs+{aVk
z3v$ic;2DGA^_<$gmK|MoxiQpYzPZnQhojJiUHTL5{|-JFd at Gi069X@&BD6zpfC0))
z;RA#)#e7`k6tg|2UQOS1m=IR7321n`rDw?+#jK_m9mW-nkLfn~H19Cr0h^^qc-llh
z3}KAXtt@^T at a$CYsW{JgcKv+)+`AQ${*2(7ZuGvDNYyD#I4dIH;7n?QL$0Tg4U-P@
znfdrM*{+Fs`;~X$T*!tRf(uAW#b^29Wb8z24V?^DDcM%G$Z(P1yAD9uXOH8T2jiEU
zAE!e&I2!VEU_GD)d;pI at B#c(~=Y&z^AR>(L*o?lzOAFB!A-f(M9-fDQQ1YrsWz6CA
zGx2eq%6Ohr8S^ZoKTZNF<6%)g;F5oF)|^4FSDz$Bc)g1K8K{g5qB0yn4}JLwP#KuZ
z9fkF^<B%X{-w(xtt;zs)$fFNwr-wWJ+N=V=b)TYhTA(=&@?5qy4EVPhI?WMbc%#!D
zR*Vnr%F1N57xKZ)v<s{DYjJAFz#_hT7+SZMErjKX1Tc{Op*XSLFRl0LHXNaP@><w}
z|I3=zp=Mw(=4A|G&C?w(QJM(tA0yJ=@H8Ht!Ip at 0Jx^myhv2%1^ang$hUq^?q+j7_
zGzbn>MWh$=G#U{H=SHMUc^dDZg7-wEZ{z8^Fg+$BeFINli0R=G>5F+f6YIPnA{|fZ
zylQG)sb!P!Vzqu}OJ5RJ?_~#H!~-74w)j%-srx-~G$h=a-o15Eu%G at HuqF-G|3AP^
z`z=_P+~g2e8J%j4EnwZ??HV{g*5<9w6jmjPYHh$qIVNvSCdOimvs-GU9rm0Wn_T^y
zK46cEVJEN`rc=Z}Pd3{zS0_@}KL}i(7Ry+7w~GF(mnaXTmxG<e9xdo^@LbG;f3nG{
z_Qv=~&#yO$Ii13)l$$UxGdubM^mmnjX<%-?eSth60E&yXv`YJOTF;7|%<r(zayhHr
zlaIdsun}EEqN&bBEIr)z7-%~+mHW at DXps(*gUf$Ww90BqAL4d8A>SYw8d4$yCwatA
zM=-9;QSy$|;>g=yHY(E*c*5vF6U2QkIp{GvO$W*>nNnAo<pJrMGRs`)vNFqjVBenm
zz21zc9w0}nH^N at pU<5)$Ny$@f$-gM(4T(tTZH<9CZ1SEe6LQp_(cy<?S?J2)XLw&&
z-{|e0wB!ltciv#8=71rXER9o}q?^3K4CxAQFi9Hd?T+<SIp7_Nf8mh#c(<nok%1T1
z{gM!T9XbAv1}pa#@7-<<E+wb~Kn->@#CRm{4?W)RPJ6e<pxvkP2vp=Lrb;rEVsCJ=
z<n{*pNTcABSK_w^c)R0;3KW=jHW+|Y at Qk!2cPTeIU;>5%$`#g~=%ZYTPlGYaU@}t%
zYj7#h8bRqJtotElUTj{A5)02M(0%HAMG|uB=(ukcG)^&vh8B(`X_`@s;fhrKO>gmN
zhp&?DV4W!pT4ot7RG>mb_}%nEdY7nnIPw1Y24|Y#y*T*z1&SL$h7pKa1DPKNF#||n
zWjKIbKp+Vk$mBP83(|QD5&$eMvK0oQ;v|IwbY;zS$Xnoigi{!u!j+*A^W^LN?H|yp
z);Rj at eMZA2x0uNlmG^R>R!Y(TO=-5lf6HM1qZwM<gJO{sd39SgJZjFehuj|+Z)7>|
zk#|Hi*0+p4nU02d818_a<j1wdg-jw#;hb;pux5BYQ#!2~c!qdffpKTNU1{^v0u$2M
z>A&;)qm|U>^w;r4x&JXZ7e{51E#%TTj0Y8a9P7Z7rx}Xg&O{HJA{?s=)dsTMUW*>H
znEYoFT8Jg^H|{p9%AZ1xY^R{PrRL7*`+YR<fJjnv=xZt6?4JJgtwC{QcX`U7WI+X~
zytIp(YBuag{&`4OEH-EGDQ`&zy8DoZ0E>^kLOV&#rw}<8$~Jh%57x{A+g4z+>drRa
z?Da3gA9(pst#I_Y^QztGDGlgAv{=n%b2kvFgJs&w at QNMjNEgn}<g5%d;ZJim)MUoJ
zG*B^XFw4Tgy#90e6~c)HlC!uGdVCVSOE6L13%q@{7!aEQH?hW8MBC`d at S;a_oRct(
zi*@e6k@%iS2$#Igg}PRIkoZNch(S2V7&I4|B=umwt|swiw%odaE;=*ojexF@!OYBS
zVplhiv;MOpE>ENpbIXnBetYyeVh~35VITIPU6h02K6JBK>cf8M!=1DBK8&5p`*4*;
zziS*Yb!EE?cg4==uBf}t-8vT<T%t*Fzt!AH_`NFmIF2-H?pg)3 at K~O&!#_WdR0M-L
zXTwWS6zr#-%UALg@?lSB>_p^7+u*1`<*9(X)gBm|jU&)4`lmIs6jNyK?t578_xO8x
zzaMu4XB~$DH4eIDx9E}`R`PG-vK%CbntOzCHK at 1L;9z_jJ#Fy6+3#qzsk<;NM2D1D
zQN7?2)!n+lj29`D8A=+Qxy>+ at B^$X7bgbN<^eLFuI;L{!<*M*zU0`evI at g}a9iq+C
z9ijok(au}42hZk{5jh-dfmmk00zULMA=(gYxWzVqhj=1#QGS*+c{#rK`8nPr+9($m
zyPIOF1Fjf at NBHR9sLMYchHnlzY<|L2Z!&nhdOVrT^gG>jHkozI3hRH}%}IFJ^7lsc
z4X<_C5;bIUe*PHuPITwoj at pNEx4WWA@cl$LUe%s-q(layYXTCrqZrUY+HQici4t(K
zqkPS2X at 1<zrq4q4j9ZM*{-zQj_cF*Sp^N)(&*r at a%8KsvUp|A=*5jGYuAYT1z%Jzn
zI?J4eoS?FpT{w$^(3X`TO5AFfGquX<&QaMosI1;TRHb3MNc8roDBqn)^?LHymYLia
z>Xk5<+4TtoHH59288MiDpQ#V#D at 8g#WIa#p`CjXQFCg}IPk5ZqzqS(Rz!zRS{Xeg*
z9go3##pil2T9>k$d!}f8Nbk_by8s>ZL+P9?V}+M{ky-%+6snJ|h>?=LjhTL1Mi5OX
zyp2Xkax?1$*7!6=92R98EEgj>YcQcxS$P~BTz93(jqIO5JNU<$@n}VlJS2VmBP2S;
zWjyV<A75zsoNvxTeAq}2J?JfKJ6rQP1;i8s*Vmph!ikRIn&Q}>KgSQWqNpF``!3Vq
zZ<GXAU`WqKpjoQMnzNoReA)xl&SM#=<x8^Axr=8Ie9bJSL#sN+Wf<VtB2R#Vy~dC2
z6x0c3U^P$#<`<Oy=nuf#mgcQaOB|QseaIZ)6I<%-6Pxv0fDNo{=IdRGRd*-`w)+iT
zhZSLdnNKjS8cdA3gH>}h8j7=dqRj~8z!hH^DE3aQ+6<MvN#{z0ek|^H@;g4^EAkmy
z-DWiC<^I&Q_~=hv$A3QKKcB<TIp!b3SFvB;0kR3spn+mw^ujjs{@|f at yuH(42+WI7
zu;5`{Fr5mXfr9nv{E7w}+6U#(l9 at g2A=P7y+q|5gYp8)Nh~861K)Bn~o#)gdw#!Xo
zN$RRe_<>q`ff$P}-(kg8r#WldVqK<Mr=@!C4`R*1Skbfzy^F>ZP)uGm#&SvBd%%cs
z6pytauS?^+^l|uj9FcFt|6txc%3Go5og+>{F2)J&cH|uvy(eP at -z181deS8LoM@uc
z9V7VCk!|Tt7knv{7{HAWktZO(Ro-ran-+Py%~Bs=Or%6_cd}5Ch_?)nV&qC-pK$qi
zk-&aP=k3t)g4dSg4cIj>1RvgEG_ZSKL!XqstmU*y0C=+zeM!W<c!!as_pp(+pGHT2
z&vFoX2NXU5g#}N-z+u!?^wtFfCz@(ROY>aT>v3Kjg2kYtz7{TU6y<x&B6=nEkrOR%
zZLE?l`sc=CP0*&H_*ocwr%C%>V9aTl1HpR at Ko^XXz6zoPS(xz;-bN4NYK#=;Rnt8;
zc}GwD2GPRxTGXc0r_ohu`j+h!k<(-L$6X8M$^f>wgaRU{={DFqeiIMFD{uD(p+&C~
z%NHxn_68HBo4vt!sSj{s_u&G{404BvsV!gQiu|>iFGlJ}C6#Pb)34q^8{|U(Q62}_
zRRr4 at hLws5E}p}^ig339+%p8XJOVDC;J#@lxQ7t#a)7&y;1)!{r4igJ4tEU{!^lW)
zB6oM#1KdHKGQz7Gr7W*%l7 at QKROuqGDlCQ(>$^COO at 2_v!L~az|My|~91fI;A at A9G
z4Bb%JpiuZX*w4uR6z6rwJG?)}@Ea6JNDty4H~uN|{%DdWd4G(RuJ-;IFAY#PN!PQz
z59pt+za1DEt1B?<iGS0Mp9?=hiaHh;_BhXa41Sb_ at O&SCz6+mcvuEe>Aj~0`#&c<P
zE#s?n6Rgsm6JV9zO{=sfyh>})>o4o|2&?pNT%}E}zyoHtd{vf$F-+R_)7SRGPssaO
zv6_Bz8%5`I;w3j;Jf0?6<cKH97I2$b>#cx1D^$r0^N{i;uFz9vsjv4`vXtUI6)Pp6
ztT|h`$|bKy)ZikAD&D_g+5nKAes*~k;*o}D at Gp)6S5+y-!UDk8w;2uc4m^G3xFe7@
zHClEo8ZMS>qKG5UP}jZF8_fo_7I>jdIrU2bQg*Vt=aA#sENB^G%RBz0svD3Cw;b at K
z%CD at X9RRef5+`qlAIky2CeY+WXfl^Rxct;!%K<<x<h_ep89YPUKU2djKyGAk7&rzt
z0>^!x_!vN^r~YjpuICk7al(L%J_2OXhWo=Y%if!SY*3J52h1Ss<XH?mJI#%6{kR$5
z!r7NLiGlQQT{u~dYWk=xT5Z*y9QOPBwaq?x3;FdO2+w{KyJG_41}o2tgFNL{diT+-
zTnk|MWANJ2Aqmht^x=|7o6Nb%U?6cU#*f(p)%Rx?+#k}hU<r_vBi-`$c4KRuq+fKS
zt5>Qe?uYk`q0rOSl=DVbE?wFjbs#5m)O*q>R3sUBuwtv7T+NArg<00TBP8O$@4os9
z-kdOK&QxgsX2f<+dKO$Vo2YC4ic{Xk=DdPP9l)fifhk5*RzCD14h_Y$bGqb49h9ql
zQ?xltsBUSfv*d)P!oH2Ic#(@3co=$&EM!KKX<)2Im_EyUledKpfP(`a)WM^EEpcz1
zE#OeO6JS?KBYP&5M+Xj7(_%s)p0b7$r(t*L>^m21tuIhcZrSCTj4}pZDDSq(Th#QH
zCX~E%L1V9gYUEwah|Q!nO6hir at vK3vXreFv5xqoDH*qh~<irm72y|k1$>gkDVcpL|
zC|0?=+m122;k`Lc{A%Yyv|B(IIi}zwqLuuq-|acaIuFHHBc3$%&&P4qe!htgk-%~C
z%dMvWa}!^!mW{&Gf6xe=oUdJh60_5L+AKU>&et2u_yetWr{&9e6Da7qXsH#2G0o`7
z9uD19gn9V|vZL}05CeB+ik97T$6 at Ybo-2*Qh at v=cfkN01=*tvNjMU>OcHOF`OZXg^
z0L at QO(;wo6>=+hq46W%%ZbOgdrpeV2mjrIjV1Z?PY2cQ-gxB(qV-ykoPxu1_T3ldk
zh7ylM9vxTutoS4_a7USH;{k?Bj^XevYC`1O2G8T^`H?0XG8h)&=|9m>bvbiRy8 at 5F
z at STC-L!J$FuJ*p94d2FjQ_eAbeGz8LGE&RHh?%J16B<M(mK7}HgII_WDaF9xE<zVK
zH&G88kK#B1hPZ~Fp?thqO}~^E{)Gy^!5Z1kwrC-kcF1Oi{h%Z5h|xvR at o9ButJ)Z0
zlNNG~-Z>53dya00AEgg^KZlmZsLkZ*+;U*<ktqEl{k`q{y~h9bJ at mh}A&G`J8Sr2u
z?<M(F-|kU*J4Dm|iE_<a_dOW0+ANuXa289%LebQiS6yB((Sh>mb;&VUdV7ZOa`o}L
zEv^z<A#7)t+~P9T*o4*A{tjVvQT(j|mmvd#GF>d+p5n5!%uSMQW>c*T=1j0**xQ<H
zhh_8JL-+-`Ci43*jzHAA0;z{eka%rkzvB+sE_LVBI5Es~6RTADqzbY%tA-8jZ1%Pp
zHE(QT-bXf;=TiW=9PfgRSkExonmHOpi&FaNOYo=9=u7b at VYI>ey3rHQ?mq??A*zl*
z>PN&s{ZMZ(Xhq0_$h9yyX|BN2gf5Z&0KVfVF;GR%z<0#i0f5+!^Tb{U_JKV!i_|VT
zXC(NZ?L`C?6aa-7`an$@Qa(S0o`LL%g>n-N1xZZqz=H;c7ri+89B3co?TYiHy8KSF
zEnq!OF4CMtOCzy$Ieq6nVsQK)<B#`=ShG;k0jYJl^mQ*MM{3htepgJFSbh>eyYPqd
zg69l|YWXvyAUr~Y7k|A-P2hb>dBHL$3}qws3qD8LFJN{G&qfih@??3zOA&b(3qdI@
zF9<~BVZ>VHj`D)%Bl1vtRk^9W;KhhM3`wmFFE98sCY*=P*pva~1)o5k+^`NCA=qpE
zR3^WKf5{KCO>Op5Pn0AaDA^ecIijD&CHPej>Ajtc9$15G%F^gbkQ;-U1Qxl+^VEXT
zPaZKEJaO#QgNQSRxQ^h~jT?bTg*;2QmRU0ACze?ZQXUX>SC&~W^(5w1SE#U^<St=V
zG8^*(sX~}ggG#ManhOCO5_kdRIWG1xRy{{-P$cfXqfh*VEL9wPoHt at a4e%GlW)H$8
z at Co#>a5P|$2E3^m^(+d+rkafOg&zXr!m+65S8-CqA2+(jNRkE^lp()|G`4>tzI|F&
z)iTTIz#OA=wOI0VC?q2*tO^+yOY_J*|1M-mll)}hGM?fWm(+_U7!8AGHB>qnKLGVT
zdkQEI at 352_;xVr<G{p6RzL0L&IS#X2KzPyQ#^ZJpucua31Cu<OSGNfL2L}y^H~gtD
zRO6X{E}3Qc{F;sKMbUKHh6F4sUdVfG4MrmuP69jNkHKgkc}H;m`ojDjv97ulrVu7d
zW=erg#c0()vsala6GXK^Se1t*+t`ffX>$8T17M6#UxzdZNa^>jWj&dsPL}9-2VoNH
z$EgMdonz;9;KiBmTWAGdqs5h35<L|9^C;zSCXVK?WOn)sQ3c3sQ{!nu@|qL`Q)|jB
zQ>6}U@(sRCo*@+-QXere)>xK*sfTW)l5q$tI&dkr?+7Y=)h7IYe0{=HbUO at 9#z^D1
zOr!}F9UgOGrZlcFQ5p*aa-*=mkySotpiT`!Nlz6nVCoybsC82z^?WG6JQ at SFE_gSg
zbNY@!11EPSB;0p;v$6m({ybt+{QxF?T-*Yg+7>t#<Xd1KauR{jvD@%=GL}RTqP(X*
zt^+cF5P6qE<qr945Q&}9kFO_U2S?W60ix>wszixI#nbZAO~<~V5Lt*7 at WKKA4HYd%
z=S>w$P^-z?t<Jk$4D>%LT6WA8(WmbF&*(&ZzAF&h9<G;k0<>Bm!s|}zsDJclK+oG?
z%B$`EA at 4z2G3g4tbjcs`p?V(KyH!n}wH|L~4)f0nzQ1!SwbWjaDPf$n7)V{_>CjU@
zp(1U*nA3{Cx#EsfKzQf1*aPE at z>h#yHs)ul=}Fay92hsW+sbxUgqV5BMm5mu_!_VZ
zxFIndoTe?deFG8j$;gcSr4x_$Uqy`4-0%f9tzJo{r?p>%Hv2 at J@FKDb#tENEG10gW
z($Gm7ckf%qkoww&>;8OT#OpbDL^en%VkhA9IQv^9(!m(BYWkA(nov<qANd8cNUhGi
z{c3vIhHyIT3$9d`AIcc?1 at 8Z;&@Uh at wJ_z7b6KmnCQtjE%W}X4h~4EMvh7VE8asDF
zYRj8OgC0H^CdxZ(;CHa#>TpEIBn3~L=uz<wO?w>B0gqd>hrPYaPM(M;bHf&kD0>ti
zH9Z}?Mr(G%4(%iIKP{e%fgeMq4=J63A7f!`<v=BfS1^Mr2eRaeVV=G7=EykXdtGv^
z6PB?j!=1CwRuwb0GPa*nt%aRG+^IHtjwqM8a(0ZZioM8IX>zJ{ke>wkuwB(A55w=6
zY?XtMAgRC`ZmKD%a%x`{2$G4)AK}x>CWIoDd$*kZFXBEqX9sk*qb5NbRAn4f)jx4m
zt>;crt${DzC3e=Jx`F5WW#RDBw+8wrmX;q<h0^kqUBdj$KnLC`_fG`2!Lz}+E)<U1
zWoi+<?J9=6cjnbPE9#^MMGyx8iPx&u!I55CTDr{FB3%I}`7$j4^&kvDt)&G>C-Y>i
zufroF6|21*B{%nuzT-P0xQ3isiwokY^aviq7mEc$PC|xsKU1u<C+-B0*0mh_+=>^I
z4%{Sf`8e8;lW`WWW6$BUrQz`m$SEr<80`@_Kh8!_EmAxZ_ewLe2myP(F+!>laSd@!
znt_~GU_c&RJlX81JG?T!9v!;WKF8sE2|o|9Qwd5V{*W4xsUB4gniw}TYY+JtS%*YG
zlNV$7pea4|mWh_S#}n4jTKFTsv_^5lfifcdH=T99zf#ysA1R^_{GyR}AUC1|ga2~}
zVny$zcrz*0JE4U)Qma|0)f=(Z{k)pr0WmN#2Ipq3j1)AvPwCHUT)IGMm5T&Q%Se at A
zH@@1xjGOghZ&!-`JmtN!I#pwVPU$|W(QA7X_uAf{mAZ71>!d;wu at tUTm%!7NUbMd!
zN8^L=Vht>ioojJFFjuAKg!!>EBt_%71D0|oR^#2z5i1pi9=UG$Al=!Xbjd;f;+du7
zx>~MtR~+Gu>c at 7B4-fAb(01ifr+*q9{z<4HmxNdLDVR#oqF%{$Fu08f5K}o6IrE*T
zL)RSAbvQ^Lm(!|n(yHi?E*35Ik0)>paX~1m?{?O-n1-?sZ`s&qNc}XOR5Kz*bKWQ#
zfL`1>s at L<2)@i+TNY3tm8*PN6{1b*y=b=%d&VO}lxbxNUDL7yJ7h~5<qJJn3(_!vS
ze>e71Ii>e=0`_xrnYNBxfvaN3r==g)Q9NHqPu!}nqemerXDAmz=bfB--m-`~KY%{v
z@?XPScvHo>2jS6z|1=0Z27Fp527LH}KnqDI$Mw9T3p(+x1WrJ?+vy*_0>4#cmleBw
z$}S(b%ilshD+})KFZjlyQE^~aY+#<TV4A^mnO#_I%XJ3EugGh$t&OFaXegol>yJE+
zBs#TQi?UfJL+5OtqxKi6)Y{}NNHi3&<BP~k5<I(P#=eVq>SBBF9XPDZQ6wq1vxY@{
ztkH0gXr77~lJRqwW at KtRj}ofj`yC}Z1m6QOIFT?_a$Tj-1U$*M(a3KsJSMxzq-Ktq
ze#L4oK*V_7-i29n;)JC+F{qGg&zgg=yDasKugRa9^|*8;k`D9p2TGa3s at qj1Ni3-~
z?H*Gfn+eZGOY`DiQ1?FnZq at T|*@4b#@|}SIehl at C=*}N+2=bb2YcUfh9x(d^GygWO
z8F)#)t3Lo+0XTmRh7xxMo=0YzqS&HpfIVO}x}gz3v=K>}5zk+L>U^(1*XwodRofc8
z1E&i1#PJG7p%fwTK3b)g!dACc-oM0Fc^~|L8^zhS%D3>R01)fq0vd|E&`=Dgq391o
zVWW6Orro6uzt4d^<b(2EXi!?5fj{7PZEJc+{I`|$X#*lL at T!4SK9^ADcGi6WGhd0!
z+{O+=rYJv;Vt70%?d at u!=Vr*r$BgnIR>*RX5R6EyWlb5&<j)gB&uK^WI#?{F(XJH+
zW@#>Uo-`Za$x2U4%SeRsVLs0kDf1bgxfJU}g8~0iya7g)JQu9x4}U_McPslp^t+wC
zO~2dNtMDs-gV-W~sXAq{D3|lDR7<9I)hq_$>aI5$xO-dw>r~_~x6<u!T)`;hU0&zy
zC>MF=yB4Ft|4|Ch!`2`r at GR|O6!2evxJQi$?U?VBAGSK>c_L~u={G?n(=54*bP>4Z
zDRtVPfoK^Zm!Z;eMchyzu03W}IE94AayflYi%|lna9nU5vUajjCew6YU%y`UrS__C
z`<qnXPm_6lw%7=ri2Zj)zPIb0$oF35?|l+_&m8gIUwXawX0P||=kG1#?}-6h3cV=T
z0!7eAZ7eG=NQqkDFSRkJIWPve^eGY7s1wBiI?(q|gZ~~;^e+O2C2rFTh%+|=d1IER
z73ZmLycO#5Pcc;NUp(9{?{vyFHg%IVKOa~WwHoz^+il)WDq4Qks*RSqK#_4_jNEFM
zXDpCA at j5sGM$j%7$9BGni_0!=cFXmHS^x#&C8YNdMZ(NfYt?kaN7`Kx-EVf_f?U(i
zIToR!dhvbexMNJ4v-5=L?TVQ at VSK<fB26ssM&*|I!=d+rXsMZR!V6Y!TRXcBcoMYZ
z#Ct0|asJtmuw at IZ<$i3zk3At~HmSkz_18G*4QU8d$y>+$9&u-+*}Qq_B`Y}|aT&1>
z9>XOP6v3ZNo4m~-Zv{HmCht+xU;Yre%l44rAE1m_G<xciZj{|~P}+$r$#PV9o(B|i
z%tWlEzYle3tfmX<3AW)ZS1*2ucU<i3ppF*-X1XEGX=$8)eW=q(qCQa6_Zv=VeaF)i
z^{rolni@=@{s*!DT%je@|GG4~djJaW(a6^Lv6px-tLf`LK-mM{MaT~Hq2ebda~o-%
z0e6agG3j>U5ul`UWi-c3>JHsvy$AycgjryGdwBtV(-X(;XV8$qgmA`fkbxAm+brg7
zWfR-5ov=7%Se!B}&cKYc(C&_iN38KGbI at Jh4#e6Mo$_8A9Ix4cBxGOK8d`O4 at XJ9g
zwug=oC|nsjJs?dt<6M at JEpx>b4Arum&XGEx_sW2W*GzDVHNyqerJMs8C=IX=9Kzp{
zufWJXX2m_08 at 0zup9}3VgY21!mc>E0+-{do0>v4R2xm at g=d?L6{IEj?wa^NLje>jR
z-|yodY18%y`es}FkUsfKT$Z-^MX)cj^nG#d`Ibn(<N6ZG#cBUYUmkb=pf3+0VtJ4_
z2>>hMTqjAA+f>a)wDv&bw}$o%y0V<EubABTiK$C>$?jr11`^w8L;1+8e_}L`UJK#Q
z?|Uf53Q#OC??vDIFY{ik&%4!zaap at q?x7wPCmiP!=J7Rc-mP|>Oo7~G92dE8f;Asj
zJv75b+6+$&8Cd}d%H3-NaxLy1_a|Bx*ea}^I|fL`2kjaoM^_e?qMtMGj4o(}&1_qH
zE!64=%xV_>Q`*TB5#E6B;%#uZp|o#8nj_%8mUdDYKyGE%@X`z at y)LRWxs~;WQYgv8
z%;Z)vFfKE)=HmybbfjLI9a*}ImtL=z=0=vT=A}18wicEoeDh6SawWZEjqc47UOHT_
zRg5fsfS2azr4u7d$3iLP76Hsv(KQd_?~Wjd;^@)@UV61&^UTQ7;5Sryjb54`S-P2*
zj at 3)&M3%nKOYM5;g2>Y6d8s2*x|APyVSq<Dz%4pJWfXv$1B}xFmPG+v#Q{Ve;I$}#
z<Zt-6EnQB_%<YUGoFBiY8gA8VSP at l269*Wt1FVb!Siu2YI>4GJfTbM3tpij?0hDrp
z+jM}&C;$fsxKRgajsnQy0QovVYZQQq0~F{0ZBYP+{!IX*bO06wQ1fqXB-{B&TB1jC
zIj^Bmuc0fdh9w+ev<_e}_6E3*1Kgwon4<tjbAX$5fV3!p!5qM<17t)2oZ3$SHXR@{
z3Sb`x7^4GZM**zm09WV$xlsVGae!<cAU_IV{(fyFiQ>mB0KXW)9rBj|#qQ)a4ApBu
zE`XQu8m`}un9tpATWbOyoIoZ<fn1=2B!)nyau6g|5Tbn_eI=JZ9GJC(VCLv;wfp~1
zQK)_FOAVG_77$O;d-DIn0j>@2^{7ri%>k|p at AW8v2ln;G*Grd00a*9-M%hbWivk$B
zPaD^nMp~iQM>n!(Z`91Jh^pah4sd07uSWrVzPC3DU%Dm=;7 at ydWAUZcQ2<YJfUClL
zJqqA%4lp9T*P{UP_x48TOP5ChT(~!C3AaW8bhP$H>Py?A0Cu%%BgrCGs69NK?330g
z)ZQLd!%MAEsJ$x+U~X#^YB$962DrU73bmV~0CG8iGmH$P0EE^k)SeLq at bjK1)Sejy
zuys!qYR`@W_~)J|)Sep!Aaj5lI3kGAMl)h0f43(JwOgZVaPEmh?P3%__MRxzJ~0X)
zVNVolFNy;Aem4PFbb#V0fQ`GOQ2Wd%fOmICq4qgZ0N&kEsC_{cz=OM^P<vSvfQ<v7
z{w2pBk%NgNnYlX(wJ(dRLES|FmxmEZ6u>vTqEP$tD1a|Gz>qKkiRq1X-{1fjhY?5=
zz*D=<!rW`3K#Bk)Ib?Mxp;GTcQtGv81V3pB9X1&Zddy4NX=a!1>!F~5Y#>i$ur!{4
z`R9pjz<-p;WhW?+%#QF3D?7{+BHPas6IlyS6tO0rC}!0>F_W$4iG20}Pt0L|<%tFC
z4NAyJ=&@xyjWiwe at idZeYynRrrN(CSG!kd5n5U8cVv~6qNi8PwG*VTpkf*Cj{>Rfu
zE3qt|MzV-y at HA3DEQP1rNcPXuNY}7mTPcmC3}ZZv)C&7IPa|Q%nt2*&5cVZcBe}uW
z at HA2u?4LZ1L<C#T(?~C{mwB3GkCi-)Q~+DZ(|GW+IXsPLJDbkac!;wip2m}yxp*2+
zTxR8IvZx-((|CrmY at WvBk`3l*JQ-OUPtPRzCr{&f$GZ0LvBmUHJdLLqYvXB(&HWWm
z<JrU-c^Z!)_Bl`EiNjX%G#)POU7p5sguTYocyzF5c^Xd#R>sqK5HN|S5$Cg+JdNm`
zP339C<ZL2OBhqGeo<{u4 at _8CjF}sSV5$m!{o<=0g`tvm6QfB69M4RmNZa&VKZs%!4
zhU_p;Bi>`JJdG%hZQ*IeW~`d05pl6kcp7mOTfx(akJuYLjhKfm<7q at P%*WG+PuK#U
zM%2M(^E6@!R?O3g4%lQ&d$kw}`rRnMgMK2 at fb4W&#1fc(Y5cnC7%iq8du6(+i7G-D
zbuQ9JX=Fw1bp3h(UL$^f3ZXW$_FX-y(%RrH21o)niSpN?yp*Uu%SI`oU9Bvp^Z)H4
zV at QWX)1V98J(I at c4tsv0G@vS`Fn8evg#}CcT$NiHBdWFb{3Oqh$Lk6$o?{rapvr2r
zRT`XXwXfQ9OgTg{WvMib!xBYH>Z0eNM{(@VU4%}|kTZ|x*m+JG<jmqZ*YTVp$a$OR
zWb&M1$oT`$>9Z>|iqZDjkrFAq20JSH#YTW=F1UNJ=fZ-!Gdvg2eb{jrX7-%X5L^W#
zumMq)W~j8sCU0Svm*^MEW}EzFu#JS6uW)DOjV`%?4Q}XBH{gYsyqzt05U;c7@;nJu
zZRUIh<KO7dD7bI1;7g--wzEkD#OS(fHQh-Hs~6uy3NN;`eMk=b6?z|{YqzVn(_v!P
zgdYSWa4{W#$*nAPJDS=qO4G{H^s?kuw0X&7KW$T0UN0U+jv@{ixcyi92A)Qn2to)!
z6o(*=>kuop;dzCw2Dh?oimARu#q_eBbR9w_<4*a)y!}dFS|fd7jilllahkr$zsRE~
zx5E-Se)bZ<Fv_z7MuQ7OJ~;6HvNV8KBMvhpOL#I3lFNCr2$FB|WU<44xx3<s6zlNM
zfcKush`f7|pG(tjm4 at K0Qihhn4z}R(d5+NcE=arlAK-f~|0;s_e~@kDF<qx-S)KB|
zxlZ}ve5X9m+Ut(x|K)xVe7F-M&h-pf%w^BgVz#yL;~a7x=Q-E#oNUOM&2xtEoLtCx
zkmn at xoP5YB;yK+r_?ZtmxAB}Gc#a4;cAm3~=gfqhJ9thV&zS=`BG37V=PZDnn|RLK
zJM_aJGOy*CRXcPl05Y?9re}vv4nXFGJhOPmSvaqkOp*30mn&*p7KvyK2hxQbwm)uN
z0k*6wFzk96wycUivT4t*<rf%xnCJe`?Y$?75M=O5*qosay63*|2F2UE?ahcFaf4<E
zzR at PWLH~7MXoGrE5$GSyw91tov{UnKYt!i-)}EC?WM1I*pY)BgWHW38bmw4O+n;X!
zFd4Z02<HYGV82e&AhK<12Sh+98bop{vuwugc%gxF;K{A{CESib>R%a15E%gB4lK;d
z*IE&z*ZHRJ+=LJlX-nh#Rt at GOy^dW3ak~y7Y7i at Rh>tgg=-7*NsEKw|5!CoUy?mfv
zetSguJiUCfUVcYJ`J_$Afnx3?4mO43u26ZN_CAN1Y+HM0 at A7_n{dej0Pl+f$-V`do
zLodHGqI{=bK1naXE28}4CLE#kUh^;$CsQAx7YL$%FNiq+ at v{!`7(oo^1+k#lig7nZ
z&$cfMw->Gn9VojgG at W6fN)Gfd9mv##<H_d~0hVdty{7$}M#AKoxUL^Pg;;wF+q9Km
zYS+^5*5LQ2&x6eY!x1*W at _g7lkp9+EG{V{9hJ(>mjTqn=epH&B{*)~JNrXrABBMX2
z;d5H}xd at +&!q3I{Tx at HI#~qD$-)w6jg#^U?ng0Rz6Tbg$3*mk`2lj3u+ at Bf7{VxCC
z&cglk0QWx?iTkJV`*2e}k_4%-UNrHhYig-q=ze;`VlpN8_w@)8=YK{s--q<DrAF;O
zz3#@y`|U5Dj=bMqvY76--?&~g?&2B)bT^K63tZpKk=NoPOA;v+HQ~^V#534l*_Ry|
z7FKiGn;zB<wdePh%;fxYljk_9nZ`LP`zp=OoJL!fVN7MLk!Dbe!}23oE<ibZdss-}
zb7fw&@+tRA5%=a?O~D9OQ&kKZ676%r+ at hljGyXvvl&lPwyh9m`!5etwhH%)1{;^KA
z&Q at ij+cQ`;`_28clw_M)Lm5uB)*-BlvB{12hWB8?&O>8-{bQvA&XO8(-h-+T!|Qr9
z2OGa>6M*Wq47K8p(m5a>uV`6tGc1$QPT6e;#NPCJPVJ5^v4pwg at 7$)t<K_O}v$B7Y
zzE<-1fa`l$qHcqd^h8`>k*b&i9;2mmaZN>alt#Poa$QJK(Hqun=krwVOyhUnd)4&&
zU^n{5X8FfvMxK8mR~;vj6oC1hgbEC|!8ZD3n9;!g^%YU{KpLj+AI6O>-li<iCGvzU
zdq9jKv&nVI21BNrUbu|z9!JQKr4%6Wn4PMsTmzs4W+UI+>tfRoSRi21mF$BrpnpC!
zz54~OZLJgk=us|^ek*+37O)yiElHAKH&vroQk%CcY3|R*>&RqkOI2T&Tmx%Cxgs#;
zZCFf&ar5KKYWFHhfiW8(Z7Qqn7S?aFRi!yhO}7MGP0hX*&n_D`Bg<>4La!W!wuP~U
z_biUT>Vd+6^JCRoB`DX{McBfN<v($+U2%iv=qhf at DQ7R6Gm`inQSM^D$GCCNqa3_*
zFZLTwVhm9+s6}p++shBd0hd%>8<U2X1hvnhf*f7rzm05pV60Jbht!SGKNOp at l7@S@
z7>ILZ84abDT<K!94r4QTPbJN5_mU=3tbg@%`0=ksPD&;zeGQ8t8#giJ$^llbRLvE5
zuor+}G62D3YS-u5I)<Lkgf%=TlRNO}cFL^$Ad)!pF;~E9<`XEa3nt-Kfl0hI)P9`C
z8!Zd7a;2*(I;3p8RX*34)+s?OVkhrXRZFY1Nq5<ikBeG&7N*%GrjhSJ9QSHI?tghy
zANQ5oxOZKrk9+r--s7GdG48Fs$Nkm-wEGBJBKtqY(c)xUE(Pn;2S1k`|A1>89>C2@
zENeu)ovrfbK`rHnVyIpt)qCt&+5!K7TC934?^7+F^m0B|Fq;0iaiW4~verSf72{b_
z at F7NGk{qs*r9324L=BsZX|G(VW%5an at xP6e&OW#k#**IgjN%n5*YP#5!syACcZq at 2
z<V$ho43sWXYf*2`dlFYpqmiqe at oM-RYYou4%W5n&+#Sh()#o0WE9v};6rdwo{ptJE
z??;4nG{%Yi69pe)ol=Uhj+uD_6pPmP9PM?se~R9v3tjvMi>o?pW|PklMtV}K)Lif(
z_So|~t>+K&>OJ>pRo>C7MVIjwjYc=_9Cc;#<xR^O*R`5HU*^$1<)v6*=rhnkd!2vj
zx%byfZGZLug72?teSbY1-d`No>Pxxx;j@<Vh+KUsUyY%ao-aDzQjQ${B~{#{{*tBP
zh5UvgY5@)ZCv|*K0ZpjqK5b9~6OAyWMj*D7ao!DBWbjP!ZorW<U?j4L8rXYO!;QZ+
zbcI#iP%VU%Xi6fN*SQAmz-LGmy^%$Zi^{*m;R(n749T50O;S}<$Vz?WB!zo02`|_B
zCk>`Wp{7fI*hgd2Vm-0kAz|1DESLE(d6G(^9;hPpZU%dN5~;#dMvb>5)8Kt7!{8r3
zSSloCV*jN6 at IB8dP4ik!?*m`y9GiwDpCn)cprm;CZbIaDMcD+$36MI~W!<)gab?~2
zEH;+~A1Lb{IRAY(QoifeuH$!5xAZmvDK$Le<BezZkH1iPb{Bu+QycJ8Tf#V03pl|Q
z)qe!GmQ{~H*5fsr;EE1UO8I!A6oTIp$$pDf^yi5fy#eO)qOyF0l<o?^Qy_KXV54Cj
z_XFFBgKDDo0Msmmnl8%x9RZ(`kOY_qXhAV!$_VG8_o+04Q1LQ-B=y$|QSMT=&WhE2
zOo7#;xo6jKE!J=krZ!+|A_?t)R2hk+$~EkR+i at PbnFXIrm_(?3Oc$DA7cJEWZXh;P
z>DMrp`l+T*Sc>FOCQwAwCf}>H)VVHh=QrXYRlKZAx~J at BgER#Qkb{Gb#F)RcnOZpp
zvNma1&rz0Vm^@x5h$d<TQO;718ZEd37G_OUEcn8RO+*xpC!%O#FQVw=GyH`l?S%@}
zlcuI0u0-W6R6xg=KIJMqgK;6hr*x3g`|wy^y<JUjs^k@*M?86arnY*<Yt?>?odedT
zzp#32W~tu+?~KhV^)HHrbPTDwqjmI}{${k+cNjcZy8>~)41x)_8n|nP#ct~UwP)F)
zT%V|_Ti}DXwFv6Q*m{JW4ptCK7!AF3qYz*np1&MOP5+V?!b?fSFuqJ|r at Y+}u*I`M
z_iETIWRO&ZBtkLwQbcZAf6M;M>FqMly%bHr`j;-NGLDK(@>~Vvh*NEZJkQT=r0#<z
z&rmeq5qNnDFZUc3fubB#jfPpv04PSfQIw6M1t9JfQBBxlPcnO4<cSWFX&Ca;mVwC(
z&((0cW}-RUR;RaZsP+-*Poeh*k?j~1{|v<miWeXC|8h!SQD_u}Cec#EzpnY=i+g`Y
zZ+>S#I!^Ep27YHM@;g(J-<gX1PLpzp#_#ZWve8TraLX~s?<g1BgjJ0;9qwR)2yi<O
z0h{9)>QrkSRYnKE?Za``7 at mSv8pGq1Ym^}Qk(?6YX&&_}<HOAqZ8GpQ$6RudZMlLR
zZ4?Y?cnP;lmlp3VkUI1t^y$&pXV4t`2)>tS2c~xn)SUZF^BK64vM0HyTTTD0f*`&m
zh;5=jZthE1$w;48{wH4ktX_T(mG=*oKgG*kdifYC|JAFN-&=vosI5>?@DjIOzZAgZ
zIJla=B?Om;_4wmb07yaMu<0f4WFzk6i-^&NoO;nn_M{KGEC-}%^vX(VL+U{+k=xbu
z<v#A*1gPag{Lqc+Zu}Xp3DMD-2hl@*NIG`{YO$$bp(%6+>?5NmURZY|U9qA+J^I>q
zX(Z6Ke8{9L)n-kbbSMB!)d2db=~rq1h>$sqoI2t~90WltNwbq`DVYxe2;Y5ZpbV=Z
z?-N=D6C?clM9TxvhEz&KdBBiTyT32{cY0VL&=?mM2$b3j`bvouRsvZ5qsa2dmpc4?
zm8~cf5LO#X$M|E7PT+G&D>S)45P{MVh&_`Y5)7;W#^e1hzhTds2>{n%%Pz#0U4Vsg
zrT&2mBbf!HSV2S+hsB-KqIED at v<j<ZO2_(R`#CWr1~lp##1=s%8?9P})v*_q+WaOb
zT1HnyTDBf03tA}Srmc^LOk0yn{Znu6A=}nv*ou$)Yh4O at RNb!c{Nw8DA8z!V*l?r&
zo6!?PpHgaJa2m+wp`vL)rnft0ajLi5<QX8xH7|iBeTf{`2*3W+T72rqg#Nl&;b~LI
z&1-g at KXu=9^Z<Dd`^t%VM<Tqras_Herx1FT-_TF5 at 1G{kt9(#%<|-X at mg5P&WPU5{
z38%b+ZT=JpY`h<|$>Y<YhH+xfDH!>orQR;v+$8vW&-~a@^xnTZxzyWDS>2RXlZhtl
zqPk5=q5&zj)JXNh>Ly`zbxw^kj#TO!=*ZHQ at 7eG>iLkzc4b)p{&7Ykm3ckrIj~QXr
z9QTudV{dg26>~*qYlI?makS%P9B&d^?XVZ5Zuc1to&|h7KD<C5k2hk@^0KdwhbyNA
zBeq;{cDIwx?sjbqF2!)SH-@^cxv%^(J7`DFt+&r}O&a84jaHyRDezN31iHPQeK_&|
zq3+G&nmV??@r1C1&5H|)dsI*>#iFPMqb*kxO===2SkY<~As~uC;YPp(v4K9|HmzNs
zU0&;Z-E3cLt##L0zy(pPXszN>_v%g4x)*TE{hl*(69VFU at Av)u{`md)e3-eJea_6B
zIp at sGIWkG*8aGsDeO^u!b?g at mgfByt5H<FYN63S&a;hljQH|j4d_L9-Ib-qZvursc
zN}{#MY&j%C at L)+-wFaL`kYdH)aYZso4_E<ER-~OmqZWIE2M!RNY~U4;f#?)i=F%zP
zUqlFx(d34D)KOv37;Jn&AEM at nRBC>WwpNE@=Y02z<BCuTKwa!;vZ?bHhsf`>AAeN8
zc#A$`=*zNYa#X6o@(=K>b8oz!z8zW$1LsnxlKd=Ds50Jz*`k1<GGB66sS>Jns#LkR
zlx|Bqq11s;Dk@<>i`WMR6%>$WaZ{>7jddLou4-ILRSH^^s{G?V8LlZ#r7G55<B39t
zjZpBRrBu>4ax==P!*;<>L;0W at uWg?{PN|BUKH`=^C#oNWUZR6&R*8jDgiD)9i6h|K
z*6488@!d+-kr;e&DSbFfrkNovrZ3kCMP6w!A?7CM$F=Yp_|l~a*vpmUT^c1iQhn^$
zOT}8`Ezc4S5r1Eb at Yvn1f*xpx-8W5L&2_{LiP<8 at A-E0!W>3^KMRmbG^7dDHe=yhG
z-p3L06uLp^_nm|2&gm9CySbH-55Rx#$tce?SopC+3;uIB9%m6GlUf8>d7rHQ13KO)
zSPGRgb7v#IXx%Lt2w?zS*&}(@lb;fRZNaxT`1ZoU|HN*UlSj0$00?GFnntGoDnMC}
z7zM%8hq*0pYnG~ve9B-we`z+6#n#&HJQi0>6hbw05CBsMWgA`Zz1-2nSoS}miR%v>
z?V*X*I3gCa#UqaRqrizHs6}MJ6Yi#|9)mNAmP$B-DS3mek;8-v7Iv`|Z^UDpm$(<y
zE)IEmDFNa{^12CdNDaXug~8NT9l*n1xU<0_N{w|P7N!(c*R<hiVkvTo7pgZ9gmSUY
zO+S>RWdV<qoNv- at 0&$tg2*m-;hu^S`&(<;D-lg)?Qc=ffno;?fcs at S_7GGYGTxN||
z!X76E|5!-qJadF)>|1C%kn4^->B*5~Tn^%6qYX6*EYtoK{_v(hS}Blfqpu=LB>Owk
zaI}dNp^3Nk>Pl$hul{aL9II!(ZNQEwg^?P%i=f_ypM+1YIh?Dvt4 at 7CucI#foX#5H
zgVfJ%VeBUuyRUuS*p|BvbD*%;-)Tb1J`O0Eq3XcPAIoKV19d62K*0a;G0u}J%Z0wW
zs%9_U!dd{lXEn1+qf}bX$J#pyPrI at Uq4yo4Q==PM^E&8hJaAaCu;z8D1nlu(H(d+C
z!aYCNBEEXhL2L{xzz2{z;m&q^Y8M|#?@i6z=@3^5=Si3 at QdpRPcCv)}?MTub#$ygX
z5f8~BYR at z@*C}k0vI8pa1SH2Q;nP;-RqQ11x1gnSoVpoW+DTO6Sz|+loe8ezwU14+
zzHOS;eU{P%!6bjhmGW_AE&HF#n(9_oaP9MQqAl-$To)6(r&KOu-mYvqsq0y*8*o5Z
z9=M^D(3gDRKc#fFkS_2;nvUvE0jk(QER0H6S&y^p7QszN0aX%3;;0wBUq?W}6_f<!
z6c%4mBC8e$3z5EV`akZHN7bo1ej46fI4{Kg8wYCkdDgPDi;OAVKqM~O=xz8S9_XsY
zL;*`DMAd;ri4o3g%NmC$oKoWa7=lA~SV at gI@vU(#ia&|m3E#S*EjK7B618DGA^Zb!
zSm*SI2Jy`fF*bU6GgD$B<fkjQ4Q7j2<}EE&oElgKQxZ&)x%Lv97ZRza!7`woJ#|(s
z!DG=9g0pI)oyIsRisKN)B`%iaxyuJbkE4jnt<&5;%N6#2h{4x6qJEYs?McEP>HFV4
zhQ6QmkvI+Lz=0;Z!!aeFI$F2vZDOwAk7&tyL4?zKf!m%-UrzIPnJuSai8NS#67_t2
zd5%ih`lZAY7*j0dDLG2Z5hoXDm at NlgRvAtb@|4kVp#{aTG|6+r76P77>4;%CqAv<<
zo3z>EphB#gzY8JpLbobWY%!b?Z%C<>DidCMNR=eV(#qm#q0&Ak+0Gpo5(_vTT3}fc
zBr|)lqRbv9KBp`Q)bSo=N}cGzY_75^(Iji<WMZ<w?CGnpdx#3>xozpuB13z0lO7N3
zZt$mKD{NH7Pi(~@@t{zO1OKeZd6u4DarJTZ&*SJ<DD)&2ifVoY##<B{Cxpamcoj at w
zOA$2RQ?9nh35{OFl%M^n3Zsnd^vA`+LLg2Iaj!)!n!5?dFh%qbb4MEe-Lt|qv?wC3
zI3#Q%QF!U#TQ6c9qiq|}v?8 at YEa_}(V at Eg=C(Oz}h{<T)t7xjzg7AJhC00+O5G4l<
z2F*vS_b_veFp!$iR1GhHmqg5YqbVUYJ2VUa6NTh29HJH#*`GE)DTH{rFud1a7=Bt4
zJ$p5w)K*C|2x<CCA2gl*lh`;uB-UUJe4cTL)NUBDZ8Z}K{NSn-xr|ls;|8Pgi2*Qi
zAYlZ9mtOX>mh*klwzP3!Ws*@*Qmd*^prT2>8j|=y61FimdWHE3%-sibch{xV>-cKR
zMQK+%nxt2}U4^+C$3+)&PYTJNu4YfZ(|)sAexJ?P2UWfu#qDQ4Zs9eWivBErO9SAF
zMMtNFCX`QGqb<42l+>abPk#1#b_X7R=)`IQ)zU_$Y>hWw2GWF{ACr{dNzd%sGmhE(
zs`7l3hs<(;u`5{qfG(v9HuXw<N~KP*e*&|)#8=krA!DlqPlWwk*3ztGO3*AT%kS4B
zd8UJwiM340OG at f@m;44Pe7EGUl>7{D;+OhjQ=kQw=2YhOJUqoK$wDnG%`8)b7vwF?
z<Czi^Lt2`(OvykJGLb3iO+FGh&eEL3lpH6&W^&yu&B;tjAo-QTlzfd6ns84Phx_P}
zc|t*uj)#>4sBs|kBUHToH~+j&@72IGLX3)6JZy~$RI{BJnrQoj-0<t&aUSKdZbplu
z?H9a5*t9oNiSM!@|DXPPzAvkG at HNCT5u>TXnjl4x68qvy&TLLQD*#%r_km<mob96Q
zk&;?+a)Y$Ymbhk}by_8&Eu9f)tI~U at Q1&PuctUxzh`gO)D<(F>FFXgAm1!aI>`GfS
zv=PDz$R)>OSc{fJu^7Sfw at XE)ypIQo)_5a$W)WbUm{%1F{75f4YH7}3N`5C0&!V=^
zEX~<W$=}IG4wqtS&SOe^5KlFmCA$L61x)E~C}`^-Y*W0rpGXW*R_+00*9~3xLEVwN
zb`@2S+Pi8l0f604+>cj{d?XDV;Rj*m>ugKWNFd%zMvySX-W)D}dRJLn@@L^J&nf$W
z^2a-lx5_l3Q|xgp(fEpSv08t-U9IPzMNkR_O%lMEk`ErhRBha=;=IzzpSF9HKkbB|
zZ5j?J0EixJz``;REjF4`!R&+cBOuS$NT-i|C>bCur3<*RoR5+DabmN*8w?eAK_txE
zm;&FPT7F_P`5g$<OrcWW)PUVlVyS+l)Ley at uPhY{eTW4EyFY9Bt%+6NXPLPBfJakN
zNr&|x7>D|%YX=+v*Z}D%9xkn2;e`ZJUo at cw>$4U(3}Bb6<0381F-0DVePyUf)P9U0
zV{0jvfaZ$BQP(U=`?aNZrUY$;LK(ir>PUKi1zALh+^2}N-N%FFAh!5Hx_La#64JaF
zscBf$N)e6r6b)QiL+pg492V9`AvdO7qa(^c`3AnpuEeaLkdr6~3G6yYE+fEWc0JIg
zG(zI_Vz7P at xp7#m;SUoH8NgK)82EjtBm+J*z;8%T_}7c|EdOxjRiwMPK2eo1P`0@%
z6no-Dl!nVmIn#=X44gE)2hd{}|1F8Xkm(j*td1}%$ylKNU0BsUftx~L!9+p$XkrpW
zXECMELf6Rn4a3n==K0{1i-2Kj+$-mT at JG1Q^n}6Q5kfsUl0;<}U<Wj4h#oGKB5J}@
zq0sQFkR-s|iD(2h5RLxdsf6=Qco`oBRfIC(_W at C&Y9<p^$%TOH**Zt0u&zlmUW_nE
z<X$Wli)QNh+d$ED&{^N9Bs7(AExQ$$ws;urS_^TF(jqVq<fpBLJ)^GysHq&OUMqRr
z^KWUPh~`c9zAWFU0Wu}l-rZR@(O at dPLK7jZN*fFMVe`12EoIRz1va^$30oJL5e&)_
z-uZ;=(YQAeQ{A|MY0zvH-JD?C{MpAL!fu8;S84oRG?Y at w`N2Np!<3!{m}sJ>k?qj9
z%4rc5s5L864S3iw;RAXxL8TxU6Og)aH at FOwLeGr_cRn{1+)OSI+<fyYf_3fX#iKLL
zfv`W~&j4FK?rN4pLAEUVp|T+nU*SRU(U?)@F2zgaBg`GhwKfd0;WjuXii8h$h5yCa
zhGKXsY+C38PVIv}VA8JW1M2L6egRYBjXvyR4hK?HiJ^0Gva-zPI<gB1>s}GXs78QB
zI6^H4Pnu%ciaKHDUr4?p94q=eH+Qn{cOyq|?n$5e%QY&tmG~f|_`wjfilt~0*EDVm
zD=>n0;Mi+yx$wgp at FVWb)@8bSOk;bIB)EsI(%7ari|NTy?1;n}VA}F%^5El;XH$cn
zLH%0RfMQaL21<dSwh)?8#j)THfb~`UAe`$DZUomE+(@Rh at gXTeY5S9Yc-k)054r6$
zexQL?+YuV%VZ)0T*rWn<W}%aWjzP=+?(7ZS%|C{O!d>9{B|7WM at 5rQ?SKHogB(@?5
zjlL{2NK-K*h~-b>RnS_t_<oM0sHnIZzVQ7A0FmlHD!!k``2wv39|>j;^qWaQHGE(|
zbt%v{l`?AS^aS|dWkAwYE=@D~B&UYYY;GjDX6`9)3%Do1P2vVX=2Wh?W^@%`fa2zC
zt`oRsE&$vD&Kuk$^FmUJ3QOrpN(m;VFr*Y(|NSJapA at CSqI!~|f=N*fDasd%;(*jU
zs;=hnMxc at 9^<DU?sNKx=^Fg`Sq7F7zsmxc|m>Bz$>iy=PTahZk&X%%Wn0Km58=xNM
zol5n7QU+gb4 at CRGqhXtSyP8Goa|ljY>OrpiLH`eUshWiUZ}C#QfuC=em--4K{xdIC
zhAG<Tr52GW<fT&J>%Z|*7P%7dCh)P%yW8Wd*4!a{)!YEWR}IuU`Kly;8LEayzRFmM
zdd|zI3Ao+NC7jjG^5yF_{B at Z2@wmjxm#-2!zYpw-<uI)DCSCdRwa8V43)M}oW%KP-
zTsF%>3+Ullj)aa`zQz_8g!gwsVwuu^Nt~3Qk#JJ^&m$*Q(~6V2B>%6RRHfXFldAb2
zIjL?fP4#p(l_{Am9Rub#<roG at 0r_FzkOaO)!=EEO<?^kp<-XjkM8%Pd7$9wbLNi*4
zM!rs45gKYt*^NSq<qcZ?ga*Q6%a<2}rvt$4FE_6-lxtTL41BButQE9lEi)<(8p at 4j
zfC0*0=+MG+_0(AdFUkM_fEnFbFIYl$Z*W=|FkMPDFkm{X*G5PUY?vI`FyO+<wHsOW
zZhAq3EshC;I*|}}h~^m@>jZz;LDr&r-mDKCbn`EYfbDo~adfCT)DSamwYdvy{rCnK
z>e at Qj7vG~=9U at Ub2>r14F!0*d2Hsdkc*|*PXkS?MZSza81D9dx>{cX~g+Q|L8rNb5
z4c|-?8mxM`HvB%>?~P>$96U}QrG;Il>|~%!RvZ(`l-36#-7Tgv)_s9Qmtw3&4NPBL
z4IT&DeF=m4HO3e>;xo8c11R4(Px8Gbzl%ThML+5%Nd7y%l)u~);KpCpp;FJ1G*5}Y
zoaZ6&m&@c5e;Mx~@s|_HM*>qaoJ7Iy%qu95nLv2Vr#vJcGmh*Cm!bU{%knjHb09*3
zSn3!TKr#OfB_$<+sq!IQ&2LJ^vJ*amUQCLx{QzI3jb>jx at 2$7&Q`*A-C at IX}zJuKQ
zlp2@=v81#jA}}dAL at WmK^sY at QS!I-+UFKqEP48*SXRkt57NsM$IU-6H&~Uh>?9)R;
zr$+hLhdjZzX&`Dl#%TFN+KN3$r~TE8MBZg=_Y)8+)ZTWjrp=cCNkylI7TAUaU?J01
zk at 7_%Ang6eRLUgRK{or9)_ko6sE-p{DSKQGE35PaIWh))u)nr_^0sWSlLgL4MZ>^b
zbs%ujP`JG3?+zDpf1S1D5K%P}6J++U!R}F$#N<rXHh?U93N;{-l`wN}Aofe73Q&dN
zcB#9Z&c*9IgVnOkmR7^j- at o;6_$pe4gV_R{_YG8 at mWb;3t+Q_s%0*KiVk;*k-RwFi
z7Y<8^DP7 at 7jN~$<i#^E_fZ})ixr%q|5K|ffDQaZO_6E=HD>3dx#3F8b(Z_^wFPBS<
zdtbT4xXZ~05HC9js}9V2rbA-h=gKAKeKeFon0Fgm5uj~)%C8lqySg{5<SWQvt0V%{
z52ZQT(>ZRaE)S<5^7_BV<Fwdq4`joCPJ^5%6sYtlJ!-zL1D5nivu*1`BB{o-UrK5H
zA+07li1X1ac0<aW;k#{bLaG*_0HRzf7|^bF$px5l@)+AX<ra|-Bt-(z7hk3conga^
zhAkojGZ}e}zhGZTm)$e&<2>58^*H;uO&}c~EreZlu8)%Q4`5oup5YWL_}D$l=_7lT
zP};8DCj at GXTp=EpCzD5R at EYl2w^`**Xjds)LEF at 3UgLvQn;L2)hVE>W9uPYCw}3oD
zX(RU?Euu*IAD4y~W^Beg(&S6|prvO9US{*49IpyctxV#5r$AE!jm(d<truJ~Be-=%
z-CNBJFC@(QpKWXJyOj^f$@WhfL3DvyX=&M3xeDCl<6a>5t=p27*)vI7M&Mu>Q|O|c
zL9<zXS`QZIHduxfnSD6s(YD5`Guq^db;l6AtR0yR8Ma(Esm(5&K&4`#7t7zb`=a1R
z?O@^@8h-hDDz>@aN^BF)A7;bvJLNX2cI7q-R#8)?(1)M4ABAFIzc0N`1vjut^orAn
zXf>tRn36Z|k~_Ura8n9DAd5y0hzBJ%X5^X)Ca1Si0G$uK?V7H`?%^|K?P}XP7=E$_
z5L59tpd)@LKtz#&U2hH~0u&apna)01-OR)_V>2Y7&l4>|pB?>(I6zmfZD=F+(P2_e
z%(ON59-06j5}miJ=m0c$wV*oJ!h#gW^Ey88nn5m;WJF@{6EDcfnay06fXG<aA|KMV
z$cN6ik`Gz%%*fmgO518c at z2GX^j*Z<7Wt40VIrD)L7G=dnq95Z*cA}}h at j|Je^Dem
zUJw=0P&rVNOAZw8CI?EQa-et(Zz|UD=1P<TCAN|R8C+5z93v8feNCcLptReMN`VY6
zDbSr;L<*D`RT-mQ)m8`;?@xq4^{s?J&s`>01_tue>Zt at sTPam(#q>hsE#yheJF%_y
zzUW%^V`mNauFk5d5a`e?iu6h=3rN$rHl3Mqi%d8m3CZOFU*W?y at EVb+0eKnQvWJBC
z*K^MiS&W*<V!EI#hAHi-pxE8t)=@!d+Dr`|vI7EA9HfF7hX;|=2HF0iA1d2b{HTy`
zBLZ80+n7=2&TMg^e1thbZ>jQt5ZhizF(%3!jKRar9Wa;*XTHV=V6?|%aNWlMYdprx
zbsST`1&&GLe1W#vXhRAQ>kYE4#INE9LzvQ6C<+4}n{FDK7D^bYZP}_8Vi;*)iEIwv
zjbt#vHsm4AYWKO%N0V;i8bcvW52Py(BhR6;bs*b)$i5P?@egtB{HXZ3wQNRb`xUV_
zmCfjE^>Sx}56}h&usk86=wqW+Z8p6ApWAGng}loE4~c5;;o+p(sctoBI;*bMFmd&|
z)r9y7Am>nSR19n=Pm2UGvFnGh)Nb|b*MNFR#|@%2ER+-$#$urO%Nepa9`bBD2>~{w
zVt8$_Q<`LeenaRL!u~u^aatlw8cBpngNQIGgf@;yl=hIF=8)31gMN70zCmih-%d>1
zQGwD2G|I#Fri=^$OadZ+)4)eDe#C3}-zl><ZIwL-LE{DF9G7NP?>2h@=f%w;7=#M$
zrmYeha|x~<tmCIuq9o3MlDM1K$Z>j^rb0zcq?8ecaW}!&Zs}?fLdJVk+KZeR>5aCc
zA8%fR>yMwdkw{A4y$LId3|W+jmyRv>e3;UIP-acT&)#aDtOW*MZ{TZ;DF?KrM+=?-
z6hUD9T(elqb%+08`0oh+f$;AO|6Z269_HDG^5J^1k|1wOb%;@2RdmSi5k(0eaW{~6
z$S8X(hm~&<P+VZ!a|76g_piFxg}<F}ptj%w>G(dU<?z)$M96JPH|K=Jq}z|TBUaGy
zR+M0%jCWosmGQ0*ATnN*bhyiSrTd8?_^@1hLZ#BB+_i`fbCBRc>cdMzHUth#uQFtw
z)MGQ2%4K=WQFAljq^ojx8LVLoAjop5uWsS#Bt7qWhuLKaQCcp at x#|32VM&-MuENkp
zO^8y?g+tKoQ1bX*46c|;?jZY#!Nmyx-v-nd4vbl_ at YxlISRNu2U2(R-a!`bf$HRzS
zkIsV06(LML?hsvOz=-4rU(dMN{7gZ`-6-mf24q|iN*>sW=8i%?R~cw6+&&#<OEgZV
zF}QbP>pq-H=+bCR-dPO(bt*jpLK*?G+H1*U#@#w=@WLf%=e^krZ(#AB)p!G|I8~{9
zh=UmYsBOX^C%m2S=vn>-ikT?nLxi=z5eb=4{F`e8-XtSXuvk6TUI at _70_Yp~>-wsP
z0R54F6uO{4iTAwbf<9h+djRa*Dh#F2 at 1((}562+lG~q!T?A?U!u4;s#v}PTJ_Ixr-
zyY0P%u2PGxU3MiseazvqvhHSe4q;Dam!j8$IAl&vZbKWj!jB<%;59x737<gAq!4Az
z_)v_ncZMIHI_r291dvO;n1~-AWJys{)2uCab*DRJqB{N*f0rpG*PQqR!ig9nGSiHg
z%M4bpUkkuXX at IpRa=pQIaNYF$K|R0Q?Sh<M5m1S$x(+n5(JRb at NZOtxZLl8A5$tXy
zEbCH91Z91MYnNPW at bu5FX(x>?u<YEQjpIY)<^XVuxeMTWm{05Q{hgV-5WGZSuF$E+
z2blvbOO-P74+NtrbfP~B0U?eHL at NmXG}!)8Y+1B8UTH}Qxeid0$1<C1>{h4TJ<+Ay
z0Dys4_KrHQ>`iQG<_OwMBv1|r32!^l{LRlWwqHB&4jwk at _}f%Zddn<*{9WL9*srK1
zBzp0TqZiLK(f!R~NV|BZY0CT2%b#v)7tz8FDmss!y<56PEL<p|x6QOMDP7D1$lWex
zvrk&NLKAIjeW94Xk^6?(%)lmmUO1LXE;^B;b=ZT?Yxwd2vgzHG7e%t_o6Ew{Y$<f0
z^fW*NUp at Fz?$W71{`zE^5dhUmmqN{RsBh#B)I_JtITf|nfsJ5FMzy(zhG$a39~T_b
zZMR2Sig#o@$n}mr^s*Uk1F+Y4Gqs!=FE~${!RtK5VAEtO>_Q{-_RpyvI9oA{OB&JK
zLLSEj7K}#)CwCp at 03kV?Jh4inA)?u5D_Y&NhtZo_NK@)?H;rYt(pQmTMuM+SqDh`u
zs?EcBuE1<LxebL_!pPo$9+)i$iTz+^O9KrRd*TnLS*$wJ9+HpL$ZR>4rru9fB51eb
zjd}Q$htI at 5W#uyR`odFZAGnQ5HOYx-VrZm>uM&fI8zgfNUd$GVV7632)dQ-W_1NAL
z$(?x{Pkk$^+D(p^$W?o33g!TsBo`Jxdf6ea6tVui*+2)Jw`|9ulNSN?tvyel(;pUo
zLyH6uiLcjQjwOO8&jQPNIX(n~5WE7yZ1#+{;gQoL*VFkL+cq-IwC62bY2o1-{wmHx
zw(5ZrsTM)AfKV)*HD#ut*s|pv_h~y(V@>uDq4J!AzHg=z2BL%ZX*-hHSA%cd2!M=1
zJnP94IFbvCR;>ymBNYS_!kmF+uHvV3AzhyH4?6j$lA9!QX0uks`7)c0{i at C@{j1u&
z>z<?Mmxj3Aakq>eI|ZsTcd)WQTAI7(D=bwid;)OP_NK#WLoNvKiG?8hsB}Lu0r0Q<
zqnMCQ?51KCUj>}1(F&*}OJhx!moIOC9wzC^m*3Eq9O9Ja%bVFPL3STaxv5!GfqI}C
zgn>iplppMa{4|tRdcz#lv`-f6BQtx&Xd5_%*6$(z6HBHc>ME^d2cY347#!{eptD%`
zj~2?#0&x&+ at fU>`;mdiW^|_xM#G>7Yq1bt#cCe}L)Q*O~VecN>xKGI`p-LH4`6s&z
z#|3y-{s!8UC^zq6f55 at B*n+qSbOxZ)9UaDUH`ZLDRo~!GFmG1_-^w4c1CQ{F-3Pch
zy9a-Q-?t6Ql$B50KcI?^CpUprS8_39$xHenV^N^Y^%;wDDelR!C|lwNkCg$($#qay
zalLJ!gyjFt-kIHr(k8n<yAuUh*t!eburuYrp_bm at x>k671rxWizQ1<<+F~oalF{sk
zDCk)%*Ol3B>jA|1wIIs at PiP8+W3QO)R|4|9S$`>=3b5^VTTi<md<Stp at ZAd{gf+c@
zTUQ{p(@zNf)d}N!XAtAzC=1u&lb6|6)BCNl8eY2}rdxasc{amq>v6FXV;C^41(rXq
zq1I79)Z<(R)CWZ~rMwLFaNyAL`%o2!c|5^au_ZUS7%0P8D0HH+Z at UFzhs5BCZiSjh
z>r(uI5W1Ap_98sco%@g!bBMuxAOnzY3!x9fK<r4g?R`(_!RrP+p+hIpVm|y&#hlP#
zF?@s2{|w;*&x^rlAP6{yFNMRW5mbRVXdklby=HH=_%Jz_QJ6j9Q;C>}_ZL<pDMV at -
z?y89*ZLCl0*NoL+wVJYJN+qOhw=vPhY(-6|u1tH3DSep;YJnI26nV{(zc`Nf*YbNU
z2Sg!!Fv@)E5K7&J$<V-+(P*HYGeARLe*rkA>qrUU=~pFf11#c7p}Q{uNY~=!l|9Ts
zx|C^kkUTaFMc*Q~7YfH0EyCeJG+-mmNm|e!TCg1#^fp;6lyS=($ZH!0RGU5hZ`wWl
zZ@`#W!)zZv7S*M4PmGlT8sz%JFAuUBV!`VNzdU8c3caVy+*?zoO|o~}CPytjbi(*)
z$`&QrJrUc`h0K(EO(d~3FeR7oDPLa4lzvQ@`x-LQ22_p3e$iWwV+k_JQCBggX#Y)%
zS^;wLL;c(0AlCB0b8!T?UQ8(p?U-H0B*6H1IEMOS at NjGb_%+%((E(I>2V at En&;Sem
zHVWk{xjH9smfWVC22=8;6T)@uR<ghD at F8$xN(%5|hk7s96Q at Y>%H?&}cl;<b2WqUb
z4(zrK74tA#v~^=0u<x3Cz!;pF0YpgpNf+AV at 7s=HudqGlzNBtc<2`bqR6|!hO#yHb
z%k$2rb)&KNvCw<20D8{6(urK$dEm+X%|TjAJGJ>1=@e6Pn+B5H|GXu!P|uK)2ml7Q
zn*BjRYS5?bfxNKid(~;f_XwJK<XQq#V#VVf#d)pzj}@ovo;Xg at luz;3RG5;aRZx6+
z#Us;PqXbu%(z(qMHXpE$hXfs?S5yf>mFInwnvT)2(aVpSRRqWPXn)-pluDI^eQJmz
zpwf46n<%+KW%zVK`)dh0bD|;_76P2q)E7|^?9g~^N=D3c{h%S5IYjeFF?gGXAQ|rl
zAa7H80w2L5V+IW{Qr39ixZ>0hr2__Xd@!uNJe22P&km5D-F5ctCtbOxACMnIQ9SK>
zKSm7X2w&|(+s8now|%ywv*;Q`%iJ?EEqTAg0_~}VH5@{8JxlCBSPfwZY`ly<CCJfP
zDwP^Owi&M|55{iA;&#p-Fz{7`ZbJd<2;mA|QEMi=@UqYmGA at P)X;R453&H~<h^@gX
z3xN>@fJ-ls2*$K~B4+`7MvtyQ=8_+!A{QWhavV1pTec{@?bhKdAGdd5vE=0j@)D at H
zy;P*UO^C4Yc*~YQeIIW5w%2jTX2h0POWa8dk)m{Fo2u}N77`Hnk_KXa)DVl1_-I1v
zC4Yjvzb5)#_y&j=0huFVi-y$wbSVr>BB^^N3m)wr&j>7xB-%sEMXHPuZ3{%vC5?!k
zLv4y`%g2Wp%O|N4q at E3y8Lg89J#f7c+MwZ;z;WYiM&SW2G-CRU(H`WHG>)Zk0d|1p
zt2AgPOv~3Bfb at a^BMS&6`WhZ4^ig1Qg&oe<CGFaCb=s6d-Pimri5tTQo$>h&B7}y0
zEaVZ+CaTi5jGQ?b1x-w{(%hL|%t84=P%z-Z$>heiXbu++9dk{!?R)U-yDc|Ip1?mv
z(l>JT?025b=59LipiZpOlo<SabJNMIQf9L^%WOFYLCW4tDX at H^t%k5%gUnt?ZjDD~
zvFf4{vZeXgr>Um|<pzM;Dc?IyF{O(=6u!IW_5n8}KLkR0*gG*>sv9-R-a(v_+5EP$
zH#sQV?5z{`v3#W#tKs6YW+;7+eGW886Ftz3ZP;U<0_oCNps*ovn#R8p0xQ!rYL-;V
zk}BCQ_Hg*_ni~dgNPb at k>0$4V32B{v%;pkOr`?m}R#%(5r2)H6b_V1UOYya^4R~U)
zXQk!52VU}~fOC68<+5 at Q3t}#^)Wr0=^WAC?p~)UQ-h^*&AP>e|dI~zztFMF~pJFEb
zxB&cktKnt0Iz-z^nR9rr9c__+R6lljx67QvyWSJ|b~3yZN;KVjb59|VJK^y1br2HL
z+x#N4rQZG=jx2(^&K^jH_JT6ae?R16Hg^TEL&_e#xiD#fj at f&<4bU;n;f<34W&#e8
z`iMC+t+bZ&!sNx2mG98zt(fEg3epH?Li?iVg>Xj+t=S{XA4$5DDwc1k(VmBNV)^XL
zmSzXgUB{0&#3(>_!Z$};BE7xdL;zjOlzj?cYOhXdz&%@5lLsg_41BY}8hHEkLs4HP
zdReaYoy5O-7jJCo7B(hTXoe}*%9)Z(NK0Q$FYYGf9YK657>+nc$Tr6tG5J+QP0zsR
zS`VgllsDBqaYR#*IV_spiu{Gv<4?B!A<OJK1a!h&V6eJ~wPt^QcT at dZIk(nw$zkAc
z+2=~XS0Ayn>IRk>*8r&I4^Nk>=bpmP^$w?%W`TU-d8+Na7v4tFMIF^x$H|5C-|^Tk
zuora8z&A|dOGuXt<+CDVoj>&aaeC0wsEJhSm=Zi<s4ztOvZMDiB}l_yckoP!E$iUS
zgQh}R#VNh at dAZg)w at Fi`iS*T${K?I8CV&EBpa5=4>1obb=I6?%IHeP-Axkr6iD8Q$
z%FRRF@{Gnjy&+HcmOM1WUC4 at gMmvWEh=Ma3Tr~m1B- at _pW2jE5GUPE*rk#Q1UbYOr
zA(6VC`P)mL$ozYCJoON$qKi;^Gr5lkoi1idM&c!x;)fnUli;!WQM`NojGx)3*bu4o
zw0jk&Mk?<Eou%i`8u at E_#XjJJ1cUkpW9f-h?@nYu*b1#|Ob_}fg&n<z3&b}LyY=E;
zTOAc?2s&}UK`rEU(_6Lj;%Gm!x8AbX!(L?I1sfhlL(iI>Jp<A;3A;uqHYh~uqebl$
z-&fJEw3y{*xMb*8%*ltMd#7|<kK*M?eq3Ko*#KwB722dS%`jiPTCYB9_Qz<m*FJ at x
zJsc*CL>nRlGhDz&rAdBJ>ZOK<BFET$;Ijcfp)BZ=LA^*|UJgJZT3`1nV=25m?7j#K
z(tQnoNgIBpc==p8Q+mWhBL4T2hh7I86~$&ewzhpIle96~8OuG-72Tk9xt;K_M>Vrq
zF)n(itoV6_jJwQi_8-UWDv{$aVgdc=A*W;z_HvsUN);;s(JRSy#0LB9*5FV>Rb?=*
zE%!W at b*xZ0VS=HWVKJ6_3iBhOqp_s$2770KPtz$U^?X$5coj$n?PUYMD4q>Jdqkl2
zW|5wYI=T(@ry0=Bff)Q(4B`V6d<KibL8A$wIvW~|%{>5xsdw|U&+DvS%TGKMpOYFJ
z%e+&gRa`D#7OAs+jxS)2ZpX#R1*WkvUH{{RoJ%I8sbxX}AA>4EU``H2nIWs*!v&?G
ze1EqG&O95D#PZs?K#@9dV)lTE>5&!_WcGz<discS^Vdh`W&@p at D7e9rq{(?DnoP+K
zVsK~-l{%rpT9}}~ixA11*W1V2PEs}LU0Tev1}-*DQ$C<V+u*DVr)q`vq}$IJXWp{J
z$kBEK&f*|fepJHL+5R*Pm9C~5_X0qG3L)(`Q6x#A_O4Jnsi~_yz!~O&VNfpu1?Kf!
z=H<Pp60m=}^E!Znl!A~>Z5TkD21fN?oD%hoPkjl7_r8N=G-vqT_8DSu_h{t&yZ~Ph
zIOsaci6)=qh7(IJ#w{{?^5^WEP at e@v*`9oe8XfFC1m+;wV}t{)tiNn`NNSRjT10Ix
z%-&tsqE{F<N_SHs^t9`D>9ni6upLT^It|qP8?It)D3*&lje8>=J*vkxzKDC{8)OPx
zHSkS(a_l(vHUzVl%YBUtFXPEq6D&xBiX44q0Ov*Dy)*A3-_S)!I6zJmpFH5)AMJQJ
z`Kyv1k2Q^J)Toqlt|K`g`vqdUH6uG<4;Jp#x_ZlyGU(yhBwunA*@MJG!9TYotK8-~
z8X^yx=91$vmw5|ngL_3Pl^6IC-Sxu!bWv>dS{W{vd2n6m+TISNbu4Suc?f;CI7BL$
z*M1MoAMZ62(rNhW0SDNodd+}JjenJ<+)E3A|AQ^=XS%xV1nYRYmIr)s3r%So`Mbb4
z0*%A+zp(sIQKA?;X{3xAo+k9-&oVR&+ at 9U&|7sZc-V%qq?Pxc{z_Hm5 at jn>`rq-Zo
zlf>ZdBgm0P44?_tQj5ApVXa4#1a*W<C#t5GNd~s<zC?5=?Z=}Yu at F2W%iTios5ETJ
z<17TXelH*IvJV_7*@X^TK<xt;%jgBHNCSV67<$$al{6-52UsU-SAAB?vwSi)P+3-Y
z;pG|^t)0C^I%`FB5`<?BERK=OP_^ow!8$Q4DoQ2;9+7C;v`zlbA-2_F5{n8<NPA)R
z-Gv1x%*}9+%l(6a4LZ%1EK~G0_XUzY7{gRLz6?(%#xYwwXAIbfD)R8mhD=K6M6}e2
z$VUlg%JAy=YW|3H1jg@&NkyK8)zvuzQJhh0n at Pf?w2GFr<6LPKuCznl(|WX|?dnSF
z;Y#b_o>poDyVVE2Y*(pHCT9c<g)E09T}^HBpt1?u_ighiXr2#R<xx2E;6pOoik3V?
zN<=~-PkQ@#remH-ZSzd0d7 at l-Xeaq2S}WTD^4Yp$j59E*7K3eG7$%kP*#f6)51nxG
zbiwJ=LpL}nThdm$(kfkP*FAKe4N=()TF%0Ig#0O?TRK%xG1v&pbvV0nspqHAe)C}0
z at X<?fnGeYVfVnfkeeT$UT at y+JflhHlEAdGkzQ7Ynznt%ms1A2``%}21;0)Jo)$$jN
zFu_;AayG(@Rv62N8cY8)4-tm#aV at Am8y#Z172D2HnJ^c?S{`^TI|y#*ioI-wS%$AR
zRZ*heI$O><PXl`pJ<+ku=AX#zQ6c{X!UBTqo%DP$E+LG=^H9rqC2FONt%w3z&c2KP
zn%EABEp|khy)1`3?B4JhZuX|}P``N~1VnO5b|+E>_EE*^0xqyvorED+l|7W*N$z%A
z9t4>~Fs->0rtyL_W~e4ljzocx--?Yerkp`kv0v0T-A3K2{C;ef7TOiZ^7}0pJUQQ3
zX4i4c?~(Q%?8@^v!MUfb6F$bkF?dAyyUJ2s%c_s%b+;T+>eY91!^}Q>wO(DlxR>RS
zCqUV(0s=X<ajz0J&Nk{9?XOXyJx9+U)G^;4=I`kgccq at cqT3}(cI9L7mSz~Za`Oa!
zFYw|VqeICo{uS%gck_J#nLnvhI~ETT7FXlYp`sN`&w1-Chedl(Y{lMCkH!YnW!!X5
zr*M$r)|dB*#Ve%>2x}Kv)wmm<0zXgJ%J`HdYlEE-jgM8wcy$;dmk|q@{1LOS&KkJ5
zj~sRO)(VRrI`z0fdU6J@=c{NgoQgm_O?ucOi^DWytD<mvIg_Bc6>$nFwy(3;uC7d&
zr%jR0EW(WkuA-$geWF>AJYN+)-sm!6*E0qJxL{#Km4lEQ{=yLW!Y!y=spDNo{B;KY
z2wvq-Ynjb{s7Y5k9`<A{RVoMqw%6^zm}p$oqKrkOuI1`9;kB%!M(#h!9EoynNdU!^
z5FwEyefoJGHVy?$)=JkJU9$dh8slumP63mC<pZKLu7;e^7j%)C`x&7DRCa}raYzA)
zZqgn5L|wRp*&OgRxlQuXIiOHBcffDHL0EMTA0h73i*=k5keR2tf%_%A;gMr?p!z(V
zD5_n79MRh~_LpIJ&OVB2zTEVqt6%^6*6~=)mqcA9(CjGmC*R*VTHe_@^^vjsO(Wj`
z3mLF*=}~itko04VNL=$R5s9O^I2_MQ`#i`y3ck9j0kusvoz#g{2B6Rag#MU|Xi41<
zqwOG{>fQO at Mb#SlY9e#k=MiDFj+0v_oohO0<o8D%<!hQ6`DV*K-^E_V)zj^Y;_67Y
zEQsipCKQ5ReK7YVIvpS{(80Tad6<s}OZ!l2u%E4vvlU9VOvaY^>WMOHqk4a?&1DnO
zP4yX-cU$iInLCu$lFRmF+S|RT3Z>s2?rS8flB85ZN>AuY6VZrN<7mD1NWKj%`5psP
zofD{vT`fSp{tW@@y8jN;LqE8HYMtPM=>{iEJGjAACjk{O5>nHTgR9O7*k4)zn+~<u
zQva_2>jp1hT`PdKhAD;D at s_a1>HpNHkT<`-YxoO*5sH8^`B at LBZ+;*W6b-r*4ZQ?5
zx3sbd7EwJeOhX`w at i-OqtQS(~8vY<&mj6W};(=J7`2;|)TX+LGF16|$jIN5%Ii;r=
zP1S$U&Ixo20kgOtb?5s^T2jRQ;q}&WBJf7;@><Iu^N~FQ at OXv$I$5H@{10mgm-*RR
z!h&kbwZItJ%BMk4m7(0EWXaQoQn6?}e*$nb8-4=#kmwN3SFfnSCtCawzAC(0(adkc
zd+Vi*MNg0mmuz at VbPr5)0viNL_A74MJ3&_U-Q~xC>_EGx>YK~{((s$`uu2PCs*j!r
z9xunUROIk!Z7HhNR6ERmM9yKGjtBkfrXnRiB7Tni5R3c>yliUnP-R*WVVPDuL0F~_
zpvg~ImIry{o{pZ~RcF<9<&H)t$+<&pg;6$Ind>!LCtv(2J~WFCv0sLEN07w-bS7Sn
ziQi%?0zx6NFC=DO$wQ$!&2V1BA2#xP$z40B71oyXx?S-gd{;!YQKG^&y^Aj_N~4^l
zzNv|DlG7(y4bQqb$w((Bslew!$U<((BrK%Cni?8ORQd12v-29yP>GRjn(L6P5;_ at 4
zy=4zDk_P?~N&a^{2&b)-(^leZ<iQ4dMdjo`Dy{v448B$gY-c;2`F<dFM!<x--I!s0
z(_fSshAu?>cV_s{g%UFi{3_~{TUz5I^&x7mOR1=f8LlDB at O?};)!8yv2Qnp2R}2mz
z9pL)#(>#Hn)nZ5YxW_98;{9r!HLivI9XZEA>?F2?446Z&P#Fg!LmW08)iIi)TM2er
z<ITA)J~&q5gOx8(J{Xq|FPV?RXk>$<%Tae7gyO41a=DGCHuRjlGQmU7KOme!l0>-0
zyK$L0xZn$j8o}Llb&uG$Y)@Y;o^5h7AFr(TGnrFaZKtiSEn58IvC3)-+A6Enp6BC(
zVC8o)K!q*pYVS0PqJ1<UtJIO;pPcGy+v=*td$?!?Q+R8OOE6XPKPj%I7y2w?7d?S=
zhL?@%nyIy2aoyu1un8d(pyjT)5!oX_ht>;j3d7TJhzlYyjSkPx8=Y5(JzdQaZhlU$
z5XX at 7-udJT@nL}%VXib7(GcNYN^r5_al9IQ0_~#7M4GA)l2g^Dv8|A`%Z{7TMci5g
zzm|(4(KQZZ>mDwwhw$)6!v_N|K^`s>`t<+}OqU}VDsA^2t;0WAPs1;@3BU9M4L>OH
z*_J<aZt8XEg&nk2vlW at yTBKTIHB>|HH~nxRy^ePyCJ1$u?$hysd%MvKx~R3|u7mRy
zgOLu9l!iXeo}P4*`}Zgj&&npsVQ^v&QzNN(!zv!aJb(cENf>aL-oD|+qM_;V20T7~
ztxAR$eqZg6wp#I0y>+ at 0xp~xw`z_W at O|1?ShHi2l(hb;zcljQ(m!h;1hi5z9(S%B0
zRFI<s4ZmBjKBwb<(K5yw2=;lJT<(F6uBI(1>S;eM*fye$4llF6 at Z(13eK;M_j&Tg~
zbXE|%DgAKO!^8msNDNj$8|~8yXA>>4zd)jAesbQOLS6I_P<6{eUyMYm&`OuY^5IK8
zQ8b4M&$}uT781qG4Px+6r~+l<fOg6GFBGmPg<m-2EWF8qf^A!qr1P1`t5q&}wRE at M
z^&qC>M)C;4I?<oJ_(tjUD?~b-q?60?igbLFfxoJ+df;WSM$CX9%ay)(T04o?{3c^|
z86xS67<y6vJt~ym^*w!8@$UB$v1!-CqR~NTSCMQe at 0W8O=#~AdheRSBAk4?q<XU?O
z1Xn|9dv_sEDr!<or11176razc!%IiDMFx$BN1gzgriPxCE}gcm>0<hLhQ9 at C`k9*!
zdhIJnxVpjhEC=wyR1MMZi#PxVD7`PrSuveb4F0MwwQnOmo4F48>~*eZGb1Lp|7^zj
z8le^4`j~e!8n<^dIU6Vlbgt%+t3jo;1$pYR-%o%+TG;B{%*F}rzng*GQ`mFE;r?z0
z&jnc5yBQdTuENFdTmt{5??}b;U|{%7qFJ}6aDj#j+gcKS{!h1)fmUy32;2>*z@&F?
zXqJ&`dC^N+UY_Fv4vwqP$fGAPn`g<D9+m9MOUMLkm|gYkk$Wre;ay8E3493Ubl~Id
z%E9P+$T$`Ho-(s;T(Lo}EPjsnJUFg6RTjMxe#@fe_Q*EjFOzT&dkFlJD_7Wqobdq|
zFOM$9_i;Yt{<fWAn@;tt43kyLWM0?^qQpp&V*??C%^CzgHmfiA*sN~C7wcV{%iC*!
z8zwVf`M1C=Pg3p2#Bc+ZgLflx04Z_0E3qH%RRM|1<t|;;_>S$-^-Gqo1fEC<JcA|h
zNMPYYBrpXDjH at c5K^bRNpm6V7=kVE=!&J&pkDaf9sg&Gmy=Q11S?}ItE{#T;_19X~
zvo}npK(d_u=tSxuyyvQbPN19D9Q2V}u`5DY^s(C`w>C?;j@<dIB<5ezG%<2O$G|qC
z<r#G~8W61$!`|-&NH^?5;(kQjHN^cFaX%&Q=fqu0+^>lHHF4JwcRg`85O*VSHxqX&
zakmq9CvkTXx01Nk#N9*OeZ<{Q+ylg|BkoVcttakL;vOUJapE=*_Y`r at 5ce!`&lC3|
zaW5113ULM6ub$|>P25+ATR_}-#NFA0^ozJ_i2EjSONhIexbulSleh-rK119{;`S$Q
z7vg#ox4ApIzZ3TiaepFiC2=<p_fz7&OWZQzE+K9vDd9!(9Z%fq9(bUGe7KQ6Qd-M}
zs}FEqta`t>KZ>gh at D^YW3YzDm&N`q94^S=8uYZWAgH=wspxYZr{$!LWq+TMr+2z*h
za$)@iWS7Xf+X%qh6^fEdZs3^yW*?onTdcABvSkXrhzc+<#(V{tPzciTRdyfY!BmIn
zlr21>6O73HTIkJ4s-#>S)oAFK6T(_2dk815Iz;J6v6$#F^ji8YYE>e73xxb+@}Q=V
zrMas)*w7Caw3`8ibss<n(XJ7426OSnS*NI@!WjiQ>GvV0Y4(wLZrB0kDhGvX62tW;
zwiP3K!$Mk*N@%RT`}HPN-99VE>lp1x6es#4;r{GJ2f5S)xktd~IIAHtK*QUp4TU#<
z7bOObDOnF8`;dyk(@B)}R+Um~sw?GGk=I`cVry!MxP2D#Ytdao&BSPM7&O74KF`g8
zp1;=%Ik{huRDPLc=k$+Qjo9`+beb(56Z#bQBxFhJg|E;_mN=TF>mylS!7SLN!3N3H
z)nTFk;}Xvxi6MoCG&t0Uh+2dmFiflXk%~aMOcOIwHAqg))iL94l#jd?0D<Kr{UJ~|
z^%bD25I*n}go#z<fk(mTtHSq<B^T2=3){cK^KmSHPdwg&vyTIg!5F^Bps0}y<MGFY
z8GjHqC`x$sE3#?g at EsNu9%T4F5f)=;bRhShkV#6TElm0i$cZN(=}-B4$fC3j&3ljZ
z5~tW0Y)7pyG9D?#n%08c`9zXLnUgj;(xXIcoLo=<f3+&=G%|1M-bdr*vgNaMDYtdJ
z*Sc6F`^VgnaT9fXmm7`aLM+@^<b_@!98>UX7|#dXYGfgzyUtQLSjKe{f|6kyr~&pX
z6p}0?NxC4l^(y2NciUG}TL at W~oo_VT+6{3#<Ar60S9%Shz#7)Wa$i1)vb}?Zr at wS<
zp`q{5r{mFWPrmTx7hZ9XDNvgGA}x1N5N12m&TDmMm&k1P=Z}nQ)W~~#a$$%g{7YaZ
zR$Wvwo2&fm)wfXb(NfVKgfe|tRQK)P>YF-7b03nH)S9cJ4Yc}Jr!tS6B9nd176P+~
zo^QZb4)j28p<*p1tLCk35ztOvO}5PVrs}(p-h5gNo*PV_IGDSN!C}GVs#7kc7b4ao
z*JB^FHptv>t(@!KxZ8sRI(e=00*nx_*7bzvD4{LT5Gmf*$Zta^yZyyVtitcxP{EQ=
zb&<@!Jt|<&+eCfdHVOvqciw0a9$ujlvF>^B?Sb(0jCM+cm`I`bV`6lI;xRF?f-R~2
zm;&K&doh+Dkjj*C{^TrJxO$=8+;ZTgd8H6GS$wo}wBPG4w9~z9sBA at etGzO5RKeq;
zX15zf7{GClj~di&6k&%09-r&x`Ie|Q<4v+2Ise$KoBvDJcORd1>3_-kLc3W>RP5uk
zlA=|Q&+7GGYW?lp<Kpq^9z`bCADtnAz8<JD=!H%)*`pN`rHHSdYp+ct>ZQllxy>Kr
zr?i*VvRoxI57MPf1J3t=j;}^O6E at GPXx9@CJ?~jbU#KYfY4|$6 at Y3Vf)A!TbYaGGM
z$IiBwDaEM5XCr*@d!q?PKOpR!)}|A!`ay~+Z?`C1=~3;~kIQ*qd#DDn#y9QaAW}{L
z_NsyH(C;zfw|;FGymMuo5 at L_F7c2BHckit`s)(vx84ZZGl6kv|uOg&sJ7{u6+d?B<
zQK?c?<fBpgwo#-haZ^!jQ3=WFY5#{OJ_eYD?V$h!=G^wto-tZ at KcPJ^(>H!++UbL3
z`3M;oZCM at -Trtee$X0VRY*hPmGZN<Jujkw8wq<#wjEmCo({f0;{d6gQ(qknk?Zn7O
zOXK~7x7!xv?Bvq+kOG<go2EVnV7m6QU|CPK9}z2bZ5u&Gj}UYG>2?~{vXJ7RmKIXp
z)c?AWVo$duk^TSh at 40XV@s*MvBKbv<pC$RTB!8gfkCyz#A&OSzT at 0hY>%&@yACS^*
zm;7~-|1ZgZQ}SPy{2a+|XjA^=K~j4pKU4CTNq(8+zc2agB!8FWAC>%zl7CC`y$4gj
zhvW~H{Be?>DESK{zew`mmHZ8oKYAGTpOpMqsr(MoZ$~8cf0z7IlD|jtH%R`6l3yYD
zOC&#4@)IS0wB)NK-&^wUJVpJ>l3yqJ+a>=i$zLt`Ws;vG`8vrTE%`&Ge)O08E|Tx*
zgyTT!pOO4}$?qZcdzbWkz2vWv{4&X3BKet;|GeZ+ko-u=?<M&Gl0RH(-*ZwuA<}Qh
zP^n##e_8VHN%OYLlM>t{|4GT$NdAkGzfAI9mHhW5e}m*7ko+@}e@*fqNPbWR_4`Qv
zP|1&#{Hc<kCiyQ*{u;^ODEa#(|DxnKO1`($uU?WrO7h1^zCrSnB!7YA7fAjqlD|sw
zKbQOslD}W_j}L9V4nGQS{riSA|1V4aami1T*6(wYKSJ^cOMZytD<%Kl6V(4h@=r<r
ze#zf1`Cm!?YRRvV{Kb;LK=PlL{Be>$T=IuVejmy2Ao&jlx9(S+)X(#hzr9VrANRNR
zGZ|63(jb=;zu-OUul|twZU44D>p{ZHCQ1J1vUbz8_g5Xh(uh9pZJF at THG9aoiykCy
ze6A^(Gifq%O(|S<ZlP*$Sl$yDZcNU3KEsqBmo_0I)8q<urpG`?k&}^?F2%Kk(}0Yu
zv`h%lW~HifO`JJ5D^C at c3i+k*)`2bI`m79YxO?QVp~Hucg!oxfUly72@{-d{bLM3i
zkl(4!md{BcEs%<nr9n&FgVIghoZReeZqEFLrb6j=UXCdxBRO+UT6SitDR)jzGB;mF
zv&_kxpPkF4m^s<_1ii*EXF}ZM#01)Z@;iQN+{CG at F~RwJe4No3H`y&%3QtI6rzTE|
zm$gaP5-f#lv<Z_E<Ki{?soL?0aZ_isN&jfH6wk)TYuH4#b$v$d<Z12HM}lRBjCr&2
zGB{I2PIAgZ0AwBjRw{!0C8XqL<ZyYjT))Rp)yG5Mby`-VothwvH?WBY{W#a$ik~)B
zi@)_*d0cWP3}HrgmMSe7pr1Mv<Fm3=dFGV)DhlJ4iDb at Nn3bKMr6TQ=g7dIG-9!_Y
zKnG?5$rBI5!phRjSt+FKtZYt|ycjA-o|kEYJo8PNnNh=sre<c6awm|gRa~};j-<*t
zlBz*rd4p6DDpPK5cCIS2AdJqR1QRzsJ9i;WWY-!P{6yPCG at U*rJIj!rLb~`!8i;3e
z)6I)aSzKOw1wg#Ult+L|vr`y7*-m?~!;eic#cawg)Ms&~+_dBr(_nqPDK{@8kHdx6
zs at Cz@bVZVJ$x1OjuD-myyk+p8;q2%5Y+Ql>{EQ{-=E)#=GGqyH6B4JhQ?;|=3%U8(
zS&}zCJJ&QTEOlsD>MUtOU}wlYnUScAo2-j7YR87*IL9Suu~6Cb$(d#o{Um?$%o&+n
zMpm9{eia(Bv(o2G$jx5#e0D}^JeTVXhfH%OWalnQ=ICz#|D5>b+&ojFIR|HkGu at nV
zP-H5phx{HtL7GZ)CY$o%cig-MFz$0;+OZs$o51D5T#&VdC$tUMFUo-#HHUh}>{K(U
zY^pgc3$Y<xKSPHOb-~k|nMx*Yc8)1am6M%^y+g=E(Al60%k!h{oRE=4z%I2LN}Q9B
zu?YI&teb`>6z0vLvu!cW*D_%6d&rO>s+Kx4vy)R*bZAr%<APf}6v#Q at gHtXyJ3Tjf
z(d6VsPQb;%ipfq>Eix^F716Jyf82bNDks+zk>S4HrJm5~66i<zot!nOb^U2Dh1_yF
zGYt+)eS*S|%UEPmIj6#~$VinjIn|_sWjR`c(a at Yi*>DIayUh6PoI)wWZThst$1OJH
z=H~*YqlsEzBH;zjgaeoiTOMu|vZ7Qo$*<2^44_O^rKF{&CUeQEMak(IDXJ{<qIrnD
z@=PYxyi{0kbMiB?up`hUiq8_E at p-DL*^831oa at +}qY87)<Cgk!P3ceolm<nlX6LI?
zGL!T2X!@b10w?^*@98APc#=T+OPrsPr<$IzBsn(~3IH%V!5NmP0w5P=n{!nu*^6?_
zP{UBw_{@xyg{sM>0*+wBY=Ci=*`$Jz7>`IH6GKe}85|i_+GJX`bNb2>veUTyWLVYh
ztn<9Ki=50SGT6@}S^^(hH8?HX3{*fymeliH0<p)JOUuz@<NU!rLYhB=@>H$n99Niw
zNnvdyXQi8DIV4e7Dj*-S6|`*!;v{Ka;vh&x0l%2-oS&^qceNP-<81fPmi{en>0hqt
zB{OUtfF|?jXTVOEpPWa=`LRW``jg6oaxz+qB5Q at ik(PGpp)fd^fQ{OKAX{b5GmR$Y
zOv{p at BxKPaMrSH4-o>V{Je*ejRS{+t28QKDIOlF=b~;`Pm*vls$=W2BMUIG6O*N&f
zG~-kRb&giOKr+t`%NyHzJ>{8ToJ at tP#RS7 at GV*dVlM7v##MwWDKQ4#J;jVHgnF>j%
zv)f&tluUzmMdTE^Mo%V-iHU(#2FXZniWlfSHRq<7T0#&HwxUVkGZ$z<RoIND!WKP+
zjnRz`Ga^<b8Iq-P9)VE%cwB0oOg1CitV+$60AX5$V=_N^F_0bRw6u(r3?K(o$tfv7
zw5oD5(&uw|emHJ8vWt>a=4WJ?FoSamlkhxgVMz7rCTVBP89#06RPE%%InxrfQ{BT2
zapPIT93wkkr=P5qwcqbF=n4=?kL!4R%ZB7a<5G^HeiVJ+{GC9;RP)RnM<-qztdZ};
z8d!fW>|9crw8+uWMZia}y|s`MNwft~fUg1fOZ#Tae3;dS5RK0?CFhx7aY41P&H%yZ
zN;^`{BR#;~H^Q~T>7PDtTAnGF&0<p*Wn?+=tIVBVBojmh%WN_746s#YlVKa2fE1>-
zzyvg;lWjq0!mb4^NOmITj5GvE9*1kJzbZW&3Y==nftf5#&{ROS80DO=qupZj$-Emn
z4=I_Jc?LO5E$iTsaJt-pj&4m(IQ!e04uF=b+S{=yO at Mz9xn%XX;1OxaO{x9px=1Da
zWS%NH3p=lJ@?9AwL|d3O^?yz0=Sl-J!9703)!uogR)xC#{lBr^Trg{A#X;NLr=x2F
z$M9C at P>N{@mk?4*`bWtSw{R!<B5O(SPVSI$-O!w?|7 at -aH+kr<^pT&OMK*T|FF*HP
zLzM<pb8C{|S!X%YdIFLlEhBeP8+s4oQ(EIYK!k)$lDX)tp{nHEblkKsO#~sH(4C$O
z<hqkyf&w8CX?$2-SPEGugltyj0KX1Rf+E#!-$Nx|H8>Z!HKY at OK8*vGX%SGj6Ec(2
zCHfbLbxNMYy1*QW2k4XnNB~Wi?IOSpK!Fl0LG~ecy1c!7DXs)9c)^^tBqOH{b%0qU
zyh6iW1vv|F(#wybm1R>+$*F~I$lp0Gttqy7KsHbUqE#6HSHKr4eOj9tusFk%kBcg0
zKGH<61Pd`KnE-8;zlj5!nV$C~P at h=eIG8X_YOx*4Fu#Q+90vqF5FNR5=qj6oG-Ymf
zrV|~>va at ptWU{ie$bw2XbJ^$vMU#R7?c^o>mYO%miN&%c0%DPgOGZN62_HbxD7um8
zFW2vEX^uF5OB0Fmlc}&9rDYQt6KM;V!DY6hvk}=N{{ujx)ITDoWFY-p at DHK8UCD6P
z1Lv8US?HoG<`qf=eV&XGQqFnSY8 at r#0v1~A;!f$`yOBQmPbPP`wtb54d)@ae at _GHv
zf}D|`rPw}sC-tM at Wv4rQy7f$9AKNeI%T6Bsd$?h<?+?qqEAolhdi9OoKdwp*+S2=$
zYW)J;OWSUrWp|Y<KX$5z{qnDirffQPr>690%k!%<J6En<n7ZWdyoZ0(nkwRE$-A7)
z^iD|`%iQ}bP-)$-%2K}=lwr8c&iy6#rSyLtxvUs7 at tEhNhoyl>7jE+V?B3c<BQsZT
z7<asO$LZL+JHNh^*)ZHZ>zwv*;PEpv#vb|i*O4a&j+ULBQat6v{;tXOKW at 6SvEP6_
z-#`D}JKGO4pZ&1)qpco;m1SOYHk=ID7i#nW?r+PopXz9spY-qE$yH+`(l)PR&n)(S
z>9l;O>gehrLBCutFa7SNzMD3Ce|GuDkE4!l75-K0Q!wJLjCpOX at 4F$ZJ6zZixL`%Z
z*hR{}XQsX(pOtdu&Xk1<=Ot(MYKSzIPL|EP_2)a at nM*&D_pG|3e0lmF=C6Gx*PG&P
zTRQ!|br-*^Y}<o#y?>pjk2n>4d)d#gnheM8Cnaw%{xoINXim2ClZ%l%j<KJed+x+L
z4PzJWIr8cKJI8-sV9OZ);AGZ_31#Wu)Nh at 8DlfuQ^ILC4)EtA~SGCIme;xCZSNvD3
z$Dp7f|6Q-B0&2rH&7b~#X|~GuSlYIaFDL)h;qKWNSJ$3=qW|jp^&8iosOdKL`xz?(
zHx5<L`eDmAncFK>maTto{{F}J11 at e>ynpmNE at t8{zki#5^dG?kPkUOrp2_RvpK_^0
zo%;4O3l;^gow;C%|KSdo{~`LmHE5m8 at 4JtDmTTT(ZXEqY`M3GE<b52~-Wju}&ucoE
zZYq9hRA%?9-V3u9_dMn}AO3Us%q6FS>Yn>GJ^S3YyLYeedTso!E!}>3ZT(!~ljFyW
z-a7KnJ=G1-Q*WJ%yP3Y at Nc!}hpa1H;>Dfu6Ht0@;2R0ab`hDB at oMP16C7$f=>vPXd
zJD0xp`fFLk3U_5pc=h|_gFP&1JJ%e|4jXlG{?vE!1L_nL{da8Z>e2tHfnL*gskiSP
z?Ek}tH)n1P_gwJ(tS`h9)x!?gZ{j~X`DE{PXJ1%fo%+GRTPc5h_{jpZ-&>13zV!C}
z at Yzuv?4{{Gxt*uWyk36p$9K9c*?MtZ_;*XAdu|T+;I*S~2JZUhw=LJtEbDjfwEwZA
zKff~W;<1~}-~T#4%W|skp{~1DzA$iG<Awb7+4&Q<gj|`aEX!HIhzHc(X|w$09mS7K
zuV<{A*Zi}%Fj;#zvunXczcts62A)W?cuubVUJ;W#F#U_Bu5;^+6EpOu^Ru3LZo!dt
zXJ#HhndW~k_J+FQ>4bGVzuf!Lj<YKcZ<uHkH%0ck^}`Pp)!Pq5zV&^==bvm0^%_;b
z{Vnekhn|>zHu1;wlLLk>N&9~5bIE%=dd{Eyc6j!Xr+4{p{O4-{yL+DVnrXf65kdC!
zVLiLQJa5$S-3bxlo_jM>wRiHDzw*V*=WE_&<CGOA_v?35AE^+o-#d8n&ZU63O<x;}
z)@^z%!t&AKUaS8$rBn5DK?6=E{G4;A;7#^=^0X7{hIYBK>FE=jR`+_h#Nst$b<dYW
zzLb4%`d-BP_YaQxa`x=}E4?x^#dFWH$3E&X^U%LSOWwH@{PC-*2^+ph&i``P=NE*V
zSL<&Jp_a3|O&j)}`fA<m+4heoXa?6U%+7e2vv}RYVKLWd4pBYn>*K#Dx>u*$qb8i&
z;4^#QONlvuMw%AhX}UdR$L8u`|1!VPt9-;7pH=sFe%x)lwWLGg*)PMQuWuM57T(U=
zr4tq`@41&9GvsWNS6tx at P0>8t-y-6w_w`CVEw2cEJ9bA0t3?>_dG*QY9|QNUi8kEX
z(eL#y-u3(GU2A7wS=}t%uoGH--o2~?2^aDcXYbe^oVn(c<Ih^l{@&r;H{w^HINR~d
zx|*Z+F8uM<!FzwrIx#P|_m#qhXE!Creq0haBdJq|uH6R&GpBN*LqA{#jQwKaL(`R+
zSC)nO9-N*UT|fDgb#KToeq0gKukMSexes>^`SwESH`nT)-56o%^l|0}-&g(}s;m7y
zIHCTD2}Sqk=bJ7z7C!sb7G3BluBUJBkwZFp-rAWk>3gegYR*|x;jrsPa~-#@T>Y{7
zp<~$_^}mc=bFl8-s0zytpEuqwNZk2djOmNDlU7^QeqXNcUwdzpZ`r|hL2<LM&*_kP
zXTqUpPcC}3Lp3+P)6Cl*1K8iIax$xm+5CoyCr16<`%1)XdpF5GD=F!@vquH{(hECg
z&R;F$k3V at bb7r5oh~POzqXIsR=sD=uUb1I8$yRSm7-m_sYTi2jNW!K!yY9X7>-0O<
z_q_c at _4QxgJ=tj6>9cOFwbzz~XNP?_<ob}(KMNNg_*$3qb9T?!%|nMwxNu?A*|ar2
zdsn0+3W at zqw~fEu-r(_R^_M-<-zbS3xaQ+0wyxWI`R>POAC9iOeSGOd;qcCdUlu={
zx#7KMd_Uf>BD&<?>qC1zc{A8&<nReY`sC#g^VxVINB39#!YQLH6PDy}n4L2D#Jz*e
zl?zAfHr3s=mYg{MT&H)x^&eo}ygz5nKg!u1B@<>3Q21m<_t^7n at UYSj9R`nE9ha{7
zGO?)gUg5Nr2j?03?u}mg;++Aj|M5kK at 6Ws&{8dj`;%_sD#XWd$-n<hH357p(i at TtI
zzUW^3I}s<A9_v*%uXBYpV(N}}N4z2I=v#ksjrSk7i(dSu+B7li4PE9_YZA=Ds7|B5
z^zj|AATd-KZhE%k<-#xC{Y<y>^|YREd^%`I#SiCq9=!EWYrTEm*@u+_u3tI%!-bt)
z9 at Kvk_^hR3V9|y*p4}E&pVJ(CFhf1z%D5%@4`0}{&~)a`%%Z(d`zBml9Ib2mZk_Me
z8y|Q2XH?y at 6}b;X-@^6(^nz-6*0B=Bj9n8v&aCzIu~#4T-muK-S=u$uYwMKG9bQ)-
zVUCynJ at CTyX#uHsd-x{2)u8l?_{eYU#9971pA76ZvG#KBKKcLZ`$X@#eZKa8s^<sE
zfA*+8_wSIuHf40*e`{nXadlJY&j)_j at eM;>P?wowf(Jx8x-5BZYggmtCEd<XFh-wv
z^7WY4-mFz`YxW;K=9=bN|B_dpnL4_1j49q at Y*M!uM`bVn at aa*zPmPp+88V{e$LYhq
z|K**?-xvNo{8xF$s8zo$4E^HuFT)(et`DkxA!4AxIB&qxL2LT=fA5Ma_;zT&!5a&P
z^gX*he8SuZPrT&!%-}n{UW(Yg`1>c{-~ZRpZ~pc4Q<c{DbDFLuy|ivdpS<^?&gAwA
zdn-RYZpz}^o836=2fvsL&XgC$ZJxBEt1 at tTzj=q3eaaOVzSU=3!GSfNOCBEBw{-o`
zotb~r6fHV?FFM<{>RwjnE1MR+ at JIdvkEz4vkBq*Zp<MCpyk~<KrKJ5kJb6l$ZSJuX
zpPMfIkea$((Lc?aaXwvj at Pw}0KZEs?`zA~(G{5oOgOsyz2Yq`@esjxA!)L#)Hm-hu
z&xCJpcu#Dc9ILGgeOaR!eu&LWVq%9}(U0r>DnCAc{>{X6kEm(S>@-jJJ-+4nS1X$n
zc6>E@>cuY0;(saHHARTIIP+YB>V;SSOq=oD-#$$m at rHf2;{Fq}W@@uvT=dj8bBcS8
zys+h^rt{Yhe|PcZXL*-qeLv>P!jq1x!_&9^<`uZ)a`bZpuQRI4*Pj3AUw<UunfvGE
zi%$tZm;Gt081--a53 at 3Uzp=IR!<wT<9(<JfcgL6B)5Ir(dfe-|q~ZR!Js;gQubb7Z
zv&n9+uvFg~IJV?Q$LSMpzWsmLd+V^MzP0gtgLKJ&q^KZBh%_P!0z>zJAfbSCcY}y@
zcZ*1ONw<^&DhLB8Axev20fK^x`dc#t#+-AW at 424$dgG6G7B_o;R@^J^wPV)a11H`t
z;2!++H8pnU$xp;*V?*z0-E(bI6p?$+&o4>LbbNA|jn1i`8)NzO@|DWD7gJ<*lk1jc
z6HQa=PXp_Cp5YamB87%?M{S)~#tj+S#wdRn^>L(RJ at 7yMykAL*eqcyPxA&WP>iztn
z at t)LGSa<1NwZWXec+gXi9&W-&AGs6C4#_x#Jz*U09^q-l9hOSFo9MOYkiaX=oy5So
zmYgL~oK~T2p8oO8$<)4p`IOy(j+~Jy|Lins(X2e5uXos-8Z)Tzy>2PD3*5djx|PX)
zHZqp*no5k(0(qQG^ho@>I{{HMJJQiXN_dftto;!Y=9$4=6na4`HOB)+pT7vy9!d@|
zE7lCXKu;G=?)oe&7r9uL-o{)yjAvQ?#j&u$&--n)3KiE~s!FG-Q~gzy^nsftd~bz{
zJuiC{!X=xF9&qjEZpmE8EC23Sa3{SpAL;g>@ihZMLuZLpQ{<DNX0n+lbz-%L>rD?U
z)n2xUuCYEj*?vutrj6jUR*OJZVrxUxY)9}s)4k_LSGwK{XP{m#2w7Nlv_wB7F8^@1
zkxDn+G+uCH_S}nWcBfiJC-1CtHuOayh;EqA-*dtV$C+&Dnoxc at W&2UcYi?eL(o8Q$
zmqFtzf6?lZ9LldQyOq)pyRXkxl?+(P5V?A=I}JZ^zFCz at Ll5Km)?6r=jie9fSRG-M
zj(5wiWbUtdq~J>=aaS<+>ccqtMk_HABotm}BdWnicI{pI;)Z@`c>1f0qv2r|4f7XX
zUO~i<NOB5!g;6fQS at P1mL_YOi%DPK)H*c4F<3Uck;%WYqR}i|{i=Um8ZYC3b8n{s+
z^^CrI&p{oTbC$cAHMWmFEhqQpX$}U3?`?j}aNMN$ZOWZh#nOv<M{es$ma;Y_91|Gd
z$&0id at jP<4^l{|^;mytv<NE|-&bda-bWAJyEoIx{b2O@<uX{)51N?0$_y(`rDSF+{
zKTJM2U|s9RHGpTLn%gq{DZ@!N;ph0CzlP<9qvxLMsByGXa7y7f^{>|y7DSLSG1klk
z-kh{LpXfcty?w$l`Opr#m}Np{aD*gZ;(NVhE^TAk1_8odvbj>V<833G#qZ{lenhtL
z%3IOh*2Z<_c-OAD;WEpo`iMW^%gp81a%Ne%l6GGPg2(BsMS5HhNBIn%GhD9LSTK<K
zsjYr0WA(FJM07Rn`Z?NNsUW;N91<ODC)QZt-j{FPot%$;Tw@?4)};U5X!O<P8h;Ii
zXAJLt+Ovq663d4_f4wI7Feon0`Dylh&e|`U3D<O%gDwc at T?i(QFIjOEIziMEM($92
zp|Nm5>RwOS9zGwJ5}mU8r at LF8Ck4}B*-_q|+!@EF)0tHsZF}=pD|UC|d><>agxfM1
zrS15fKaEIF%Q5`8$@&VP!A{NCfAUk at sOjssO|#c7#S!<OTWj>4mWQl6SUQkz1m+^*
zb<FrpzD%6N%eKwDSA36fst2b_#Id1Di<pQeQ{DC0Pp;u2SlIPu_l1GOPo^o8N;@l0
z%flE%Sv`vaJS_XCC~<s^e^igS-hSlv_~d4xu0k69dfEA^??Xl~If4&ro at SAo!?EnL
zFIM5Z=9)fyUxbe*!=Kl(YjsUzzFq78QXi8iM`}v3!9ZxEn%Aj$TYN@@BjoI at q%@5m
zyu7zswb}P(SF@>H3}d`#7lem-Man9aqF{0>l82ZBgWEk5=a;BI8(jUazowKSae0%4
zAjn?UMB-`raCHAj**Skv_{|AJ_WO?Yk)D1NA09t&nmDFUQk%E1eEi5(piimFq|G38
z9fengL0)g``F?+#fFEU9uWr$>k&5JsIBGJ*mC#y-^}0NlI5X>XMyYi?Wg`%eICZ6^
z_PP>z!ExT&qlyw^GCcZ at -|l~&Su0Mo(mYXCGvqr==AL5GYPm^(KZ~+|FGBvb4-_V6
zZV_v?5js3zaJJo!Uo$H at n{A$2Krs^`=<}kbaQ at la@$|9j2;wGHZvR at pd#_t~2ot)F
zB_3<0G`Fo`{<ziZq8QQ%pJjah^oGOB<+s~U8#RN+LkFnsGjz=DO1r<Ce({a6c=YZF
zjse1qz<&Dc;frRmMC6~u9GM at g+E5xjGlnncTe-N3A6gz&!F#GOMjraTh@{c(Y-8zH
z>ADR2nf6B$l^tKC1gGqm<mL=KUQCdWRE%EKXP at S;)SQJbJe<@F=t7#%vNUWr>eN4A
z9cfFw)pD=sFeh$H_BH$nqJFaJx?0jTHa;i6a6M~PSdYoEiY7~*i=Hpw2{<z at 1Q}z@
z9qZ31PrKBHMiMkNp2+E1E?RAQD&$T0DE~0 at ML3PPG;V<+gZ`#1c{`EAMV>@+`}7qv
z0~|X$&21)o6Vp%&{;7|qkh(oV>ieTOMc0FfwtGGuexPenGu=<syrvP|+45$uHNwyI
z<*_-M=R8U=<9=J;o~l}?)tTsBXw)1o=z!dxw(~D4&lSNhPNhy3jy`Z0pV<B;W3y%}
z>^QwwWfdX++_(iPi^t<8bm-WtauU^RFUkELY2dqvbKt_uJ4q=iACWPK=~_3QVs;9x
zZ?$|%JZ!R at V>J7Pf@}IwMh!CK<iKQUgMR%*I^G8Iz~*}fV%=@_RqtDZnKQfUn+`QC
zlDXH8Wxjc)aQ at Di*Im3Bb{e-Aw82Yeq*N*9Vj<)Xwi3R!S4x*DMo5#1f8HU1syS{D
zX4h^UPL>TPDi}MC^U>Odp!dg)sjgvwh1DQ~y at -pW9l`4#Pmg*=j&sjbKKH$1^-_80
zOY59dT<7{1y5>$9<C?f<6B7lid85hxqEo#O5OW_djka5D7I)}cNj4I^RIC$GnIh+Y
zewXB^s>mVb&u~0n<2mE?`=wTMmjxW-*5z$FeFjbHV>&E at 8BaNl<zBL06d5A(N^K`q
zICK)1w)HYTJ6~U$SZCcmQcmuMD at g|Rws^ghKT8^sBLZipv!k!hRv)`<-dpp|>?6B}
zZ9x{ULo!JgF+tf|3K2<HLaR`GNS8XbOF3w<#rMedTJCDHrlX=sV{x}%J?kX*d$Hb3
zIy1)-Ha_-r^Xa0r^~?I*6VHPk13PJ-d~RjG>Qv*kK;Nw36+v`m<>z5rXG;RH$1ogH
zgLsSVpSz~jHYRpI$7$_H<Z?+Cy(h`XKB(gbYo9+<-&<nEZh|zX-BGepP?K=<nyDVO
zRi2)>@<M8k)biYv*hX1LwbpEVcArAs$W8vnpKJH-ePnvv)*Gc&pUltJP*B{46v2No
zNsz2PtINeYZPit8>C5}TM7hP#`Y7&cC+?I6(#~`D$>Q>^;Ljc9!Cgna{TX67DgYN0
zF%9D8(YkML--ma at Yg<m|N=X<3o;L7sI*Mqtw_WM$`fAkD_Vi$7BZ924+Fva at m?thg
zgK0#$mr7G>nw8Rf+j-n%9iGHnJ$d<D<H`}HjK)d);E=SSqZ#_Qp)&d!p06`yB7>PL
zUWSH0?d_SK!X at XPT%pKL4PncV$)Q;)sgq~!Eb}tiTwN$$-9o;;KO4;Uysyr}(6G8(
zRzByglid)fr}KB4^8$9&%%`uclM)i2p<)tsn3EUT>Ng~;d+)66vTbL<-+p>)Ctskq
zDUvDCBY`kim at cQ|8%0QL+o`fyAMv_%QMWChpSG)to$$V+H}qyti*NWK at YhWJWqT1k
z;WOGy{V6n2II$G%QpK#R!Cj)$y`s5&<Sgymsw8P8 at zk+t!v;eTvD~D9qT^T7Xs-pW
z$8GI~+6B4xG!e0q6NzaQ>9dm=8UsURuy+ez$3A@>Om;P$G_dnoIVPpuIIE8c$)Tm7
z(mPDU%D^V-{QM#-{I<n+yAr>ZD=WH##HZAeqUJb>)dloXIg3IiLoBB|z8hDuE!=I8
zM1IJj3g!tTuCsrn$X0>WqIvVpU!H5x!poXZ(&w`Xn_}}Z;-l_(RHx6XXmxzNq!?T8
zV=?P&?7uGXdS&a!kMF%*&yb0JLxZ^&gQG;gW+oE0*LG-omzG$Z7Yoi%Ihj#LLfrWE
z5oPsY#I<!pg#5NWg~PPu6Zc+<n5`>RGH>9lxIOmHJyTxrfOL^bg*cuSf+DD~uj6P)
zhzmT5(fUgJRT;0<j4Srj(=<GY<76WK*Eo*yWJy3wFIzJps at z}!t>|jggrr8T(U;qO
zv=7#|b=P}KQa(?oJ*y_{SZijAEzJ^`wF^DHe)_SU&--y_#mZg7qfQI*r+F=BMHX)M
z5$1x+e>1f$i<7u at Td$6m^%nAnBwBIh<gzdKRkwVf&G|C1HFRNQ_51aJGP{mjbyvRE
z<q%6$goxfe!^Bo|mXK!i_-T1TLIE!~MdyVEO*`Z#U- at 7WGs8Ns!LO6*V+$*XzYH}F
z%}<8J-c6%YZi;0ky_4(wFr*zGd5G0eo>A1EP=H4A0Vf4Ts1+hZ+F!fu&}E;m-KwU8
zfq|lZCo)*Kjp`{%?v&G{y?CV!9o<6+T$waAy*2EkHKnwGpwsy3uXBBpC)IR_=_yZa
z6t!?#`=t}@tBC};(?}!#t#=9*y;b&#iH;sxxqKI>L{?de3CoDsv~6LM7TjqiKFjeP
zibaKqM=kF~o#yyB*fIYW8JpMreb#h(Wu5g%$HG1G6679xRIsFEVx7M;lC9NdkY-nU
zMPBUccQ4-;7Iuw&{#Uj?Xc3>=Q55xTA+D~?qsrNck{l9BX8Vr*It{1S_S~V6r;fPt
zo%)2tr7s8ud*9;4`qkkhXhSKeHCqmkip7(shfa`PUSA+){9;Ztm8?aQ%|k+Jpm33i
zy}<d{@*{;4`CiA58z193%12ts_}=6;eZ^cagH7Wns<R&-QtxE^gw?VaQ at W`p(uiL<
za^wd;D{V`hFP-nQny8xm{Q3AZlVXpO;x3Txwo1x=5SIuGAr<ewaOonhhJ}a`o!+^u
z8%}4R-xm?4FT)Yg?F!*feO50xZudqAhVzom?p4C6viK5?b%7u3JXasFnyRUu%;mVw
zymIR#3)>dWY3~M3?zY(zTzkgyoDw81JT6SzXX-ug^L~1m$#*Wl$~iN(+ePp7j at xnl
zYS$M+x4e>1F?nhtxZUYCT|J)Nmh+E%;eAu332}p*h}Lh!l*K2&z0h0wc(N~E?&ItI
zkH6b@@YXo^%Z59New}svny_Zq7-nzl_3o;*z$ILpEzz^4cW)AzInYR&a93Cwuk~nJ
z6i+ at iH@~-JdGb)3)x1rt;^ZK+5=|bRiq;8r<wOr3#H`t#Iur4r>XqgswTzcV@((gI
z6bLr%%1NnzmJMR-fj<$Hl{&2FCatt`S|&Q?nD(Z%#$_Q~D_xHc37zH%Vy)fom`fMR
z+co at -ENXW8KfAJce)TG|)||fO`!K!2 at LI#SiNXe4-wqi$$z8ct#pkea_GrNTj!W}m
z?Z}5Ex1#A4 at p^;TKc?+owO9!*`;z0Yvnz{!SY|%_E<ao6z45lmD&OMr+WUy{w-q8$
zZ)^<ieWz~O*c%-i_>pd({qr(G*;hu&GvB6skABI1AiZl)?Xd-|DSqq?zPS-{k$qEM
z7q(3dPx&;+U9c0I`t>v7=aXq~L*uEobGpy>A}MAhmd?+*eCn91&xwBdiDm4?Ih9wF
zc4Si%WtQtt*Qc7E at zez(O$+fxbBBe-SDbCf*cc7_jDAo)$V%bpe}3A3fL=<eS664~
zeyaGlp7EgkZrEz-pxWKi$MJnR4<B9ce?$t~9Fiq;e-h>(GtxcIIE>rMlXy2xD#2mT
zD~Vg0H+hYdA+1;<E8SeXBK72(k16v3eK{QiyV?F#BUz%<X?MQ*<YhEEvEA~*r at k%F
zuAI3wdLuUSEPss3HNrUZ1*7<pXq%{jJMW^UcV;5-l!7AqSsQ~h%_D;JD7pfU*Q^A-
zcs?4EJft0}S!@<gM}HygnJanOA~Ls>xh=ii5^uPo(D6(4TW`O+TvRGmPL))ZRsE+*
zHUsI4h2HWNdR+D_YL<lO?s7fIyCAbw;P<^ezcc+#;{!Kj0|CS9CaIFn=Ab8$bx&r<
z>JQh7)hZn}t%<g{+&+2Ix{XHhT8q|ag4V<=fsWazhI>r&!ChC3o_A&lzem}BONW(3
zIq}12s>Zt?;!V?a&&_TKp0d04;?AUKYhMHB`VAsPl+(R=^GTd=9Oa3wmXEemFX!jH
zg!IfPbu<`sb5 at J^zka36IU-%T>oRw}`=Ql9NtK5yk<61}C-&5;o6bBidK$^X=5OKj
z$ZW=uRgQeOc<Gvc=1L-8g-5x9cO~fK9$qC8vudmhhmd?4qBiO8u91c6Z!BJXl^$*p
z7C!p&!hFL>JmQL%5U1puWy-KidR|LX at 2ALjHM^`gxOeju({mnNImv%|F<TdLQ_1P`
zz$c>QXHq3M9QL~D&*mW2V_BQIbJFPhI8NWpZTqgkfD32#quh>9Dpg$FxqU?MB5SFn
zp1`q$rpUaV at gtriwv~@d4|m=qTp+k_9AcE~Jhs9_*SuZUqOVFbCqCNyI at HELVE+0b
zAH{tyMY}=r!})Ht)&nMZ16<QBxvH{G8K3sXe<pme)bQ7Ne(oqmD~DPWz7%I+&3Zo*
zSwunLObz3CtI3<(W8R6$jwiOo*mn*EXC_!C@<~Q;CF{L!kTupO+a(k at u2wo%ygAbL
zBWdoPJa0>+_H8<=cO1^RE*pyNk5u_)XTAjRo5{VtY$utUH6A?hrANe?&L`@y>$2gw
zL4yU2YIW_OQlD2dPE|)oxY3?lr^O4B+U=0wxWlq`g6-C2Z+P_l<Xs_yn#b?;o5U`^
z8Z}bT at UQv#j^UZ97>oV$aCzc~f@`mx<Klui-)BEf(EL&xw5)UOf}X&Il6d0a6GDzF
z<Y7HTjTed??nx~a;_rp^&?#~8-TkDlEO^p$D=Hh7mciZW&73}c%zOKhO1EM)@7Q;o
zZd<rz(N3BX6XNuFAH$rq^jEB#AJyy_ at IOuZ8^1Okjk`A6^tP8c?viig+Bs`Tej3 at q
z(h)Hy at P^+^C;sHb7n4leY&^ny#rL{!dZwxx97Sk|h_#Nns%I7rbNy_-9tJx+u;89V
zIsN2xWoM}<157 at k$dh%d-_pa_7l+byr25BWw at 0^i3pY=$)2AtXuR32Q2QwP-RQo_M
zycucsLY6(&d>6j at h0jM5o_t(bi at o;w+suis`Y-)!q;h#N3>y at td8#&q;<q(BLpVfc
z(vohS<>mdM!LHqUD|>ZzFUHV?N_c_Rt4xG<7#5{eaY%ASu01%Ad1*e;^QysTYNa*(
z at 0*t;GVFs0Se{Cl$o5AMm;0Y98=1HX7j?YPZs_M3S^wbihY9^-6HW_xwIo|djxVc}
z`UFxB+Duk>QPj2e<{9Al_n*%y`w_rKbL$nj{3nfL(sT^7q%Dzn?$Ue4Y4%LYc&idI
zUf at P;%SvhixzhEcwY<k=#v~NKIqLJQ&3wMEX_Z(!R8w}soov|GvehJI7N21AV8sDy
zQ89X*zPpnXv!#hEv#E)h9eP~^R=Amyxy2v;_BQSot|s<;_7;v-?$!sPzdy#P$B~IN
zfKWn5h}<A5!V_TM83;cF5qCqBgd||!7zi`qTnPPBSwsOqqyW!@a00Ne2ZSDQ0z^$H
z2KK#yhyq4JFhUsEw+6xqxCU&20-^{YihwsjdOWbN4de(!L$n0abAx?%Ai^O0AxKXS
z_RWE?0WJkwRQwPivVd1XdXzo`AWVQWpd*A at VBZgjIN&KzA3Csa59AEs7O*7)5(7jP
z at GeMy2<%@1LIv_K0Qs|meQ?@EBnZMEfc#0pzA2ECfD6GE7f28gX~4 at MJ!n9pD?k_l
zr-1xrz`ie#3xJ=3{HejdE$RU^zztxFYR at Pj%7C{)dVH|21B4cm0#%_V6axF6Ktw?J
z5Xk>9*tZ124!9C*QSBWDL>}-vke(Rq8v!{EI1A)&2KN1dNC18T@;?gp9f9xy?f_c~
zAaOv{0q^biza|hEsDJQ&|GNMY0O7s+{ci$<1#mvt;s6N*0tdXf-~akR7yu{j_rDL2
z^MJ?p``-o#7vMUuMU^)ah!WtB`~80z2n|F at go}gee-9vMLHOhS{s&{0=oH{`utl|3
zC=fZoZ}$7&5XdpWnfv{J1IR_d&-eS^0SFJ^Hn2tM1DDlAYJk7)_dhBPHK_mn{r-0Y
z0{Vftf4~1xZ3_H}i at _EZKNtw;XX2Ip{=W(Yv@>zqe*a$w0@{IiV!!|GP!C80ZUS4B
zzGxsSfIsi|zb+8EKl<Mb$T<)`yx;#;KsW$bgDon*a3BhRKkWDaH6Wnhh_m<m|0WPg
zz_a`P?*xPoa3|QJ^u+@~0RHh0_TPhL|9Q~g_P>B-|A|=kKZ<4lwb0-8zxfaL{|L+e
z%b>sQe+|q2Z(-U0G?x9hLVw%;mw&MTJ}mn$g8sJuS6KF+ie>-Lu<XAP`rH0L{e%5K
z!Lt7<=x_Ufk7fUNu<ZXOmi^y@{<i<`|6u?3vFyJ9`rH1Ou<Sn>%l^l)?7trR+y1xy
z!Ttxa?7sr~+y38T+5c at U`=7zG|90qa`~UV2_CJ7S|0U4h_Wv5o{?oDSe-g|7o1wq$
zf9D_Ue+0|^??Qju|2mfa=V00Y9G3leL4Vu-Plys92cpBr!J)>7K}Yd%C}H^c5Cc9A
z9t}PmI);xUMTvh1qQ}R<J%Y~yG2!DdQ{fXsjQBW2wD^IL6ev0+J}yWf2+}j4($mB6
z2~p_ at Xz)!?>5VDz at lfdx9l;ksrRS%@Cr70xqs8yRq=#S-6>11Vgb*=A0FglW5GjNQ
zkwJ$batIfqfN-G0=<^vfCs))`aOQ(E8EXsF3D9qU^y66jz7T{uO>#gjaNUoNUP``y
zisa_wVCrP=w!g0Q at AD@&)Y{koc>Z({`a2wTLdDF(!|Y(==7w6&YvE|l<7CNWYVU+8
z$3Z+(n_ne&MX&7NKmYnm4|XQtV{KuAdM?(?)eMz|gNeJD^<U}G867<A^oPHjyA$d`
zAx!YTUg)oOJkWg5j+k`&51qLkJZE_D9PWN>OM4Tmzsh$Ij#^ObYT<@{=*hvt-P&n?
zWi0c-1KsEcwb9Gk(F^aH1<s#8%Ol7yfO?G2)s7i%ZV%K$px5!h2p|BXfe4HT5-=9X
zLI1-bYKRUx3Y~yhA#O+r5`$zQEyxUVgMy&~=svUr;qE`|PKo7U`;KbgQSZAW`;KPc
zQ9?>U59(d3xcg;5jYo2jk^y3Y1RywM0tG at n5Drct4h}BPAsjp$0vsY7G8{@AdK_jP
zejF(r<3IC1$nzjCR35az(E&#f90PESz#RpS3AkgxNdbrI9|va>cN<fC3+7*|m{IGL
zEiFL<SsXmdXyf?D6Aiys<wFqK3M_s<@aX35YGLB=+XuA>{ojQ<?)R6Yg$2qO&=0_x
z0G-Gp%=-ko_qX)cm~G8I=k9M4_P5^qTkHL;23EQN%X#??l~Gvm2PpRu`9r0I)7ssC
za<_Jg_MbeDKr+9%U_+TdMFes4^WO>3VhYcd2K)xYQXALI12v9P<`6;U5MQb~GxIwZ
zbo`h5@$)%OqInj>ZSmxCr>c;!j8Y;<<S6V=!V%1S4!SYbmrumvBrHzG;uI{-#o|0H
zMq=?O7LQ@^I2JEp at gf#4Vev8+zrx}bEMCRpH7tIE#c#3r9TtDU;&m+Ez~W6T{)oj}
zSiFtJpRo8d7Vlv3E*5{m;;&fz4U6}%_y-n4G+5)|#BekV at lnd!pU_JjvLVHQ?4=0r
zvm>x-8!$e3sZ4V}8&^&rM#63lLfwc7+4Ov!&%}4(WQq|xv_s^y at -&5N%SM6 at OY&hI
zgxciqk at Fko*D@%d;;MI^d`|eWv2S5?_$vwL>L at HRyiss-P1mrOPxv(ZbtEjN4A>J-
z*Q&3 at m;%Qi>>Oo%gSsE&cN>-8<poIEo-DEta3+RnQ-vr~ILBZK=K;sPm0(^{U at rSO
z46C-llsE81qnY(X5I+kOU)YFrQ|x7lbomWF^*)uF+m=ZM>M++Fsiu>kFW#f=6N-U7
zRAg%%g=IVg at teY*=g#kS(7i*#Vktp+4s$RB{Gf7x`Ha9)!RdeZ)oN18n;XgkV at O!5
zGzdRLwZLAjc9pON*e?x8Kh5C!kZkp)LN5rvfC<lSrf_*LhlC|5L(F#vD%IwZx{%u+
z?b{6{5dF#XMJFi!WXQ{(`cHm!YSUujI;CRUoiUe(GG~^AAN2A^62+=!7?$nO^VgIm
z)V+;HUP8i}w?TO(3Er_4ug9&8UX at L0cK<fao5#pKfBM*Eks<k}3!M59G-8iU%6X31
zX;LdRWPQsp+U3gdo4v2ZHI9T;xPkQdB?4*}xu?u^k+3pHls^1?DY1{=HkOW3hD3n*
zO+sfk0E=_U+aK#bAA#L+2lbsyH<eO8C%)V^0_(Z~!foU~K-FC%#dN>NlL<#V<YkM5
z6`e)tN1E2~=Xrfk0W6E*TsV$GnC2L)y$Lc-zb>!J;*gr?nKTMZVgx*Q^{E+FdUGt^
z6zM(`mWPA|DTDm4$^^rUb*x-wk+9&S7`DKQpFDHcW|d_~wX-#6X~37u_mZgS?)cs)
zthg1EAD&;wTO)xnSQ8(Hr8?784H7|p$ALcO)pJs>5^I)%M_?t?nEFHEcpfL#!T5*(
z at n<W)KyMSarKm=K at jS1_r2sJAA}c`tz3DuQ+8lN6a=*jj#=Y*N&ZDsAD_}g~oBv2C
zvVR~cJ_hStfuLRd$GYEzopa0WwUsI*)AL<vzeM3_;I2wDf$%dRe(A+LT*M|D({*tC
z0;kx!cqStn;l;^}siUwIC(H!EkLUdD%pV+J<8!<(YZO*03Ci>6j!BDfJY7)!7%Z$0
zWp8h8O*Jl`iT{Ih2Zlz1@<(9_L69*Kesa*IHC^YU_eNon45<1%6p8u#G5P4RaaaKb
zV4sT7Vp}uLi>YI<#tD?Y&?EUbPc^SAFj5w6;u^<fzpczW)^g-5j(}R)w0+kjE5=(C
z(NFwEdTuMHz|`+qx((gG+2m<>@pijxQ}wCm2(u_FAr-pYKc&WC`TnT!O60;49V^J?
zwWpG*n!qi1N2f*@D?C7(<73cHqV&C#O_5~H3-5T(73gFQkHK;%KzsLxeO_j$tgenE
zl51^l5A*F at e18@zeFBq>5}iLIWf>F79-ovgkUCQ|-5G`D4Wq`7A at wzjmY=PG!-$rw
zOuG^X>eo>my7EWiW3b>%Onuw8H251cMquqhV7%NLCauTf1}vtGUBHP}8-s-!qTAOB
zYFtnfkspVp?*M&r$a=%%%!uRZR4T1xY;%tmUajUI-uz*7mOwo@@HX4z&QJuq;(*qz
z3L&-1LIJu@$IeAS1vb+^Ujus<!_04Ni-G6$KaIoUE&zSj=boLyVs<R%z~YMfw at j3N
znM#FpNsnnC3<h&zg)bGd$WLszDMV$-zrIeVD3vF_^h|3<P^saNoO=KTTSnnR$RSpm
zESbWG6^WFWK82B3 at Lp$*Q%2NeTcqC|;HzQ4|D2-1$);3(Wz;AnEZ}_3z3vva_Xcvo
zE6>i8AyyyIt(SFf1{ougLJ+ad24ZX8;Yd;4PYLqbU2WRVwo^M<q!lgidVLXzu>wla
z3MYxwUe#BxW*e3AK(9ka8!M~x_!Hr<z7bd?>iB~X=VIwHptv>)<_8?i{7{26{{{RM
zmQ`K<eZ1+W)^ae78HLq7LCps-Fy`*8_pL<0epxZcgLiQpF%=S{u$UT5|G&NadXyK;
zH!<F5ZrE-!qSbT&<D&`_ZeA?z{+1l1KZQx(;NMeh!83-kUv#*;p7wcD7bE%R;L~~G
zi1om*dn&Z#$L7^C#im`;6na~zNOBCaQ<1QOLQo$fb`i?b<P=dbzjVlh`q(diqO@$4
zI at vf1t8W18`2BTCrmemN&L}Ka7&9K0w<Q)ng5z5TEhc{<+^vAQ<}p}-7-qg(ZKrvz
zmO758**?+ON=m2lRn^qktFTrfD(-?ZLk2yE&B$?y7 at ah=JNojnaQDRtG4 at x8z{DQ;
zn!-EppU&KP^WX#NSg8TNQngsuspGk~wfus+Np{;$%Y~BrAmc3kO5DA3)X3EFl+vzC
z)r^rzsJvA!32LY|0OzsD^bf)gW<2V9o>dbJa>Zun?&%N&hVDjN%Bc6$DWyMh_X?Q|
zX%>aE93HPtP;M{d80_v7&6NB0L*<4rfmBgvC0UJ*OOi}xCZ}wtu2kVsJzvks*I(qN
zw3-Jc=v6z_&7Y_?PgHVGlR2gHj><*+tQie!nSI$DbMiZ^dPzA<m3AwUq~*tjp{|BA
zGpf=xTsPM;!~5aw%r{zXx6 at VID2+sjWQerA3~!cj^WK*&&aWuO!B^J2uXWW_v7$%4
z?L^)>Tz-!suv?>g>}`}x*ySi<Uf~R1`$NHz-5e at X@kEq7lrO%!BQwXp$Fts*uWGOl
zRXk)fV6x*yS7jZg7JiSvS^ulhORcVozMBgy at JJ}k)T#H8TkJjeq|uT4 at Oq<K$;%~r
z+pEcf#p;$bin%^>9 at +TBJ7?b%1wEPWQ%K`lFywPlcT|6R9_NScN2RcYi+3Nd{A^*+
zg%$En98)Uyd#w_^RAWUhT>jwjM>EB{>%0CRSK3Ym8CIC~e7~<&_L7kNn37 at o>vPhr
zmAVQtiJCPr_JX53ci9x*FTW_23tZguu^<u=o(XM|_+s%{HTS~Ox`k`b#ZZp=%{HeI
z#GT96<8IP8Cl=;07X{FLM%<&Pb(874OS>A#cD7SUQ at SnGnDFuYkvoQ-hq>3fUEm3E
zM8&Wc#AmUn7t<llyfP($S77`l`et70J&dn$4b_`vd26dRGn#7zE=_FK=_(cum%i?Q
zbAtnKJ9<mz*hlGPe5+Yf&OO%nP<x}36vhgfKi&w at HMzL)2QCU7SND_;zLIg?K<s||
zy3`fFZ at GIa;mX|~=UczVv8koc_D at TwbtP`gX)?Fcc_jxpY}l&EM(P%LN#Zh7lsvOA
zBR~8~F8nijk)18#Mw6LQLRXKvQeBosv*7p`BmVo%9fzEJh4N~yak~Bu%f;$R1BR1U
z$}NWWSqnPGgS!0pIt(74lyBha(3v55MeDq&?#ffRj>uteq6l$nL)=goMc!{qSBO6{
zn9o(8)adeTN`=8;T(L7<`Xn<Eh0L+r8T5^}uF8clRrt9tzuZ&7bAFh;%?>ZS-+21O
zHf%NQ+uJ5W8*zB%4x+bW!>_OL>k&cS^bF~ClcciQa at n63=pnXHlW$7-Q_AO08*>*J
zS6qH2Mnk8TgIDz9)*j6}0kYAknbT>~r8~>cRDzFOjm|-*RZq?;wT#M=@2p>Zfn03s
znWGez>3r#%PkPe#4rRrqZ1UYXrOFl={!iB4mtDt92}$~DR0 at J@Zai_l9Wc<7G<!4H
z22s!+wj#i+%vx{rnC1h2k5c7=ozZ>QyN%ZU8g(~5EvOfZb5Xn=Ek7ZJpYXtk)k8Hz
z#eC)Ku8UntRd#47Z<S&RBeBh(PVtk3kue*gy=Fuv+1r|py$11o&$+qN56#pPY;|NS
z<=jFmEnVl_ldKeDFN;l>%!c#a8pbc+_{6Og&FJs>HDhAgW!hx6!w45qP-Y(#X=H$x
zu&8!UlFC9Z(fs^_BqRCjw^hwAww&Nc+?M<7%zDkI8}Gug8|||+ at YE4LuIF6L&sjDK
zFL_)qQ_Qhb3D2kOh}Ty1)*0;QmJhUvSkkC$3E~woEZNg&MpT|D?JO6NP1bfif4wgo
zlIbL23wm44$S!iKYqoSjU$rS8E*GX?`^Kaifj^}dt`N{fjLZC>8Tu(`pn9jhMy9cW
z$MuzZc_HJOzQ-3EU#KTd+VMv9qzKbfyvxX7mQ at RrwM<W@$q$rY7X0v7piMatQS^4~
zyMxjEv(~P%epRWux at w1}yGqu6hljUtl!lbU6rVj+!CQ|v)W$9NIjbUHv1;<rJU03E
z=($4-k6T#a#pfLqcxcm4mv at Vtq0$Ri=|ZX^=W1`CzfntmeJm?kIbBG8C=!>~kEDW%
z#rEM3M1eK=nxg^^Z%%bWnOJUsdP>JFs!0tv9$(UNB^jM<<&wARzSOaS?)fuLj6B<V
zG9?+!YVP{%eRffoE-kgbRBj^Ii{WVt;aMwMHh8;yN1-K$nhZC><noImiKF3-VG0fF
z_m15ctga^AeXcmNqK;^RC~T(GmqIF1&u3?yphmQCDAuXiySO`@YV7#z^Fg)w)C=Kd
z-0$)k-T}IZ7*pAHGZ#G8fLh{4PK1HYZisrE@#e8sKZAkejI%cdqKlN0TkIB8zbeUO
zR;XVSvNl0P-Vqp)PrswYKB;trMI0Y-tNeTKBL#UKJqnw8lQl8vrf^Zmt|`IuLoX*%
ztd%|B1 at 8Cslr>4c3C+u{dHIVgRwmmV!w)52z1 at HK$)d|E`Lu+qPjYn2>xtv1AF!Fs
zBW_6tnbQ*SltJIm)jzv)R=)V at bD{5)+`eg7`EI)Zd=9 at m#pGSIRh|FpnnI$TUYmNX
z$Edq-%ahOVoVjOrZYL|>yT~T#9r!e9upxYX_+zL-n4W5Jzl3Oie7^4GV#8oW1aa at 9
zC|L1VLLm|4ASVGlhm}ib>DByeuC%-H0SrIo16c12S7b>neK^IDq2QFQ(4Y{={q+WK
zJhCRTY2342HGD_Ukb-R9*_Z$^OZhckr7(pcnz at dZa4Y2;nOtMJOaa$@cmBTE)BT;-
z&&WO`QBM3i{P|PX_dLA$>51?s+_HCcjY!@ioLrBdcb}NPM5rFDZuKaPa_dfz1WUm8
z4uon1T|0*{l~oxx+t4Y$Oie_<ye}8$k51{Od{WYDQbzFN5058KF?(ytMyUn66Hlmz
zIet7eMJh^pKeWSv(9l)2#OvleZ^APKt-|XnVI>|?Z4qSLcOuK;w*vzwBUzUf%8ZRW
zdfz9LhBOZ9Hmp at E<S{>(6FNJ)xU|*(9v(sruiCO_%59!iAe{=DDu4Z6DXe*AVduz`
zA3?qAx%0*p^2zRRA~ePK0ycIA@!notQ0quY2$p*g at VVUlT07oGqk5bgy9a}%uxh%H
z{Z9SeNx7n&D at tqlGX6dH4xQX&43diB=RBVS7garJCos5kszo}ASeu-+P at K<N&wcvZ
zV^8J8C!g}TzSVd_bgQoKmW<`Q*u=%In at 14v+}~j-|8QHTUGrS4(?pp}^p^^mmPj6j
z*5Q at gL0lUQqh{if59R38IvGxiy*|2Rftc;EAVhE=f=d|p3g>RTjGkF*XcIoK+Big;
zckc|GNmI=r%`;k8J)l`fjkmDT$h}bf=n-}mcndY- at MDRKQ*s7f6+;Hi3hnCQgW>I?
zrem~A at s}t_<g<<|esp{4T<}~gH_3*JMXHNKQ+1D5+2-Kwum|^xMsWUST&(b8SWJ(_
z3|P$kFHG?lvtWfoSou?6h2vs{vtuzOR(vw7aAGVzj1|AzF6SeQ#xSg$27+vGxFm6~
z;`3i{BV#%}46Awt&aY*?E|OuTC&yw^Y{t?@g3Va*4`GGlV=)z0{KHt`8d!V^i#4&^
z8 at oNRm=-HPW4lk!#Pk^{8&UVKc)EO%0tkJEn at Ct~3i^I}S5ppdk+AqEEbA7y-e}Dz
zhjeOB(cmCqUF4wsTIR+WLUZ*VvYl0G2$Gy)6}o^Bw*6b*9u^~Q{^r~VM3mH?Be2X(
zi21Ig>-I&g@=9Q_6c)>3 at m1{lZ#=$b1RsG#90BERwE2{)H(5p}KLShL18hy+kf7#3
zA!;=OOC!Rt at 6#=Q1 at lo@oH(k!q7K!cNjtnFMq$BgsQV at TPlX>c#QOZfC$ZX79xMMO
zEdBgg at ddD05Q~Md_!Jg%Vex4!2IHOS&+)E=Rle0$vbSkIW3X^u2-+ng(&xrX&yK}%
zSm_n8SP_dKU*MYw;{)x9haNwfgIGL-#ZRz!7>h at +m}uZmnx_G{J`O|OKdaH5P4G$K
z92$e=?mz+8LgQ<Du*%bo#r;_P42z#)@h}!&CKq+(jxCT0rRH|rIwHI#jMZNE^DpV~
zTa3b*3PAZhu77!6ovCqN2XG#SHxj6R+#4Bz74U=p>2b8+e<nw+;)#UiJ;pGJPX=wn
zA`(_p3+g-dqWJhoh2JOdF<2TI-~z_5?$QQEQrj_Dl at f-L^P1U*9YHt_hWS72#oRlO
zgtd%9xoj0Y?JY+H7<r44u;M;o-voE%x{W%5PdkD99$@n8p4F&0_6IZj#rWUxL&6dz
zF)TSiR=hWlgr#d>(i^R?M)e9HVUbK2{R@&Gf~R$nuvS3~FJiIthF9aF|8ISe6+~MV
z4p<7qn}hW|wh_PiBNi`V>GQuHqh&M($|H>_kIzP at Ur4!%Y=^V;GF9-K4tka0l=1pe
zSZf2S{hrli-*W9%`Z@~By^Cp|n$X0XNrQbd0cA-XzKHAEP^@<-p*3hPO3eNF`RjxB
zfAX+M-9W$xBrM|^=6>qN^nFGHx=~naCuE$S{su9J*cf*G0qm&=eSd9auhNI|9 at jW5
zjvRBpO`3)QsqI6g)Im at uLfR?U#-4D;){#P0z6O$h*L`EfjpF^f6~`)(Y(uj5RtC4V
z!I=9aaol<lwJHgMX-OMH$%wD#-`(BqgNLw)c8<l%yVaa}{p8UQgIuD&prPy6hGEJ1
z&$i|h+v;iTJM-^FJdCUgw-^yD8PW-H1T_+*=fB*@h^bBwA6M^mJ+1IEIku+giyeb}
z{f2t^al<FgR at SxFBgrdP(^T+qvs-khKNwxfJ5}{CMeqYW(87gI1<9n_&hc(aOj25^
zmPC1En(e99C(YvS=!P*^<9p2g*)Y!Dthg6ruv#SM`=6xXnN0yVBrN6@=KG^^1gEv)
zANSWnyJ>7lHJ`|)+~u4rvj4)(9PK(7wlfS%ssjC8qKZ835F|tY`h#@G<-A3c``3Sr
z*W~!;BofM0 at ZP3379dOZiSFs3ZR3*-co3z3pG;mXbH${nrGXlrSY+Pc at mQE&D8ba(
zY>893$cnr<fM8{E3Yqe(B=)*oeZ#O}TP114p_(da?OwlJ92YVtS!;o4>BJO|cxjnh
z0lxy<9pS5aoyj^s=g%mrHTFpb-e7#vD)_QWu}GW^Ua{0za!R0%(87}R$K&}{r95wL
zgNE3oqUYbOqh6d~R*iWJx0GotK2@?=gO`xfA)B@!omN0~Y0;rXqAB!*lU!bwB2D(!
z&}hj{x0^oS#FdH%{1?>O^x*B!vY6H~5 at m}I3zQGJwusx>G76rU*iuQaKGMk*)-IBB
z!`CA-ksf|)a;A>x;gBV<;^$0rJ$BU+=ANAxBFCjjx!MBv#8Rcm0)o71?%O5NSogQX
zcCOC)DgeHNVe%XE!Pm&l;9ZQyb?*4brK%ei<?h!4`{KiVKNigO%s?px%qOV(#XeOV
zuCSj<FWxxFCWX?NYZc2dA>F?9TzHqS(nu9ElNjDKniDWIV#u{BowFycBJ?19#cg%{
zWx9>EdMEq&CZVcMs!1I77uooG(z$m|e`jfWw&RAS&j6p$O}WlaG3OMmguX9lS!j#T
z$2F2rl}dt_ at 4iSy!rNf!ZOMA!3MC704j0YKq$xp^3~;=k$^q10N!&<D-waXfv%J-<
zKvZ0L_4WFj)ApN_8^^5bIMt#lsTKusiym-x{LBr~wv_4QkO+JoN6_nM!rRVFJPOMs
zMIFy4dOp;Or8Xpw!ZHdl-#7BATwQt&^{C`fi*~?1J*5k6Dy$D}!dJXCZTMy^Tu_90
zng{34?@L`54!^y?2<F3jz$6Kkd#9GYz6=t|wAr at na=7c5EIW+)e5hcNioKI)Q)e=v
zE4}qy$Kg8?mKp`@=TUA#suGX!h1%QF#f}VTmk}~_iQgFCaAt?8B&=oUL>aB$%^0}&
zU^MlON&<iTt;LKBjL$PiRf|puD%Up)U;l7*$xgr6?IQA(wA$TnO_nxkgV?Kw(<1n!
zud4 at 8yTP>r at 83@==ItH|JFaw_)&0COo@}Y5q#ea*Mz>=A$#1jni{JX%GZM?+4e=;+
zzGo=>>?Y}p8((z%%Clqen(S<gN*3d*1NV-Kd|07Y at 6^*<WFrea+}JceN7l2Z68gE=
z#%3G$b6;XX>eFma)exMDYyy{Tm_zlev;|uxl?1YWMT+tWPF{beGZZ}fQo+ZMI|T_D
z at M^Z?kUe_!R;Ivt!|FP9xN2Zm&8Nngqbey%j5OI~ZsOM}d{Ycas8t&#RCa=$9_ at 0v
z6BRFsxvA9?`Qa5wbusRya!nhJcq(`4zZuWYZ}sO^8t{#~A0-n$W9{ZG`_s8(YFJlU
z@{CNf2LDId;2p#^d{o?4d<@o6jvD`5Gc|ahRMTdWuxLrpU$E6zy0kM5lg>tpaS~30
zR}AQJAHQ%px#xaFHom#f4!?47va=dS6i%wGn(e9`^H~YUPL6!u<Y&CGdXl=uxh7hw
zmm(jdW8N`dQ_4t5eC8)^?Zn~QIL3N0RVBGwiTkPceVr$G5jvBDzwh6tp6FHxT{r`8
z>_c$OrCoV*lHpPr6_Ko3_WhgVF|JM*scEihNZ2JQ=DX_eMr5i<xM7Vi?C&c!2J_4r
zFPO+C>YcN(u{p0XLwPp+<_&JSNDuc?J<f4$5zSp`|CubA(9LB+L+Wb}S)X)-%wC&O
ztuDN4-g42qBEr at 0S=Cc(g-+Z%X{mzK#*Aa%S0rgYl(J%qbB-1`3rkzVM5rgzRc;5n
zhm;}lga#1qCXJzq3S~7MCq4OZQ<IQtsl!&hR0}E-1dt~=kJ{vUo=EvpDHZ>aSbsHK
zfij?Ns)`#z!r~8OzR!IqGe_BZY#bIXjQRc|M73kgRq~Q at G2ZpTt&B76aH<)%(Bpw}
zafs66#}3En=0OFjvA0KI(I+wU*E!D<A4C_x`M3{;=kG1=S*rx7#AUg&3tVxF at V{Gf
zLF6`>bm`L04SDy%2-m5_=<+ZHwPsJjp+Yie`Y72a4PjZ9vPn3+rj%F1s{<5XdAe6E
zDHf-SmF3>uB==nrFR6{%l#P`c+v~DpLOzyExbbCzQZZOC#U96NQ6Yutin!*ZX4Q5F
zvE(hX;beCg5;m=gW6H(jPgBId{kZrn^`n;)4}*G3wIH8_D`TU<^Y{1#8FUI!Gkve0
z-#T8KuK&H?E+;}U{7}j&Ma-<EJe>UwqAV4jlOtApX8zG-n_EXj;z=GVMMKK(>Tpkf
zJL(-CRdW7>a(R8h?JVJv=@&O^UNnj^$t85AS<3#Htmzo*c5!eWk}K}!73i5^(f4T3
zXK(q?tQb#N?;UtpaioAM2$!R2O(8<3N7~}DI%2ANz>k8fLn%_OM~dkYzkR6BWb#yf
zh-@&u)tQ&MxWf|`{a-%zGN^V51)rQe%cnU at wdL|&CIKGewWehkbe2 at FM2zQy&@<`w
z>(_(@rtH0gVa{vyD<2V|)`224KL$GcYf~dmG%%?anUd>BYXm#p^?mr`%UNI9s%B<Z
z*+eNu`Bf{2tg9_*SsgDI_ at uQr{R{|O<DN=NRot2w at TCl?d`Ia#PuI~cn_eS7 at aSsx
z3;s1?;qzBOe}BcS_qs7U3$LFrk-l{!qMt(Lm>zODCim3W3fV@#f!h15^R32%&+qAa
zRx5<ajY%+$1XYh*Aq+ji`bH{^a?I|!-e=KW_J~p^`f#Q4**9eC at m;H$bZO>iiMnOt
ze?0RH)1okU<d>4ooJ1-{tQ4{*aoqk^{cUW5b~8pUM);6UhFAVrV8&s`Qt8u(^xdfK
zdG=`@(<#Q$S<7v;F8dQYEVpbolgK}l(_2r-*XvD~IKN!Byhb>3VaDaFa^QyKgYO at U
zTDoQh%^Jg<<rBJ%bQ_2Yv(MfTqUuk{RqS|en`QHK0?I+?i}UB?DWqpUTD^FYgdh!P
zM#Lg*RQ`6!xO4WqFYmt*th#)N-IMQ%@lq_!tEL`ninNHmmaWn}&-!HA<wnc{JM*55
zkBNwUyth1~&UYB6N5y>0&ekIet+rz-&n_Yxc^B at --q@9GdP(6`uja5U<o01>Z{@Z^
z&Z$!4Ug3hcua3nqUQtH5B;n%}RO|eqwQD6B>wm0wfUwuIsfcW~S`5R=+A!-ajL*bk
z*5gfL*3;o&#kZzAAykI{Qmw`D`I6d;TTxoq&!%ua_Erh5Uj5-tOpO at XDy<QcsZfb<
zV;W?tDvVC{GH$G78;}iJ45ni*w{MPzHHdwG$*)$RnA14X#rWe=%jD(J&mX1BJ;FKj
z>c-6bwb{j8-Ruzcl$R%{;+4i=enD}sg?d!#q+_P at dh789oSS`FDSXwU@)^3S6f(F*
zcB!V*4$&w at sDG0-6igALh@^xf!^PoM9g3eCVfA<Mquze|&?zk&pe}XCUXEr>7VG$J
zs9l!do7*6rPLx~M_R{O2(k92lp39tS$ws=%e$~@%-_{+6KFjpUr!i<gb4j~-L!4H~
zuE^6~rHe&wHtX4;yi(ioDn<_<xqQnBr%Sj)?W}{f%+ at xo>djA!9U!FNhfuRGE)y at u
z6?1#4307+^e`6vRa at -x0QfM^dg^eosp2<a$d|r4pDA&lia5X2IOZXg{?25JhB}B^0
zGe5?x)?3qFo`PSPKLn3=p4Yz-AeMFCO(-I=YZTUbmIxB5WjwU-?NMg_{DgADheawJ
zi88u*leey}VTWWAJw7h?NAvo5Tt;5djnGg`@`ANoorxpPy2A7#YIRnvD9?EJG;{UN
z)?!09OPiZQY at 3kLBl)+{`~w?mcjlIq6Sd0ig4TSlkcg&_`j9+S%N2SbafUBXWx-`j
z$si_6EmKUpIOwLPxM_{8{#XNzbdLKP<!zEct$|8HXI#NiSos*Zp6}tHppwR~K6{p5
zHu(KBoN~*6l|wwQDxbV!Rtfs~`Y5ck`dESw$Aqow2rM=nj6dT~T?52a`qw?{q;uM2
zKgiR39B`ntW at y|Rk&UE)ISpnHZ{kwm9J$xN0gqUEU*N)G5faK{N}ywHEE~H}%D~dV
zq+;BulYO{v1eSRQeY_neXFRjP(y1X6QR8N{m$ojxLAL4Dc+pa+k-51KF>W+*NUA5y
zPHjuQqyeA6QjFL7WN&BKNB((WPsXE6lLnl4ZC<lU;xM(mBI&cIwdR+OvD8oBe8nzX
zzRq7tP&J<Zx>16oCPGHBYkl$IF`4pLJ=VfJB_d5Sm2Bf1eAC9hM~76COf5oH!*oZz
zk}jQWs)%7pDt~uYCQvBg=9qBrhe{Kv4SiZk<uYxrD at 8ZEgR3b;({H6lsAQ`-uEnHY
zdX6$W)GZ8 at 6{7AP;{h?@bB0VD_?#Ue)cb{9<-BcBKj4CTr7{FLKyHv3<OI1w7QpdB
z=8!%5H@~Dz4xw+w&F^ouuV4&X%fnI4$x++GLf67v+uB3k)kX`wc3s)TQQpE-&BPV%
z?5bwsqwL|R>|qc0u+p+{Mwq#)J9)}lpx@`M2;2pbs{{D&2K|0dx%s|312IEt`;PgS
zkI%k?(EfaAf4+Sm2-1MiKUW69_qV8zEU1kc5C_N<{CEB3uMX<!`EUFYAhtUQJMh&4
zTW8>d9TN_DKvqE9Ak30?Ww39*UycKIgnmC$2?ttSAsgu6h23h931Bnm;P+4DL0nVd
z<AL`7Q;!MI^V=6wpM&xrl=q;V2jw~_&p|mb`T6`R$3gxF`5xqh(qjVjd4MqU{S*h~
zLzVuwpEf8tDwZ2oJYAsA99{FjL$pEcKmF7|`5pg=p at lBzpKOAz7bf3>{0{UV=sVDJ
zkRFUH#S0D&7k>ZljXC(7VO9elX4H-k_+Z*!jnCYi4+9!txWM;^3>cmksCUr+8YfPk
ze=!)uPACN9+5I2 at 3~vuNP*^b1(fYukM|V6h0UJ~wsG;88eb9~;rmh|)uD==#*b5p_
zW&!d-=||~C=|t&6=>q9}P`XfhQ0Y-=AYg4CuI46aJ;3<(_fYQ}_i%OlMWDSb%pEQM
z at BkKzCSbg1PhiKGEwEmo2bCU`1{Dt#2NjM^rz&$zTS-k0wN<~YCU;3m20HLpL#WGX
z!_mJkhh`aVeGR#T{85ZhRfTKIq4(jcsu=$x6S#l<4xu|4=JyMU_WhUDF!PP~2*!W+
z+28(t6&U|jEPutv82>3O|BQZ&KN8DdyAR`!gL?=MpMa2vn1qy!oZ>JgjEedQ4J{o#
z1LIMqW5-W0vz%mQJH^hy$#t6h3=c0Kzkr~S at L7>_qUSG&iC>hEl!8mk$jZqpC at Lwd
zsH&+WG&C=1X<ydS)ziOn)xgl`nz4zgnYo3fm9>qnoxOvjle3Gfo4bdnm$#4ab-x?_
zH=%31XCTyz@~;6A19A}vs);X(VcN$PJ-*$6EjWO2&y1dlT+#D2Gdi3c!h9p84XJ`T
zK?}G);~a#d>_iF79SZ*;6g9sffK9>CvHnvW)aMc;0`Wsaz at b8TKwLN|9cG?H&6mvR
zS(F()Lt3Eca#YT$U=MYaF-QAZqIEl<<6487xq&?s^w9t_+oI-E)ZFiZo&y}gyv7Xv
zo1k046RqL5E>yS;I>ZE|vw?i~<Dq5;67=kW(QkvEWo$r76Le`Yc`}3CJka`4;i%(`
z6FOH^m@{zpzfxc{@`4a0bS*Jj9e}SJno%+BfL=`5QT0NV&J~>#YDPxIaRN1GM(eXj
z$H&yn1fBCiJMp0FhH6XHF#|Q{F+-f-SZ4;v72-m-9%@9G{VLO+?P>CFTgnk#M$|~c
z9OGQkWpVv0r7XHksH1}ox}FF9e$d~7zxvw|q;N-%5l3`uS%JDTgB-v)2KtDL(u&b;
z54M=v9`qC@#Nm$?{ZHdd;2*}<zxKPuAMGv!^l0z*kL#}xOiMeVTMu=v^MA+qz-~AG
zU-dXB(?R?FyBe7PhxQPJM1Se=K=-ieeyjdZt$}I_R5}0Dd7$sy|FS>5&^7&^?e5>@
zC-T3 at 4>fAd|Cjll{gt0Hy2ns at Jwbd|^jQu{$G@|r1Ka$q at j##O|DycY&{{1ZZ*<A|
z_D2?mP(63hi~m}F0qFey*xybdH;ereW9-{$KO8kHdZI_A#lMWDKlT4To=~N7MxSB2
z at 6S00W9NT57W}F2+&}1Z*q;S$(3a?m)^7f5j<EZW`5fr~-;AHXb23M_zX?_?4)p)F
zQ&d|!p~nd)dcL(rADfubR{<7(jgtRtul#@X-+y0TR1C}*MfIrzn%)0xdHMh7zyDr8
z>dYT??Q)>m?cen1f&Sm~y(PMjFxG}SVmSl0L2F<}AKjeMKCWm!C=Di!`M<Q$uk}iE
znDa5BeKy`_;)96$e2}tc7Q+YYhcxyXw$B?cF?_JzCU>8y_gQM657t8=UtsuPJygIx
zGww6xJ|8{MH-llOgZ%gT_&yWu^NEA}o at 1E#Airr0v+VQy<o@%q``oh62j}Y<`|P{V
z-ut|_&(8b&^PoKYtcJFISM+%a>U;y$7dq%;+`+6T191b#40`(SGfP#lhq at B|eH}{j
zN5Ao+9R!J^uOpqnI6%d8*gxOEXh7++LyrJ2 at LvL*4m%gQUsle7*01rGwhO=7ixYkI
zi?TAz3K&jD4|{vCOMv>rL5+h$1P}o(C7zs|96suEmLEd at KsG0{sD>UP5p<59Usr<=
zbO1AYh!GiE8-ovMNM~>GAws<-f)FA?zkLMtvVntfXlCXHUDlT85#49hzJQ48uj`u2
z>Pj*QSvg3{#|>Nu9{e;gzmUj&I2 at cw>45(l;A{?c*2D`~6;l1xj`(2clS02g#{lE~
z!D(0=3z+B+j>F=3EKb1UL at Z9i;$$pt!2O#Wu^4qv31y?*K**r~|HJ$*j`NrM*RX$e
zivRM4g1=qJzj1%Z2>iq0{Fm;}^g(|(-2c)Yq-FkpyZQe=@cGw1wf=v41mOI3|Ly0m
z5rFgC;r^HI_XzmE>i((zD2IAu#-H?O*neH+{d)h+|80GL*ZcppcP{WvmG}Suo}?|k
z(Wa$WC^SOBDlN99D!S@=g at Oe_8{{HxO`FgL(j-e#D9W^4)K1yP81BcEX+=P$Y<7r_
zIX1h=v`(fKnM203bEwQAc8(z;!vFI<=Q$^rCa9a+ at 3;T&m%hGzf1c-@=YBcQIZ2*`
z`lz2kR$iT}R<Bum+wFIBeeKS>)_wgO-(3H#4d32)_jmql(|7N=ck}n|yTAK^Ee~$p
zw*8?U-+%a#oj>^Dqdh;`_1NympZM{fpFH`~y+8Z;Q at y|V<<t9q^~|$<&;9!O{l9tP
z#r~HLynOJtul(-NtA~Go<PWdCKJdpk{&e)sx86SX=Xd^c{M{4p4gU50zn%R1sSi$n
zc;=(CAD=t_Pe0I#{J`o{J<$5^F8_ab`v39=ijj~1kEs84r`>0>7J7XapZt at j!oAe)
zY_Yo9i1^pW?N*D`IKk+1HCbB3*WStNYWKAkE_HcqmH at Y9vB%zQ(cH$6<HmsF4%afv
zQml*HZ62Si5Z+46Zcicqj;}=>pKjjaNVuIh@%}c;3vaSn92T+RO{>e<f^0a|-|=pB
zIpkw4{43+eCXd}`k$(@`=4_Gun{Tqo&-m3y)iW$@HaTnUUN+PN^5$J`*WRG;F1K0j
z-qym!cBdSV*KOgSPcB?$bJ}idw>i`dtN!ht_Lg?b3eByQ)2NkG^S620gWML6MGhDe
zA7E*-_}xxqRz5T2yf&BB=5YqNZ5=q%sku>K)^?Bfv(}nFV#4~^GNc?fhtX?sEVEd}
zhC`ZvbGz)Py3tweoF^x5kJaAfur~+C)9gYQGpem0=<jf~HQ6np`Dt#If8JGdH at O`4
zWjIZB^UuIKeg2NZzdDQ>w|Q-aO&-flc8A>}zaipud6wH+;3#yifc7pG=llJeTuV`I
z3iTIm^bU at yQ0)tLk6e26CJ^oxo2M<{u<CZSci7sRT<spUU#kB0=2oB0iF*;dGtl4C
z?!`z$s*61~XLGARKH(k`pYTV8TdV=$nrsdw^CE|Z+ at Fa8-4yIz8tm4_`-<T4t{x8^
z$Ev^crr`6IpttfVs at pDpe_M5<_u8A9Y+610{hdK>6iD96Om$mC0W`NVZq;bW+U^Ui
z26>!wr|@}DPx7W%N>i);yy=?-okx8K*ze!wcGwr&)n5o!{dv9#m~K>mCajgT1`#hc
zCvpQ at 9NG~z-vM1I$ln;jpF&<c{;E7jsF^iacCQa{cZ9fGHFt&VZWQiWb(ON)q#ak@
zIII)yg|)S^yH;~gm)+&UT~*s4yYoZNH-sENJs2E*U{F17mfih>!TH%U7 at YqdgTeXV
zq`8%Q_O8L;{JS-`5?`a{R?;_V?iosXG`I2rihRwj<Udw(EBQVBp6Z?^yN|sWoZmws
z?mpq3S})3{xt08OYi^}H>ovEMey4C(*C^$0)!a&Wljc^!muqe%e9?Qs<u?lVbhC2Y
zAl$QN*DK{a5$qn&+_RMO2)D_sl&43yYZ{dJx;3|Qe7)vY^4FocXDjWaxs~#iYwl_#
z|C)QM?9S5M;*pQ$7VYt_>Q?&WA<eCPkf2X<E9L3Y+)Dj)Yi^~!yEM1bKRPtGQa_EF
zTWN2T=2qT!pQ5?1m)-fo-Eh59o}71s+bc^wU-Yju&8 at _52yw>>_gs-*67Ff0qCJnR
z<4q~=pz2<z)Zek=!RH?earYlr$EVUBy~164osz#E_4q=ieRqbqyF=1nAL8y5Zd1Kd
z{~gEG`ngVaw+i>d3Z=g03-@)Rf7XT^pAvH1DBNcA?4bHp%V!8FFC7oA&$N*GO-vk_
zILvTGRAOvlls+oaV2B+ZJG;t66;<-nO`4^xGiC*?Kc?B#&vea`ckFDy0-U#sg#TQx
z%`>}ciLKc;-MN^5hMo`1^M|XmczqSkKKnA8$>nZ$YyOI#5*^J%%$62grK>{;IhPu!
zhU$kr<BaL-yuEW(Ckn2=z4P|fooUh0H8nN2-F90v##&LQsk4h>DgWXrrg at z-j33gP
zOkG@!`JG*z2t|#pjjgS%v9ZHC-0tOW_mJnaRWzGs!RC^g^0?k-ny9{^x}oO5!)srw
zUpMpXHFKZTzp`M9+y|~+#AWv`T7so*vulyt<KkNIE>aehi<;dle7OEDa at d;|@qVxE
zKD)!asM*zq6_j<+ax7f1uqwQ2QV~`K)+<UUxvfp~NiQiameQ;+^Ds&)jiIy>gImgq
zr!1?1vdqbpRhmRu8`Anyd*PoNL#gHwlv<ifsqZJavx^caxAYpyl}gDlm^6^sAKx46
z9 at ZFxrtkX}`ZfwBCC5;*IhK-3hf#7#f?JBwQA~-hNQ#f5c%&C!6603#5RW{>ArH{?
z26uLDGz~8;pyAS`6ysLn<Bpd-A)3-l7gD-3pVV}EbVz5IM8j6&_{3o}(zlRCmM)-?
z()E-e&gtfJ(vU`JB9}2Jx7imbjL#mICXJxsg9!t1{lj{r-BFGDBAp1!?JVUaQjRs1
za?B}|Q)-}`4OxR31EO9=C(>wN0*yu)MxzX)QHIea*#nvV>Al$#6DZr9N7<$0C|k;*
z)B!_(Qg5O=p;3vuA8{*XU5~P^)5>a!g8!valqKCkDQ-g}`x&Fu_8N}5N<djq9uLx&
z>oS(&>to#6d2y5~6;MDqOu8ZwC$~qGL{Yy)++$)WQ5r?+8GO8#^HLf|<E&$J<4Q;C
z#z|Saq<-X8t!D#{XLDM^DSktYTW%8$bCI5srC6PsP7$9sAr5_~6!|Zp(0(E3L(X%Y
zoM*L9WS1t;SYNSjthGotw)8UHSm{z-`oM_(lwQ&PDTsG6pR<6*TIbW)(s?vis;9KU
z)P957Ryxk3j)qAS{e9+=I2z at fOrxwNG^(_iMoE)MJ-<<{lS(yQy3%(^b&n#gZe(}1
zQWvE5MJxJZlhzmc4F{!-&_3pPtv`qLQ^$fz9xK*FjFosw_F#NnGn@*1>AC`Iny#QU
zRaYP->a<>`)+N{V#c`Bwz6yDng1nSaVE^jm@?D^Rs%6*eU;^d=v}I`D;Wm|0qcQgL
z(7(pY<;}hfaaj{}qs<Ar(WUXa(FkX72b|AwVhWO?brkKB6qZWLoZ!<_yj8eI#L@^~
z6w0or1T*TG{nY%(ZFec!?h>?JKH6 at A)^<iNTS^?IGzE=YInQC|HMxE<55X<ZMcMI`
z?Te#qoR^LBvf-ayf;!2Jqs%Qqb3{=z($v~1V%!1qoIHoZ%sdWaDXT=8E3z+5!2B_W
za- at u~b7r?XF9%RdSJcUn<8eBQtB)>{5~3)<6XoWaYe-o``&w=y<@!=67xR2B=J;HX
zzh`Of7K!mXp0`8#Z9rPwo|tDx)F%$8r4#3xQbd at JLP^g1%KNdVg!Rl+-f7p)3yD)b
z|8<=Eci8iR=X-Rf?1BUuX&sGuKL_)E8jToC8A$FQ-kX5_c&u0n`!*`q_aM<*BJ4eZ
z>E%RIPGweahC9764gE(=FK;W+8?f_gdPx!`RR(Z`L?gnvL)vUe{j+~6{L?XqY)Ntt
zZ%i!Wc~**(D6UDgtK83$(9eb|*R2icXKEXSJH~1Av1Eyon?zm$-GSF!t)8Q_KC71b
z=^qgN29`Zblv%#^4ac<)#N3oq5^(KP<H^Pt^1-bBaiqrg%%enyVUyMP)H;#JUoyfZ
zVf+n8xJ1g{fbkc}|3cSbE}KuxC-QtZoaZLYcbNB(=h5}zdVFz0O?GJ}rB at jaBo4+8
z#P-MZV#GA6*Lr^7AdO3;alTAk2Qz3~X*!KNkTW=PAge#4H!bqmQ0pN*meMiTreo}<
z<NB6fpCZ=-mwfIsM9X0_MLn#9ULWAr`UbAC*&9;bDMc8IYQIw3Q0*TH5+yW=bx%{6
z<Czj=Rt8Y*mx2A$Bl_ci8cT+{FGBtG9who5?4({#7xDaYG#=NOIP{6wpkq>I3}vEU
zWR~#SBH7JhJAcccxyJoc6v7t7Q^CnjG9Fw-S-vhZSnr_N(%Xa1k%nW<CatEJfv8^Y
zI}zqvQ%WM%S at l{k)8 at TLUnSann5ac<dkQm0X!C27Ki<GG9CGarJHB%;UaiR(FG-Z+
zpX0T${=pxJqF*Ok71{@bX^P|WV%!YJ+{$ZIE&Kq=@kgR<2+!2=lBmP_GKI1y at fu+t
z#^BR5TKc)NHW6cOAUY(^f#uQWxZwMOPZ)ng>rPxBQc`0nbwko1u1Ni{y)o|S#;787
zT-tbV<YSokL><`PA=>he-z{-i%zdd?pQhF;t1IRDJ_6VGR9xS2ue2*<J``n9>#1&#
zpS=;i7F^Fm&bt-o+y?tF^t_Pk<_?^*3zjxp7x_Lev`>cim!Nq#%sMFaybIOwkacXB
zwMVFbm^|~Ea*XeB8e`o}V at e;RF;b7V-g8F>)Q8+}hROX#t&_25iB`Zan;lShm?N at t
zW66LvGI;!}Esk%BdM#QV5HHuoKHRhUK+GN4=y%!m>HTUNhwy)`B+(2t4Yh7Ayxtnp
zepS&DEr8iV;}Pcvmor8yC!akbMxr8ErwCgE?SOTwaSfdZiiX5HA_{A?VKky7S&Mf+
zt|cGBek$Tgh?S at k_WRip<_1Fy=Ef8<?279h=EfQ?bX^#lW|EGQO5(L~SB7g?BkYuj
z|7Pedunbdh- at i~@6eUV at 6|7i<F+tCR%~9jXjHb+{5$@E+6qBJy?dxb?%q!Vut$lly
z_KQRNVGUo8_LJ8dm@~2d$iey}r`|tzW>3JJB;``*U57lUAx-7E$V|$WD#NbvIpfNG
z`pB^N>AiG;F&R=PLH!nMo^0G>W at EjBGRb$&Tu=NNxT28~-2iildU+c9vQZMP6YhAp
z>)_sL3h9sPeOO at v?!o5JD6<LoVY6``HiMMf5clS~3topVaL*JlW_V8JxwIa4^xAWh
z_ at VbQpEg`*e~nb9pVdFYy`6R)&y1x^Um|6qEi%y-nI5d;jEQ8#STULnWW=@D=+V}c
zZb at D<!ceAkq>)~d(i^tELgt8+q2aW7>WjGN`6}#LQ<ym+Qn at 0vkvYsYBxt^j3tjsU
zsQLH~*5f~hy%}jt%Xz^%-zwJm9)G{(5RYFj(GeKUQNk~R{`d-sjB`S+k3sA1SZ&?S
zdHBhd_&-IWFNiSNW3iriBmA>IdHtV*dvsqG#(pNoeg^K<Q%QXeHKgzH9OxT{>kC+t
z*el<Qmqh#fTo(EV>NE>=n1yrDS0dKGGH+NhZ!8QuZ}jPgUMEsU$NQh{1U%PK%f9J4
ziOh8pt(g-rt}k?NAL+g(WPViRUoumo*I?gM<Nt)~U~s!92F_Q5f$ctFwnR%{dqlkN
z&O#aBJ{H>UVeVfK;=I>j`g-*mfbodDXPQBri*^6dIVALcJ;HTeX`_W`BU9Kma_cTo
z2cJjW;nw&mF_eNjOex{#9r2B7J&ao}(KOiT`k*>1%Dy6j#+QCYKVDj_50{Q{RLHo(
zx)*bcc%I^q|7*8mtpK|sF#bsQYT+1eo>c25Bc3wMNtA&(A)`KZP at UC3sXyLyyF~Zg
zA<=9#Ps8|`?Y+vptXjBdC*k}?#nULC0oT1`T=SA>)P at Mp$2d>*qJ5h#u*Qfq#zOi*
zT*y6v^i7GPzo}@M;&|wJQ*msDIB!P4d7t!5?MFEGW7v}VfH`95x?jw(m|s!vp>ym9
z-;yZq+Y+s=4;i1CXjjy0X6bOstoJ{aQ^S3CqeK_qjW$!mg}W#Cq_t9n>+z5^xZExQ
z>-rM^wTAQZ+IJ<|dJpED(0T|QbCI-qpB&OAnVZojuztkJ98$O8uDPG^-q;17=gV!J
zpuC4ruRi1Ebs^?jvzTi=I8S}gC}54ItzW|4r-kGpoL_`{odw^Q$O?Nuuy52~_+E?8
z+<`DxJ}lAj263MQy)eN2Y2(?3FlCQOlrO@~fc|oTJG*!|<yuEku6ZQp-)zjkxTn`v
z`$|9S3O6o>tdWP;<oZ%EU!<VF8)!sT(uVlK*nyaS<rxvjQ>)c)3hLKD$p<j+7Y at HX
zSIje+m}f>zPV$6?E7HOxBU}<C?@AE!6XqqXokn5K8s!o5leo_svUXGN&*Xa>1J*Y~
zp9^VW<@W~+sF&pM?+=7|E|5J!na|{F2<P`g{Zt*B0r&CQdBZ5xI+9Y+2B}g8CAj_X
zi75RIeGS*}G at P%@3pn4LgY!q>{4DK!`Mo*$J=IY(9R4u@{t>T5VV?1*;~}(M*<*0c
z*)a6pul7Rm2aWeI&-AtRK)^ky+<q9xrEvjcIm~q>+#JGvV_!<}^=ns}DSR6Io at 0Xi
zo at 3D56Y2SpHlOM#yE5G!_<qSx-;wA8Sd}_PL!Uc`K95%2>9~Kvcu3zRzZc at a#>&qa
zhGTu5NQMoG?jiaASFN)H-%t35)A){*E3K2lr7=G-pdKTv-(JR8%uLqN616VFt^F>r
zKAU6E(QU9bf%9ePXD@=*(ZTD2FQp=F*k(1n+^3R*=bR1bQ|fyT5$1n)nvQOUJ)xCD
z%tQQnl6 at m6)t5r42NFzDUOeSt?B~5daxiNkqd%=T)t%C4FlqCAnx4{D8{EkO{mnN9
z`GdU_dQFha7*FvY|MS5cb9K}S%QcI0Q8xxpqJP~cmk;H_nsgMdp`#EUbE+w#e at -0b
zY{7lYKuUjd?{IfwV?t59DWD!W9Im^g&_1I|G6$8_MzWS4_e33Sfwijn`3%>Qa_xFB
z9PO6K^HIn=lAwK#Knkb}W$sVG+;12<_kX&3!J>%u5$Rdzr(E|AIUZrY%g&3xJY#ao
zFGKI(<#846Iw{|07_bgiuCJN93?cWSB8 at O>!UwL^(X+5sfo-%p;My1d8aEhljl&u^
zR@~#nY416y at kdwcXd>+1kUkLc{iF-sk5%dDr?A~>T<Yg7BCY4Oe8msR*KccdbQboT
zz<f1 at nS<&t{OplK-!(%=W3SWETOzJW(A5F%A<qWF+}rV)FC)yyFlnw5ZVPl`osNp<
z20nWT==UMl-T|Zf>m)?y#_P${sH5_W{C<7;dg_7Sp*+8z^-?|6T6J_fAnbAYwc@<>
z0e<TzLc^~wAnXs}Hw9sP#{2yS;b*kzDAH at jMCIIA!7RaB1f7D51SbeyEqLlue_H%{
zL!{k5KG^@);=CsXe<-*`aD(7#LAT(ckoad^Eb=4h5L_wPC3uhE4+VcNctG$C!S at AY
z@)eF0oFrH&Xck-|c#Gh71a}EuU97M`uw2BSB;4nU6uu*PSa6@<F2T)$cM9GlXcaUI
zUM*-8j1fF}nZl!j`vspAd{}UkV3(j<uvYMD!AYVVV+GR$qttqwpzw%bzu-tw?w<>H
zk6^c8m*7o;4#DdMrwSGc<_IPVmWce#5b0zI_qj<TUxG&k&xn4TRv_w4ut2a{@JoU#
z1=k7QBe+ZO*Mdg`PY9kBG!!ZvBREO0T(DknvEXXKZo%DxeS&WYo)U}^<;oGfLa<V>
zPH?{962T6^+XdGPZWr7o*eCePq~LLQ-^5_|py>Zc1z!=IFUIc-!BW9|!7Ra8!84aA
zJT7=xuut$w!G{Gm3EnBVOmK<d^@5dxC4!d<juA`}Jewa}uKl8%1A<S6l>0U^d0cLr
z$G4)P)n at Zm@W-*M_`8s{Ab*pk#fD>5vu9SB>n4{>vN{|@oly<Sr^{<R9{#%DN)fW!
z?y)udT%HvOaa@{a^G&roY!yDA$KKTLvw7jWKtI#szTR$IK6^1AqpyjO?7$JX-PuyX
zdy7;#TwYtP#c9Pk9h at 4UV79l}=onSIywwQ8F0)JXkJU{J%2QWB%oX%z)Lds<P|A(b
z4zJJSusM;QT|cwk;j>q+K&-BLcB`$b)#9N#o%rm1h1Kej_f)-BU+1z|>+DS)i(JNo
zRBdzE)HI&f*V`;sIdbx;c{aK1P9JY7`GHy=4g58=R%xooW)m^dMn1d2XB7perJQnr
zdj`^Nwm3KlHA_?FkNS(x?IRao<Fn1SHaEvU%hJYvcd33Ri?0>#QS6 at SvbH-!t-|jS
z_PgHZ@!DO^nvM#}h^n`F+fk{ls5mQnCg;lJvAaBW--;@Sg=^p$E=5(l$76G9Th0DD
zz)uakox>^)H3r)1?_V4aImq_sDj at HA<fF~CET}hCDs5q3ri5RNv!^@JX={i2H}E$T
zxfhKb8v8t=>uTy})o49ARp<ZyLj_He+sM_-Umd(!zufCaOuoexbhi$rsdltX_u1Oa
zwhp9wGkly at e;e3!_2>x}udTX@#&Im*6*`m6w$y*l52 at Pjbz6MRt$x2Kz1d at NdL78V
z at WhNvHBPI^f~5IV$=nm<Eoo-jP_Sm?EQu;@Eq13k<6iW^#maX%<i3hp)z5WX5ux~k
z2feLpXmu at DU2UQj6gRi~Y~;PgjwC#CBg<o#`#GA_>+)1ku5PAF`??5qbB+{8J(`EE
z(wSV|fZn*6kDDyq8EBbYOQPbmQ!bI~NAV>32G^~U6wPg at saIR(3UyAIUTODX=n}mp
zMw{}L7xXa>$<0yaa`1 at XqhrVHcAm>_<ztmg(fT%84(&h)HC&lGGq|`1nT4yt<*-{T
zJ?;EW%4yZpMK&B<H*?x;o)y<y9PM1bS?p8eY;U{Hwt{P~h~4sZ1rKTqKA%s(Vi$h1
z-8QEP at l|#sd;T+~$Z^Qo5a(ROK1y-nQ$f at GZjq6S>gy{^YBp(%gxT8RsOhjZW2UX3
zhT57swUfK4$~D(%ciMe+i}D at WH25gVO?P^I7H2d3D&aRh;2f93Cc<~>v_8l)ZG~5x
zbAP9+wOQQqv_vn<y29abHPb{%J;m(u2gJ22z+ais)R_LJ&W-`!WU5 at D&VS$3^GM<W
zY&F^4Haer8ZC(M_`xr0Wc`?b at 5od!<-nohB3;H^nWtnY=|8L~}CwBl&3H85Oo-L6N
z&F8ROntGd3o-v`bC+3k{DR8^(=Xt+hbT)OmUnkFr$`_96>`t`E5 at k-eczo?{F62CV
zA<As?wAr2hDG{qAT&G&)B&;<Z%{DjZ7zLHDAdm5!8u74BKiykxYie(4v3X3mT=Dpu
z5LNGUTyIB`7ROxYayxH at kjs8`F4xj_x4Ov{s*m?C&f+6g7Pqh6W2?g0z+j>isN2AD
z8Kc$9quHfhGwFV{{ua8Nfh~yDnp_Vi_9G{2`Ri`i^7*rCX0lF1zR{)a)+$bhC%}c$
zREKw(7$0;4yVTJ_3)m%hxaWslb*7_q^ZB^aX!Luz4G}abM-K;F^>FttpQDTgto>wH
zwG9gc*9t0)o`<d at UpvUgbzkFLX7{+9ZAkHYi^pzh;*MaAaHN8IqZ%AGo14aSy(-mT
z(?NgH`A1nu*Q{__8?XYZa<!xF4v5(<wEIqwrdoU!M}^zX{jY*na{5ZIR01k9G#b#0
zA<Q+rE5I#Ji1Y;xqn?39kP_TO6 at lv;^zlS_O~nJ%rgT|qk=HE&#Z|7h-g)##P9 at v{
z`o3PC5KT6Z+zgm)<cuP{dz60Dyj0};*`ccoH0ovgx+<&<l?dnYyZiD;Vi%8p_&lf+
z--g7c(1KoBS2ewwC_Xs%7}co~Pu$9kq#WR at U6R@Z6)(CGeF&EUZuiRe#f#BZh$bt2
zLDbniI->L~d8V{t=4^B0il^o9n*nRjd1O&~h*c~+X^y(CMDaKl`j2>>7q14_V&8HU
zcF|0Gv&ZFyYmu at V@GcT9CkEG|x$@U6Ee>TL1!JpD{yuD$pdrK^8{#Ix!4`!_TSAV9
zywv#nTY}?P-T!R->hG`a5$CCU{p}ELb$`iC!maK<*`ek~xEs}Ugu7O_hY9x-;m%ac
zCEV(hFoSTXsTmXQ!Nm$YN6KI2qtG%O635H4!yoSx$JdQkjz@(Y-y at Ef&I%vCTO99*
zaD2Tuo<BPL at qe^msjrePuNQuIBChT?8V at W!c>a9nI(<+(s_vj&y$tk;FI||te$x4o
zpIZLk>;GQ=_xdz1bqw(}C(u9Ct-d<l$~YbTt8(1bVE(7lH&y?0;d`bk^Ua_j8(%}z
z`9Uwp^DJKrqKSX=LEZ;f-iMX12fPn!tYDmAyf~H+a4bWFWhRSw4Z at H2QBD=c{uc at V
z%Z0l_xT}QQB*N4S{|3Q%BK`#;ZHMsZ-ySl;cp1ZcD0 at U+W5oHLBG0P?SBv9o#PPKv
z9{#vL?+ARKa6cgOvsI+`knsPp$lnX%`0vE=tYJ!BsCD+QeHkLYl;g&TuYY;g{w=S_
zn?)+eBX4H--<$8x^Yy>I4}`q_!@ERJt(d2EQS$V$6%%yh>J_Um634f{uJD0v3Rm4f
zAaB`TeoLp!9XS6N4<3Hd7$N>u=M<I;KK?1suMm6!=fAk+=$4W6=9XhyZipQJEf2_Q
z4lXEj4u9#ek-mI*$>EZr=f8aDwSf<bif>Uup2KyuD&TmZ_+6!ag1v%!1@{Q<7VHt+
zA=oXrNw7<>L(n1ED7Z*)zMxsqBv>a{D_AX9E?6cwMX*$`NHAY8OE6I|DkT212Nj+a
zJT5pOcu25MaF1Y*;7-AA!7jlL!MLd4`w6%3Zxw75oG)k+tQ9O5ED|&d8U#<jEb=SZ
zFStjrM{tK=x8Nqh^@3f3oq`>LZoyW;M#1 at lwSq;0MnOYJ{3JMdK;&1jPjHW5w_umx
zN<p7squ>-lqu^(`XZvSf>hF&IPd)xgb<sOFeE7kmqW%9Y+UqZ(y+nFFrVxtxQ(d2*
zd at KBOlu*A<YNyZp{LdQxUmgEv4gbIOr9OY`9Qsp5|I};#8)DviBe=g#nIz_w&xxFO
z{!JPF`9EIq at bAO?7wmE3&k+#)4VHovi(s>0ZIZv-9PVmT?!A_i{97Wl8}>5neV75~
zUIv>9bBJ)0gsJ1ZN3i27pAT;puiYZvm0$VCsLnI*zvZ8|C(-|Z<KUBizd#rA(u<cG
zUVR>NPK<+p=QWOBdAO_jfbVQR)X{11cq&mEH1pgDq5^1sD7_#PYcXgCI3f$zXXrF=
z2FwlJ2yTIOKyL-F$tGG0T at Kzl66+A?PH at 6#^jYZq(eg8C>Vw`4_G2*gLo;1Q<OA9b
zCXB;c?u?ES!RPa^-h<u`{$M=Tif8z<r9=;1jQl|F09WNBUFfyo_)Cd4L+69<!Fr$v
z!RCor|3X{A4-1ek^jWa15d9XK`6xQ;X^tPfs0d^6BOT>|Ps56!_kq7HMjoIKfzMCI
zoCCcd99xQd;Pb(6z}7<V2FG57GP6H8?Hc3<x)wYDI|zLcEGfseAG#Fu!J^LU6joqu
z3(e%uE95})CxA}F3ZSzpF?V30Uk1(mMK#vi(EF<Sv&>l6K_3FsrecgjGfl9y(9EW3
z$Q!g3eBnCO8+1QdI1_aRT{KgEkARLsGnesptsm?7eF1tB77M)>EUZUeK^K8r8<00>
z=C<pRH|QPU6Z3Fi0KEsi6O*PDdL1|cw?7W(a&Y>WP=4q- at Kp=)34Id0xCwm;Iv-4K
z#yXPI0&j1 at oCtjyyt5VSd5#mj(T=_ZJ;+>w`v7R><W;DPb0`bA237#Q7PPKLIiUx@
zSJvSA0nHDyR^Nv9g+2;CawqycbkWy|Mt%eNVGUaOyIRo9XJK2R`7`-%!gg{z8;I`y
zHrBw<J>ZM{V@}ZhptKS73>^iI!3AVLv=Owy4nenqzk(g(I6?a+^i|F?_})F}2hf9{
z at m`ecyiR5%EC;$8Tn@{F?f}0BD}e3>{{Sn69sr9rqm7`MZ^5dekAbcCqc1 at -?}53Y
zH-jnNC_8i-_{@VC%g}w`sjd91PEV)7^lkjzJw0WCmv7 at eXY@1$T(ph9!=abCVjF*V
zOiwGp?rr?6QcpX;uI>DN2EEKjVU5r|;E0EKp8`Flfi(~DGfF-6gJX8^^;b_u at TDF6
zj8abr!N2a{{Verl_&$;6VdNQlGuZM7`Z;tfc*`UF{Wv{!f)jS4jiB?v8)5sQ8^Lew
z<ZHT~HiFOX<WF?zX+QWe>?l9^{Q=QUu;W}7 at QokvWUi;9pz~4GKeQV>537YX^x*mq
z^FbGZtv|xp<a5Bsb`foa-V5IU1o{u3^JCm+?m<06CxSIUM}DAd!JenlAE23?zd|3-
z>1EyrD}wF at pZpbnCJAwZhkwO;mgwmS_ at ie~=g__2h-WbmK&OGbVH=^DFFnh9$f7>M
z)36=T%=A9qe-`ZvUfsu^*3wfMcq6PAx)EI4$KNT_%X|RV54{z94t5B7KloSJ0Q5;P
z{W<h=juX5JHpp>;TVSU-EO_y+QMb5^=7V>^VxiZ8 at z3*C#;70A1<QhVgC}4{=s~by
zKdvLtX7B*42>Kv+^>0u=&}HCLuyW{LaNG-MFX%jQ3(N$)6&&^=`X_WOcsr~Sx(hr3
zYvr^+Z$J7cv=2NC>wrE2e)%P|6Lcf^46F;f54`RG`YLoC_$X`>bPqTQi^6W`YVap7
z^K&V*Blt&H5A;!R0T!HlpcjE_VZEIHfPLSXH~$uO4$b^3tPeVHUpMBGL+C%y%;m5s
z=nn9 at S5Xhpb>L%%QC>bDyzTeMKXe!P3)nj7ec)l(M(C5^l}9kvpr?RKVOyac;5Jwf
z^bYVf*k0%XFyjxH523TbXJPxH`@ngxqn|*p2cLi$qV==~JPON#E*e0;`XkyGdO!FY
z%mh6EUiv4r7j!9j>rvz%x)b~<tdq|NKZdP?rZ-Usu#M2nHL%UlYr!qB9_X#$%dkDr
z2f^d8UTCKD7U~u{3e1M}L+60SutS^&aMwHN=g_;~;eF*XKg8%|77wB=pi4m)Y(BIb
z+z9K0X6}RSfM#yQO-3L4gRjDlKpz1UP9jgxiQpGtC!x#0rLeQm4sh(>(Z0hlcEFvm
z9BAf#SROPp^%Slb&}rZ-SShp#ybD&wVZmo$)zE#Q{sW>q=qPaOX<R#?neV`?(8s~z
z4{@!BZUs-mRzfq6euVxH&Ajg{>K3{iEczJbf at W?zkMp2+fT#JXM66!sE0RP8=tKNr
z0G&kT&_#NQz8 at t~E%Z)MA1%>*=qPXntQC4I_#CVYdOx^|_Y#9%3&swU=pZz+05$;4
z{Bo>Br=c6c`(Ooe7^h%yoJ6J2rC?6HL}kz>a1E>udM)@a%nWTzkmwnh1G=A?DA7*n
z4)71K0q6m6eUe0j(98+R$WuJ#Jy61pWfpW4SUv*jLNjM(Abw~Q=*^O-1KI~Zk}c6D
z=-r at ultg{d%x7R(31~a;EtnBHCkOR2MxuP^mEcpbIz9)?%tidrMPPF-?_s7VD|iyt
z3eCLPDA7s|3tpKg(K=`|_&eBE=tJO_$4j&ux)D5^FVQ||=8cy~bcFrEF4$4%O<=~Q
z5*>%m0`G-ICE_{`UNjMP4V?$>gq1?~f~^G-nV{E#?n2}ln!iiej+^RM*5Fy#T4?4P
z+ at x>fIKiL5c0%t3w-igX7kVqmd+8p7X09wjnW34NOqM8dIQj<o3d{(72&^lWs0f<*
zS6Df8&gBy2T`5r~G&6S!+5*}LzH>F=ggy at b{2GbUl28_K^0kNux)hB5BI1FL1-}S0
zL6?KK!{$SGfv>_Ep^t!Ta0l*#-T}s6hqi!D1WRB&94FXOCs8jn^Iq5>^k(oW*lErK
z_$L at 8V{C%MW}+WL$AS}K2IvBCHY^L;1fGHAL!SlPXCa@^9pFA#BQ&#THqwS>{tea(
z%^ReDeGb|kdObLy9(jN+1sB3%4Y<aEt6&D`wcvljvY<DCM_@*1rl}eA2F-j6W`;fn
zCRru2LL0!#VGaX-S5cztU_R(Na6N1#H1nf&)Eo3!aL+R28=86Za+C*pCHNTZIP`8X
z?N+oSH1lsTV+zIvcvUC*1auj=24;rdybA3PTLjHK3A6I~pm8<w2F<L4`JlVNFRek|
zpc}#Mu=UV8z%Sj7KFt2$kMBTUq5Hv;umNc5LOsEbah%{qu;b80U@>eEx)l5~>?HJQ
z at Q$yc&Qnou;0t$RtU>pK(p?y9&{5!3urlZ}@L^ar^iJ at XusY~{VB*(NUTEf}Fb8x2
zcq7aQ-3Z<dTM4}heCHb&o6yI><Znu}5!wJ2!gfO!fpcMdq346`up=B6ELe|nL3e=b
zU}+=tGP_|p(99dZjq{)z!3}q#PeN}7yT60_<a5BAH(|blUJG`77i|sA{3+}R^j`3p
zdyp1%ANV>fCk^v9m~}74IW*G*D}rX;4l9E;Y?f#a%mi%)?}oXdH-SB{4vvTQeV8kt
z_kq{kk9vSE2i at JsD|81qZ42rIx)!|lL5ceL9I$jN+8vttHtaNX^)_4ww`2ZHM;`$D
zVFqaCR~|xLLHocfcOd`JQ^3UUOEd+Vxg2JO?f}~#MtiXaZ+Zmv1HBU5{3znj(93)U
zRsek*9M^+9LFa)tz{;Q(fg54f&^_QykD<>%uLM(fqi;Z`fu6_FAE15U`>>tRC&A`l
zpbtP>!TMj}dJSy`--R84E_eoG0(KmlNzb8gXYf6RL{oo_vS*^+z_Tx)&7hg3FT$Y9
zz~!(q=#}7UST!{Bu72bbdL20KC5&I_Ja8(kgX09>fptPV4xp`HMqh+BgGXUIGW9Zl
z^a}D1y&HVvcM=_9e=zS5#v{iG?uDI(W?uZN#5XpS4 at Mus*n~EMZ^Mkx$G}y8KzQi2
z;JVjQ7HDS50Qwtr8u%yJeCVU#>_4LaLz}?$uvX|zVDB5~XV6UZpHTnM%;#Y1p!b8{
zI*Rs&-UvSTCfbGl!8vcCKS2AyWpATg(4F8Q8#MEcV-kP0iH?G|{26Tl-3i9LgK-2M
z3%0-tpj*Kae?eP7r-7Hl8lk6v3t+9#i at -H7H}qO?8>|C*2lyha6WVYbedJxNEufjl
zV4I+s%_lIXpsnB at SPwMw9IO|b-b1-yeb8p`BiIq>v*1H#(62ZxP<Ix6X(Z-Ga0V<7
zx(@svtY9RsX)$I$#&sOp4BC@)G#}alRwe6bEp#>bDr_h85%4L4j(VYc!4WAsIu4x%
z=BDcCB(xE{6&5=RbqM}_gpLZJDNRQUVAarzz;D3J(CfidFduYcx{elR=x8PMN^sm5
z9j$}T13!fAggy(tkgKCZ(EVVFQAcN?)4-{)s2ucpaMD;EB|=XDH;vO#9&|VO^rbo~
zgWd<eK2b-Dpa(!>0n&ml12-1JpqXc2d!f&Qmrv5se&}lODcC{iO+`8yUaX^|&{^PD
zC+lbsx)bbyC63n1JOE3BJ~)|wTSG at V(6L}4EDyQ}{0gi9dN26Y<vJ>b?gf*t&`}+<
z0hF#py+KET6Jb{90&o`00c`@CVLoUpxNr*U6M7MND{LKfC-`mHM(B;;)mQQJZ(P5a
zWjfjo%^ZIX$_SkgPP`Ungsukv0;4f#qc7^{$FL&kJ>X&3lrg;CL;4juDu-q^S0bO#
zR&WJuJ%<HTtI#&kY2e>rJ<un?Usmhr2=qQMss`yoGbh82LzjY+rlQ at UV{3I(1Iy1v
zyMsT16+!O?yLgWaXl8yL$_vemo{4sZHh}A4N1&NoU`L_(cQE+3En3ej<lm}Te_kQ~
z21W0Ah01R;=w<TnDx8L9@^1;0OM02Sw|uQmFO&CopC6@{$$PaQf at bm_=SJLvGkI_F
z0ca-gKW at T3GL!ch?|^3V-rC*JOx^>#2lt^&-p4u?_k&E{m%0&}c`s}eH1AE#`%15e
zX1)R&gyy}adH?5Q(99GQ+6(u3yazPz>AVP<SqIw+&HFm at 9>$xYnRmc?aUaL~7(WEt
z1I>FF^S-w|&`jQYb~o-*<UMHTpr7FWf;kG-!S@{??+xpQX7XOCz0geF*K`lo|1x1l
ztizcDd_FYqN6Pz*wn8&`ugyKsOx_oBFV?_J-j6a1>q#c>v)BX8<oyzlVx7k1JrMJ-
zj$-m2g!7 at 9FYr0gyoVs~p;wDF43qc4tHXMO$$Q!Ppqae))?R2P?;TZ&Iho1(K&`|)
z$>cqq_CPb`eVH(iF?k=QI%p>Ele86@$$J#_Lo<0V95dz_ChuEw8e@~m`_3%FxM1?W
zF*~4{ywA%?XeRI7Qigucyacumn)h$1gRRZghk1wY-}6$w7owNnkId)CVI=Rd)XAS=
zb}JwE4LDCC{vpz?A^uUszi-zKfBqct9*{pr+z;~k$HK%TDH!6<udIMKLREkMoK=1V
z|0xmtYa{s2kKo at 5|Bhc^ev2nMD!wq&`8>w3<aZl?gLzTscjvvRr-cFT&X+J>1f0L|
z0FDQ^QO9x}7Rae8p51XY<i#JmdHe0R>9yBhqgP&eg?{$4pV8X2YpJrblCHYyDk?56
zrb{llgtD at -_>-%cgJOwZJ5Sr1mGCG2vDg2WaPOTzF8~qn|NIdD^FiU at KBoX8;Qvs6
z*{z0qPjRbB1ieE21H+wv;wg5Ye`5Rgr_RIi1pj9p?7y8681AF`8#t;n^%a#1 at qa=6
zLRsIy{^w4-Cu{a$1cp0hoWS9>8Hmy!-DXHL at PDES&%poO3E6*w{GTQSg*#I|1HnF;
zQ(RF|yl at WsCjYOfSQy~HQ2uY25uBbO9a%qROy9oEkdEZi_`j|F_U(oYgga%FwR|)q
zB)t at rjAK7jKCOHz{-(jFqH?~R-Wg4QSRR at lvYyVdBW3Z&qXm2v)hKkv`Ecn~6wepw
z)z;5f(lg-y!ZUCwdd8VKL&}$Cvl_-5l=5Y4-!7NW%BiN`4Sz*LQn>WwIuxna3Y}7{
z`t$$d(DaO?v>cZbZHD#~I?bT^^Z&Gv at _oczLFpq4xsSkvUQn<4<A3G6kor`*-Z`~T
zp5uNg^b_0FzRLeY(nE(oi=M6xId-YWQ2udC2B)Wu2*LC6fKW^w7i_1D6GFl%Jzu3L
zV?a4Ickp;Wp~j@}lv1Yw^{TkJ?7`ubo_}8938kk7wxi-!r<Z{A<eq>2oJ{%uDYdsM
zeaPQ8!=)!;^`|#Y{qOIaA?c;dZM2O?fSQ&_iBrwkruEH`^it$Lfx*5|O;3yhIlXCf
ziX)^){<%e at r;fT)Vh)Iup4{gb%qhMhOnNEBTHhQ}J}wO>IU!8>l-VF$dehH-C~9v;
znEFgvc;<rX$?e8!`}UyrOMmp#1<EJJdVPf<rE-3l{t_lVdBiLIFr77xHw^8cL&GT}
zUg`4-q2UNK9!?AiCoVS1SZBTcso-&cP8$nB;j~L!;KeRfpBNhMGrs;~!b#-+-eWoS
z)+#H(o26Yc8^}gJYL~x-Cx3lKnh8H6%!1XUS5`LikewC>FB?r?rFi;)(&(6;*O05p
zOszPJL(BtjLU<2Z;aU!t1Aj)4WAx#O;vO%b?Sik7R)FmYVWeiLHsq%rXL8Du;8%t7
z?KrX&dKP>;aLfpEiSwP%9D6&Caf}{0440r8J`U|%4rv!*Tjg{8<qyvHq at cn^#rB}Q
zxhU@%`dBXSD*r*O$&>h29`)Bs50Vt6)W`Yr&XAS14skq)IAZ0S0X|2$BM5Gv*w3|n
z61DbekZZz*8sYN0QR7?(O6>=?j76?Z<%m*m?Ko<aKS}I=b;hnTJ%u~8$0>>43#}8a
zykDa$k#A+-ttL}Ys?|uvBXY!Twjv}2+$~BEAdW1QV+oy;(^&JF>s`s`_vCyIM$G4Z
zR2h)Z=@IMWlk<!wDzB7=Q3=x1$$9Fesd5cl<-V!(Jno^B<iBuz;PV`#r_gWJK5(IN
z)C6~noKOGgh}185Oio8?>bT`mZjnc!8XMQqGMsJ05p_g1BUV1EMUI=*3i+5n9?u2)
zqF1g5Wu&*jRUpUdFHt4VW)(VPe7cz+^5~a)5$f`LsLLe!i=Mx`?3H_f1N<`D#e+Co
z<T88lH<|cbbEXjA;?Q0q#>XkN>2c9Mk^5a}8UelTg5$tc5!$!(pJU(pAVS|#>s0CY
zd{t<bdsw^Net|Q~g=ggDk=o=_j(ug`&X?!y;{jv8%;NRh+L|0Ij2&$br}vt%?H=dV
z-sV<Yo5fq$rtTwB*z9V%+Tv}Sw5)invCZPNFSdEr%|xylTRf>~?6t$=jm9#cr`;>>
z74<1&o2-OGNUyEAowqm?Zuod?Uuj1wHs1YkncZP)v3a$Ffrph1+mMku+cKNO=-~g?
zjJ0^DJD0hZ+B{>8?e>ah-YDprv5PGZuWjtLWtT+=>`(l%$f=iI7L?br%d|qnU3QsT
UpVyiyOcmAD(`QYaKVOLd2Rp@=@&Et;

diff --git a/distutils2/command/wininst-10.0.exe b/distutils2/command/wininst-10.0.exe
new file mode 100644
index 0000000000000000000000000000000000000000..8ac6e19b8eeaf7642387123c749f416251c496ea
GIT binary patch
literal 190464
zc%1CLeSB2K)i{3lCCL&Nc98 at kM2HevaM4B=G+~1-A-hB+;l?GqL`VXPbh|~R;a;GX
zK;q5X+>G1Or_u-eXp2?*<7w$r`cxpk6m|*C2BgZ{gD6xZruD9yVw4ybh}`cvGj}%$
zDo>y9_w#%C<F}vB&b at c$%*>fHXU?2+X71eb2R3sCj^m8*S5=N{<Jiy1{r5iw{-Y<q
zI+}ZV#9wY~(=GVRjf?!>S(CTA{;_Y at FMlNOq2-T0`k0XS;KO<K;-h)rc{Hzdp(pQ=
z$5uRi>!?wg`C1tt{7`Ip>F*OyC;xYBmrnl*u7@`7Jl#aE!P9?)>yBS+J^gEXZ8`lL
z3OnJnk*5FQw2fYyPQOU6PtxoC-+9Q7<t1_DT^zSSXXMguX(~^~b#VsWNL?n!<>)!?
zFpHb at Dg;*e7w8!k at E&f{I2}z-UOC=CiMF%DfXPi15Mfi-)P??fJM`Q(yeTkny<@+g
zrd_w|x!h~eeEVMg at V)^&x9Ptg{#N1P^#WW!8LwvuVOx#EVe&X`*{$^}mJ7>)3@>SI
z|2155hZhX>I&WoQTs~5<3(~KH>;5mng>S82Q~wa$)3!pJxh%Mz_;PvIXzKs}`+wjU
z3=3mgP0a^|k&PF>B^o-orB3ma_A1ijC89alZ)t7>AP=cA`SuOmUcxor#R-oEmU at -G
zZ*v^!t*#FC3w553bWY7)bXy50yUbET6~7VSJZko0hzN$oF-0z`VD|U|X=;^KI$(~Q
zJOLftR#*4C%vN!te-G54W-kS3slmz#nS-Dm=}X<>Q*}%1VP|a(A|>^hJzgJ~QwYHJ
z{?{O5xJWdK8Bv!Bho#q#*s7w*>-DIjS$$h}4FEot;16jP#aKncAWl%lJXN#;gfdoD
zRj3Hi+!MPDKvIGiM(_-q__vD0JWF#oEz%s&t5tc>-mq{ht0tfyUW+)Dg70GBey6>J
zi*3{LX3)H`XW$WlgiMSx(72GRk5|Q9Rm at Sdolq%h7{Dl=_o>;X at LVKji6h{?3=vxD
zRmCiC!03gD1rPz0z<6>>eOtP$iWV%p5G$VsmB+u~^?Cz(=m;KQJhIEAzD-;vM~65b
z;jsDsEPz8|=K&4u;kw!-2N{(Mp(jk(>t3HFxCI+q7;<$6I9{0%fPQzGWmhM0WjSTn
zVdBaO6#AdGW9Oejpik}nyj*j_t^Cyupbfdwfm|S(Ij9OZ^ZpHp*hB;~^2)!Laa?t^
zqeB=AiKBSGAF(k)TL77UfZ>%pmjDFhp1}b4p#bsm_WmN#iv5 at aZSg2Ku7v(OV0J@`
zXF`kXNQc&*rXDA7$McOJ0Mq;#It!>k%5&tPaz$046+Y5nl|y~-5L!_9v2CuIR9bEO
zC1so(?1V_e{-z at SzO;1tPp9BX4xNBdFxtcManeh at aL?I~dAutfm6;oIkWZJ8@&Wr_
z>XbGh)WLQVJb>lqW{@>E8!i}jVS!B!{yv>v-qj8Fmf%}Bd)&p}XE0iV?Qn0|=b0ph
zZw;9<<WLtv?7J_|a0p^^4M!~d+_{E%Hye&x_Ek(UbP|T&TcJ|jBvNjcgJG;Im_RhQ
zV7<0T>zI}-)7<7`Vn2%y at w!%%v-zNS(Y8Mn!kBv+i*-xo&|z%VO`$(w)WX*Jy7|pv
zF|qeqAo$9c2t}39_OoJOgv`Lf^imHJAk>^j>kJ-2FiO_=d}1OIs7>B-1|D0jPQc-!
zEqI1z-h~aTRQ~G=9Y+Tr%VTNA5vT^SOcKH{WbBj*Iq_v^_XI7MR=<+(r=86nl{+pc
zQwAGIXq#;Nv3-J9-Gv=&*)z|~Lok|G*W|Da>Mq2Z4{*w}mr)iVvrf~X_f?nxPF<5#
zsqPBXYTp|`n4DnP(mW1$O8OJRaY8-`A}cs~5<EdOIx~4za3EdXf-uqn>tLEnp^Io}
zdFs>`sv3)Yk!tkJPLdv4pK3;h(H142wvL%gDflMqB64(L>q6+HgJOalip2EiUm}O3
z4-DsDB$R0kopR_5B_n0BefLbTb!zlkt<yS#Y at zh&Xf^7KmkJY#za@<Oy6&f4m<~|J
z;%|w1_dS)YEHAG-2V-t1d&K+@*u$~Ufle^;YGU7kVL)$w$Zje at d|xD=#h24br%qD!
zYaeL5xKv!=Y&A7rEZA^Q<3;<%$&D8u70itn>&4m5j`UIP`0dV>(ezQ7QioppL?53T
zFontoDtTr8Ba{h>GsQFnTiB9LTm$a7v1PQ|xe#RfztzFaR7+*R^DX^28wnY_ at +-(y
z4U>dY_<P{Lsrfnc;Q0kiuW8r7#I&}&StT5u2LmQ0_6VI-NUxFxS*qpq=br+wYT0d+
zXW<>2oGL3pu)y>LB(|T1-kbe~c+q3)AhV{S{DmI%K^Y#8dQx^J3}IgRDdGX*$k8sM
zIGLo12|ft|D2!Ca0i}Nxz{Ed*X4R#HnR%EnljbykRsvHWOxNOU|I>iAnw`gH-U<E<
z_&Dpp#CZ^@WXuC;3w_f9qs+eoQeYJ41LO->fG-q8Hs$v%g9M*f&F%(pIyi;JS`}jU
zSCki at ZSQBJMV<Nivt1>evh6k?5en at Bw{#`5{wz!NFQ8eAbCOxvj6;QGtwJ8A!gA*4
zTcLyi=ha4e0AR6dDC{~d3TD2Y6KKWlTET at WoZ>H0`k?kYNFT4g9|XMFEAQ%pAqG;H
zhNoz#(6E<=JrJtdPlJx*=xCV0`#bL#-c-Oh_B)__D2RFaP_Ua_6n5!imow~gf?bZ_
z#s4~#<VzAXANnN&I$;kjs+R(6UjvQSdHpTVVCQXSD2(L&TOng?y^1mw0f{NJ1+l!}
zU)F-1H-<s2MyUH!P#|_FEU#Ab41h;~+lBy~NCM<CfEfs2g_I&nBjLs*U{?}w1_QJr
z;72IBC>e!ss+5pP at a`mdDFg3?o{6<laAjDzN)j-i0Uk!cA7f`4DOviEECB#Sa(aOo
zaRiZI56u?Pg|;BT{g6Kg^1FEk=ifH#>K?PQJfLBu)9OqNfx%}rdn-^owu;VMJxQ!g
zNqP^0__OH1qO1ozTZc at 0@<C);rj>?V1ANGp;8Az;_aN(lVyJa_7IeA(U^@(F7~!he
z2hF*i4!#+9 at hf+vO0EW|SzH%B&wzna&BpucVf^gzl3DqX(dQ3CmQZjjVtUb^cPEr3
z|7kNkMT1X6h?G=MvUFZ)`!2}o8&EC)Reb7kn81R+!`XIL8J6POq0X8HHTrw+K+H~(
zS$PE%G(^h+R^E<-58!w|l-q~`O1SYW67|VMlxPb>f7(8DJ|RIwFFC6m(Iz+sWZOSD
zp>@K9Mm~cnt&<fE6B~d2MfErmzSjPiCCbv}Daz+kdQe?B;XidJj<l2hFkV3`KIz|%
zce1MwZnv`A0k~~pw+Xlv*ljP|u3)!4aLcn>MLlWnmtEbC_bkm at sO~;sX?}{{^jVrE
zdXo?~7Ky#W_lv|HK`0Ux;W2+H<OXaL)s8E|9DgB2s%pSrfHyBt30O4%v<;-cfXupA
zfev2+LQkzq at ai1^+6O!%by)8cKPIl;7mzcEtLFt|CgM_FQ0TS$1>_JQvH_INLB)O1
zFfDhGHW#VFZuKuMqz&5%ZCp^8BvK)ZY=hew?Dq9RB83M at cVLiSFAvgd2NDS>^pFne
z(Pn9WfZn`rX|AL<pevQpn*)~SyXnmiOY<FY<LIz7-%2B1wlq)Gp<&U9abuCi3OP%2
zCftCM@#bG~MuGa#%DPb%JN-sLQ)zk>X8*90SI(}YYCyoSICd82wq8KY-(x`TZkvG8
zpyhVjAyMTZ$_aFTc=xuzyy8`AYN$CwC%TQ_APqaod$#wHRvEy<BY0(MLRG8ddV5$l
zI;5ykE$<Y&y*Re3+U)(+)kUItV-7LyYWXawT)1E+t9Cm?^9ChgSQ2s_2J7yCa?a1u
zIZ?EchOW^3G$r^L)Y}L1EF^w2rm4XjM|oF9jRl#&AFo$K&s2pm`6qeMdeR=x4CrGM
zRn)GWp at +BCX@-Wv*QUloj>l_1ZSVKEJ+jy*PgY(q=%H2*TC0s<2zvc!FZ0OO*=RtM
zS<7IM2R^4`BG5+%0SGBFYpE99L!SdMcwXsBpT{YWf`Uvs<?@8%4Pi1fpizyIzMwWV
z2sa#P*^41}JlnqtyXd`DS{L2 at T_k`i_69!3LVK`KGHWM*dQdK&d<A_|j>wu!_DFi;
zdh%(=t>cwPR-l%Y;b<48c|4dZ*Cf>JEUHq0!1bzkVvg(_Y)}R%PqgIfXapL at st8TZ
z#S~XxYKWMJN(?$4ki%1hK^p-BgX02)$5Vw#i9vepVaF-KQREsB?kIBg3AYuw62c5e
zuQ1K;WMiAMS}hO at r~`u<1VJ^}uX<>BRUe7Q4N|8%sLgHVt};zQgS4Oac;uh}1t{<9
zhV@}Ur*&d*m5Tbxuzn1pu0XpoxSHOnyQub%?9iZpNbF#@{_916NjNTx1<XYP0(}Dj
z_<IVOiU@;;#qi1>`=})Y4T${>XOCSJ$Cp4xSNj;ktpC+rhyd;DU4E^yqUSK(()=TI
zC@~yh+5=#ckbqKY`;Y}f^KapmA3R8XOOErx18uJZ66B=(9F}K;DWk=#N5#4yc|j|K
z at d9l!?+dwS at W}+q6Exo2vb11^^7(nVQ(jn(Ds`rR2Quhch^kJ)Q<mAq2urz!wkS30
z{QUuKq&4-Jj6*xk9`^1<p;F{B33GTJ>}u%yN*LQF-p`Fe&yydT2_|TQnyCYqk(3e>
zS}an{UV)<~y at e)fAk4<L_4>fR#t4vvKlm<_bXI?E5%vm$o0UhkYE&nvOt6P*m7+mp
zjl+-y`^04hp=4&csWjx3E03TYG(q2%F^^YS8SAMs;n6a|S0+p<vjqQ+tl9}v7Mj0A
z^K&f&MB?i$dt6pBs~It9$cl7XL3Q`*j425WL*DH3>xV>8Us#gg{)Ct)ze2x(KTzOb
zJfv+yb)~ppt6dm_HJ1Vyul$X9eFC?lJFj*Xle5BIq&HyP=L86_c+US?NShdzPN^V(
zry|(Y&rqsQ7*^U0TH3#|(vXZ{Q1YC$O7CKgkd<J%+WR%%pTWyUVj~W5HVP>hquNtJ
z1(T04H}%1JQM3&8*r9xRTWT0!8FCTGNTn7}rPcuHMPHp+&LJI3>X-p5&EZU7s0vPL
z&JjSH6YuoWx;G%rd!NTd!e<7!P}%58!;$*~Mqt3~1(feZ(+fwaR@``d(pGKi$-3Gl
zmUMwxKeo-adTn#fXf{d8O`(~3`!RXEJT~bD>!E(D>vib2dfYqnI$_NH`<?~rDIb8*
zUmerq%)a09R07CDDol<;!YFdm<~7=m%Grpe&21#KDx2FxuE;vuMk7`G6{!{_J#~s8
zgW*b)X7tf?HG6eI31z*fsOafUd4qu0wiZz?Sw$g)N9|#r=hd}Fo`D7Q%DxzN?#R^2
z1&|s at _3_FV(1|3-95iP1jcCrXj!<bKOg`g&iE}S?%P?zG)-g|yY+z1Cn2h6D8XNCh
zk3={FYzsV>G!p*c9aL3e-dT;ByIqZEg<Rc$uYj_Z-mSkKZ9t#TM<3Dt|7)`2d-x&N
zeuLS9edXFIWUFEpn}i|zGBjg4P_n}KE`PleqE^rnQLW4N<85a3GZ!xUj{uH1z0e=<
z at av$l!yUlSEI<;90A7gG1<aytsOM!D!_(d_1F%;I^Gcy#!xklToS4BIummia>ur?t
z9L-;fLcJqYhMuO`#{oD3V3~nT3Z{xLrz(M3%L<SJuS3N<q5A+&khNh=wGpd;cKfa9
zHfk$?$wArloiERoWR6gPiveCanD_*ZpCb_Bie at x;0`7kKO(!SsI`auN`XK~7xlN$|
z$-yof*Nt)63(&-a(agy~g+}mDrX1|~1X&CVd at XA>+E=@JG1GH>3<ff-gpL~T^_w8o
zuN0yEIVg)kwA1_p5c<y)r6yD0G_YykCUdY`co_O))VKM76#|e044n7C;9W#VHi#OS
zQ*Xy{oV}Duc=T-JgjBUC#amfJ4aAVEhb|u=^eo!<AaDaZRBs5VBVY*h+K$*<i2!#$
zsp_*;^%x at eKV#c}G{J+NVRQ8v+SwB>JFptr{O8fCYcpbJeD>{OZm0%x1uht{S)-}J
zY=t3f3BHIdsmy^f at jQwk6wO&UH`GHaogh5G3D`Iv+!SMF3B`uW$FejuZYk-e%}$Yy
z%xYl-)X3yl3|PcTe;x=H{}<ZBGMHiLyao?-wecy$mDRM~REYZ6_<$a2U(G5mW>brE
zaNb;^=sYQ&YwEFHEh9alkO_*Z^k2{EaTv+L0lJ1 at _A8V>s3eh}Gcpx|2_y9OY}C<F
z23iWIYNj%%FIZHR#n8zxhsn3#Tr_)tvFUUQBRpsv1_*l5%)&`R0hH1 at dbUZNF#8SR
zy4DKa>@uA=8eODeJq*!qm{{1X=V-SC+ff)(zX8 at A3NA$&hbduCvKTYQJk4UH135{_
ziw*U#R9^G*X$=$W{pg8Q4lkzKT9nGgG#$n7z7T!ly;M!3ZuV>w%T>TC=Ru`Kp}q?V
z2!nyn2wvX*^Hik#BV5x1fuZF$qOmZXhUzX#X-dcx`I-*`cwKEW7PEnrrX9RQxv4Ta
zn|sk^6EFfdtN{C)IWB0+NN=!T96 at JemN(dMc{;3lk<mHh-HZ0AqeHlR4(1ZaC_7Y~
zQ^aq{)Oi#CCg^7~98jpyfwQ at Zi38<HfVyyMV)()-L&pmUsI6%>nDiSn+Gcj4|5+Rf
z14&OG8q(T~G!93c71T(jam8?UgxR@*Ez*HVI)}RT126(^*^hla2S=4K9kjM54XD~#
z_g=y4n=2g=OK=U`Mif-_(A18tfJZt!fm^Ltjn21UD*%D!q4c3e;7ZClB<xHaJ<18X
zAY%4Vx6oB-Z7eMS^2bkfgIV8(N&Xz2g~x+MFI*Sk%6R{iLjfA+V6B{REA(~(V*H9@
zsQ6@&Z1g9qq=Mm3SS}|zlldnl^Kbi#{PDE5RS*rGwUnl61yMEn29yl}gC;Aqq~n^f
zpbcvIa)Z!40dwkCXCiYD!@cN7^!h&;MEq^9zjw&fHU#(;y7qpB##yXW$6W&tP;anx
z&kV(dwBWdrM<Iv3f(4PIU^wNp<m#Qxr^Wutp_NmrrHW}CS_~NNpTYb>PE`j_3lDfS
z5P2wwAAN^@>NhL}3VM|F52E&Ll at fY!GV?5IZpE268n8XdF0gu(iHoQm#u`l1hU8E_
zq`YIYA8h>zwxQ+eQ78p)4eT6Sw+wwxms%5Re0|gfh*~<hf~C0<lfFi$afrJyaSeAP
z6MBOkLf6z7nc~hN^T<q4IJ}ex{8tRASqvG#7|_M_Flm4FB!iYDPBTAWFl3sUroUPh
zr at m+^Y@*Z^otRU?QDGxwvWRYopvq5H0oCV1A#}c1dICm}kbBFZEHAIV?PwQfNr^Nu
zH(>SnTjro&d5Ad$^U}Mh{rQDCRJ$0Gv=^se=x0QOEe!dW&A}o47lHccF=8o=sD+3Z
z(2mm9MU-Dwq}E83RYUHV!9DMvF{dP%AEydlnX)EXAlR{3j*?XkL=8jz{yfB(MXHOD
zv&vMuSmQSjCj5PI%85;v4H)}){T#(^l7QLrQp+=RvBu+1$4L!m61vd97B1AcK^{%;
z_?6<4<O;+vl4wwLPLTeD<>|!98lWEu?mtqT!iuNpTK%Xtr?9({#LgcsM&z1OO_vU2
zv2|;zTJLxA8bty+&%T$7(L+U-Ow??SsT6?bv&AJTx(!8Bi}Pui?L*9b{tbhu?ecL~
z_3SE&&H4IN&-!UZGeiIe>a0TJJkW*d%FV2op(%=IIkwKpIz#zE-Bkr at 5B_3W%)iwS
zwlbGlShSTLLtD9bMlp4e{102{)mk~MfhWM?vWG#1ai%;sGww+_Lx!8ZA-dUsS3bTE
zk!1IKhTQ-5K4e<+T~{&fqpPoG+B&c18lfwE=m>rYtyyNr{H`ojeV*=WrP)hFlTW5*
zs-^iax<TE!S!55W$XbFYaks%7x>jvzejX>=IZh*ecp6h)!VMIhhunaY%HMkznj<(_
zM}xRF-+dSQzwP1H7Ai}hqT4l48lJm)#s3sQzVuQX7Cmf<=Ido9Yc+~V>@p^sE2*sa
zhwnlLD6L{+K at VmZF6b_xdVB%x%#$)Dw6<p@$ToO%(bXho+3Wcb-D06kjA<LSgz>z8
zGZd^m;njT0A1<Oko8(@MvD&&YT>zkTRge3fNs1(67?AR_a at -5BiyHVRm3M)emc-pu
z7qY94s4x~-E2Rv1nUF7{y&ztv9C;syeh<}&=nUcWv9$#z?a?(bb(ra4)TVLouvuZy
zR}gfwNn!XZzQG=D_vhU`xLm)P?PO5YE^7KM9^@xY?V(PkxqiF{Em>3QQ at W39JJad|
z+~A5`Ql*co;`ZSxv(oEIG4F6!b%?r?`6#_SO%0g!Y~YTA%+jCGkD9j5ESid_3wDj3
zHWW(y#bAle!%C#86RHDD{0nze-6T7g&a8QxW+WZcg?A5a5a at 3Occ)y`fuW92#h$DR
zw|tpEV<udyb at mu>Lh~^&nRwmoN;H|mdMTm at O#)1&ns#b3X+E-LSFODIwDoDKCD>K4
zkDo^O1$$<)$p11Tr at Zt?avj^hlSbTu4%Sot7w<+r>9+e*rR?1bF<y@{X)wyafdZND
zPc4N*`jtv5b3Mw)2VfYL)`IBU21!0%`FRN)U-s}ynQk~p?M&E4rzX^Zd|q at cX|ht@
zwT&(kAI2$+cH3swZ41e)r_l5BsV0X{1}wnW)J=1eZLG|0W=@;Ng5-QiW>Kg4$)xDs
zKvP)ul=%JKyp#*ogBx6weP9g)mhiGGq3oCgbV=AxLq|F;Tbhx at yz>J!KINx#*alO_
zc}sH>#I{Uw2Qt0NhB<W4V7s7i$w3Q_&E>x2vbkn+=P;#)+FnB)$hUi`U1tR-C}JWg
zs=_#r|Mk1S44Sh4R578fhWVqqwr<I=MqFx5HR7Y<uW7`a#b0j39IvvcSZl=U|AR)D
zhd1KHf7giLmJMlyH!vI9aBFdD7w<T?Wp6sKY<i6DxD-G2vNaH9qiW!)<7#kz2>8~5
zlu6rT4J^S7Z#uMfPyNAmuQO1?E3c=Dur&WCI)^&aIrnRgpTdZJleAxZaK at 8fd|{pR
zaDtN_9^iZ-S1%vXdqWKaQCHs#X9*{Zy~??>$;l$y&q18x<+ZtDPX!`G8U})@Fro2o
zPRIt4({nf7pfiMUKBZwkPT$8#hwWq?TXlkYuO9^466OhLn}$BHbBnIB$n6KgoHuv^
znQ{=ljdG}mhJ7 at o9>)+m1(yipDl7eEB_&*CQWtl|Zo{d8tTy at rhJB?axN>pq{I7-4
z=*#vOz;kRmh$H_DxKme~l)w2w&FQa3hxsSCr9~VC21ynqdSiNk3rth&^Qk|*n<b}v
zV}9ye=^b=R;))xud`gvMGrCTGg+BK`4WuB3ZWkrJab1OFZ|R+&7gayPy8RQ)57*H=
z3$L8=w;$>_vIQHhQtxRs31R)R at h3&k;q!*cQhO$8k96tzO683;*cl8%ti6N#O8hEQ
z_yt$u`gcErQFNeKM2-2~g-+ZQyo**!{kh6VtEor~<ok^!IGfC+_RS1BkEC0I2Y^1&
zG#qO<`9*{19mZ*gxp#|bNtPd_Ar<vY2t|*CFp11;ArzXtNjddq;8d%|sgn%thBtsu
z{|<aQKEUnU0hKCmeTXX}UMNZ9TubxM=nO)s7NX8(5YdPqb5bj_JQQ_DyI3B$ZXcR?
zp<M_}m$5_(LmSn<SUEc1ZvO`*T at W`o2duo`IrmFOo-=mx%T><6DwWRrla)>ID%rSt
zgBZ$m7cMeuEXI8)XAaHzqg2juUS-E+np5zoL1gsUAHST7qq!C*a|ws8O7C%EdSR;6
z$zJ8~MOBRl*xCx at SS}?D!cvtw`QwYO%6^JwzgU^fZt^PkUjjJWRd5F=+|d-AS!Gl&
z!xpG?BoWHDMfBeC)D at iL*uueD6O)M0P!nrtd>liE;Yc=`c;&qhpdjf_7^{&$n8MZp
z)LmUP#Ekyc&LJ91R(#^H#Im7@)_~JL(^-<FXHvaUmR`V}Aa%8xU-RDLluotyOHOOA
zy<ZOQ0M&wSTLlH+W!$8DFm5DH<6IC83Fa-d?1|vYt(Pjhuf?fbgRR!S4WdPF9P%vh
z+KGN|y7?6)Ile3e(ht3xQkPi at KP1zQTk0KZa3|I2+o)YxGGs$R8?~Oc>|lGNfvD+f
z at MXHrwmp?Yy~DrkOL+nYW$FiX7dASsu=wG)L8hzs{*bjsz%uv<Tg at l59;TXH=SVG~
zSd;rg{^?C2+e=d0$hMXww~^WVizr#B5`M4aJz-vvI3V0rB=!kKxLa%{?iTx&qeHOS
z4;G0gx at W|)B_f;X#u1#sVXn5b1xeD2J4QO_juCCcNF~)5aFgzk9fs!A4nrW0sS7AF
zxLpxa|EY{R<*oO>GGm(wXF6lWmwnG*y5h?dCYka(Td}3yXTfvJry%nLTbU)e9d3A4
zw9-!UBUkyfB_G;NKFzt7<<)i!3<XgRoTdAnVh`&FJ=DY3k2J`k>qV>QU3<L<yLRb3
zZHpK@#8A?cwWg*kxJg!+)^r8!HB0c^P}i$(n9UYDhP%~fVT=b?QyGXn2U#wfhV~)V
ztWRp-0PtN}21ekj&TG^!+dg!`xv^~@#4QzaLXWFgZ@{PY1 at IxWv9F~C;gxTHq^cfe
zR~*C+72bt9Znz`$=O5ufrK2G6`~dBB(`!fuAm!x7LQa_AFP?|nu$YuOsm?+mW!Y&I
zWJ!ku-BvekD474fDNd;31a)wsSBP#$^(mpl)SZR<*ZoGwpfnyCS`hB~kmk%p&xLTe
zUnv<{;)#;s+xE2WNr at A<Jqh$ROMp}E$4Sb^HW_J!3T4uq0<FNdf2P3yYp_6_q8n1+
zl0j4a(j6)PtkkmsEWf}^`{|IY#ltH%&qDu_T+<tB==<$&0|mbgxxyY^u6bRt&cb;m
zXCG$*aTIkm7eZs at h88s&SE$LXX}G5BdMe~<2Iy^3*R!|X?Bt at Z&EKW00>Xo)G_*j}
zDqO#IJ^R8fPMXp;nDPiqnOw?J5`!s^vXsCqO!2 at Vjk;c+Nv$@4R at _PV4IBW4S$3Vl
zCHJT+oQD|Jbjvk8a?Poz>jZrZID19`F2gSwveuh^?^TAdI_ofuMlxqx0WO?dQ}g|6
zC_g;@!=)wMUbM=+>e~UnnkBx9-cTj+7xW_ at o|qc0RLS%B50p~qR|X4v6&H1t&J=ur
zrz^W2e;WhUVs-xQ^f~)kG<0a(3&>!Qu=Ps`$S8qKKU>pk8CDKYWr)Y$2(f+vf at BIc
z`u*q<^Y~W`%aZBu&A?cm#kS$ozOqufY at g25_q2(}q<7WeF)>eRJIB;qbb2T`^g(=F
z!BvLX%ebc~ZJ(27y(;4k$|km0wov(yYI~wvF|e39 at o?iDtdtXOhbq(d6_#GT;Yqk2
z1Xuw!$y$1qYDm4)$}iu8ZhHZDEhv^RP>QhO%(k~Yf0)VK44&yeNg14>?c5l$qS0x`
znG{&#H6)j3FS>BNDIbZ4&U5haA~Fn04X?8OU99c}tj!S>M<;jD%y7YU(BMZY#N^9s
zh{P-Cg(gQ7=V>PCgbbw?(2ds=&B0{x`sbhRNA+H}(W1`U){ib1FWu$kz_(T1ZfbBx
zg~?7KH<0encOgK*cQnI7H2L-=N^t|8Z{G>HD&tSld8Zmi0TTiqQe&l_S`ZOeoRLqg
zO at GI?<sGNQe3%O at yE#K|+ou at OTd%kE8m>4JmM7i?I at l7i<2Y56n}Y`}&2OQr_Of-&
zH-o2zk(S*$L+ at O}mHWicU!hq)g{+^FsQuW5Ps#q+FVOpYd1p3A%_llhy=s3AA0YKS
z;3B(BO>ul~TY|pg-D3=&S$0?I3|Ht?uU!q=)u>(5v}?L{&CsqU?K(ocW@^`w+SROG
zM`_p5+SP(r!xbrFg^7M0YF8chV|%eN7y3zbAKsA90OJd4xrtn|1n)t!@U*2l%uza6
zp7;rESVS at YzuE#RZcR2qpcoG89MVC%$9{}_imjpz`jlKEQBamgb^wR4m%l)J{LDu#
z+K*9a^3H|xmOUMo-|v^J2C&cYVbA-Kb5`IT!v&i-5PCMJ7XU-ex6{slr`}|H2SUB=
zombDQI?k~lZudJP5Ju{trrMG1OEgcW6}X91nQCG|mA+&*BxVi7w3WHon`@O)gNgHA
zIP!{$Dp_v-euFUHvio*>@03p?ipg%=g at 7f{HDWhF=6QSpBl)b(@&s;gfYKr#ry=g?
zh706K<YOy26^Was93@#>%I+!Qro3a%dakS--#w1RbMPL at ni8>R1<NX7mKX<__D2*e
zc^5N9h%u;TGO|qXVkRTYbkuI#LNg84l&S`E|9`C}sN`L(8kXrAHA#<{@>p$9=Ev6m
z4GN~3#2R?b+SKv^OYlB?->Sh>Uq-u7PrGn>gNe2`RXOX-Yhqx4K|4V9ixK3ax+Tau
z<LpPK9Hp$Y1wq}&I<X5!m_rN)z&qr~D;#he)YBXJyVY<KE at w@VbEYYu8cs%(9K#VT
z%y;3KFuA|oAWX3Awqql6>>U7x^;VT|^RUzpkRb!c(3*j|HsoH*6YW%rnj*0 at xqQHI
zfzsztBnJIHrIVOLWi_lfPT9 at Rl~pI{1NY0JNk{DFEm*XDG-Nu8{r(QZ9zkM2KFE~C
zGQFeG0W)>lvqCh}|6xt3YFMWK+iFVH!y0$ZnkZY++MvuBWy at rR|6OhW<GNBzNjU>K
zvz+#$9{LgZ61$Q%I)wpa^lPGloOx7?&=RE%BQg~-(_M_2qJzvtS at iE0j*<N^jy^+{
z?0^gMW2DPeXXuE0oKtJq4}#Sm4jvRn_eXSs-maJS8;{1s&ycHej|B{#-awx1$`WF}
z69$z628}AGL%sKj|454erXJ(fE4!SRe7Y%vbi{BEr2U{hJU2?0sPd$?e>ml*=)K{f
zQ%dA*_*7fG3eoL^O0!BmplneI6O?)twVvTnwQ%3>GV7`Z3wblNg~rXoIk@*|gITy`
zcmcN!2c~hRB(V5vn78pv1o|$nI$d*#fYA;;h5O|v(&}r5N2U)(k}5MOszzKs!*rKP
zX}Ac9+FF1U7vIW^gtvM~&V8W;*I$;)Pmn{la<iAL&h?S?=7om0<njZdr)I0T3|xMM
zR7{i0&yb24a(S3k6v*WYshBC3pCT27z%`_zScdtoVuAgbT;5G8_!7Cii&QK+ewI`$
zzE`d~Y(G|V{4Csb!n7z|w5*wI+3nFuF0%<B%FVi}0jXVY***67S-gd4Qhs;}6kF9z
z%&l^HFRAK{#7vgm2ai88FumL?mnST{4?);`Oqfr~6a5jZcyE8iX$kJoqgqgcr9uwt
zy;G_N3`Yr|Wd6xDiU}SRUzrbssAYWY9w-3rqz^1|RUae?Hv at i-^2C}^^M>P>U`>Jw
zpfFukAC&h`x2==5tqa-~pG48_(P?N~_LP5?M7rx5NJEQ-KLe70s$A6raYg0kH8w;5
zDqxrbiclfOkA?W5aR{RkDFG#>+5k+`L*BBLA8;JCJc)zHc2urPII6;HM at f6b6H({~
zi>S~)bq^v|t^nb_Ny^XI4(aeQ;VAF3NSgs}dU+poz}(g`^VRZ1%XsngxW{p5O||Wi
zq5KR3wUsLXy=En}4uEZM%T>K`13b*Xr!{Lf<mel$1mW%iAZX?ALJ?PJdvAQo5CqnY
z{c`0e36il-x};ybC{*%Az+gXC4GLp<ud}sMCq2?<Xz}S<EA>(YZuG5Vq^O|`@_h({
zB%TkI9Qryasi9BbGJahbTsh%7fSM0?x|Z>4(_8P+&u_6fYEG=V)6sCm@<bXMMl+($
zoDC0yO>+a>tiYSB{z#r+il&bQn#D&!Y#GEx({JFYeG-WoZ0|%qFhC#K56&gP66WJ)
zL-*-qQ)r=1E(3l$VS7W0q{%Rn%a6e5GLfo*DOD!hTTKxiZa6H1fp4ypy at j&7SaTkL
zq_7`z91 at n2xw(%0LKQlq`CPd&ORhA at l{s$tdj(R<0qAQr)KZWJW$eU`m#s2ylzDU1
znZ-52BcCVp(`0^z%ooUfq0AS{Wvk>eUM^c;57*YT2d*rpf`;vc1?7DiS(6*=7ph5v
zIjDZ$Bt2~6F1#Nf0}6Y>=mf(_QVSXk(npq{Dr8EkX+wdeS~l5;dnO(;P_!{$7{#k=
zrm3EMY2{2 at EOePXvfCtY%vYwP$cr1G#-!W_-P>b7?e#g at g>{XEw~6&qLsp@<3M at s(
zdC?fS5`Rdp%_*wQ6EmakytAT{lWV6H)#i&CQFs35 at aR7b4G!qkwbN8 at 9!byzWXLxV
zw}FV2H|Bcfx|zykDrsdGE}WQs6gD58YjdG?z~)j48}>Q~zK>y2>Qw4j*RV8sp>gww
z6HhlOrq<~9&C;?$PFhxsFA>j>E?PI`6TUb!GgG>fx9)nMU7dgYBXUSyUA%BggZ21F
zy7h(ja2;(s&^+o~unn2Vxo8A>ot*r(NAPJe^dXm22G`|E8)t%UDc(pb^1+xs-WAaC
z>bhyF4^JDCk=$aslOB;|4;Q(oiDM8BC57xRkliz6?=)MTmAI!lPSxj-g=XH?S*fm_
zsmz|lw)?Cs;No*_0E#DQtTo6r17yBg6$fnXJoKf(UBD}rNw_RA0MNEm!VQq at fkZ5$
z{{~uyTw4I;LtXKS#5+yrE-3OAh(;_K<{pqCX@*X at Vg_(o()2P(Ju^J^W6<CGEzN(m
zLg}k>9iLg6kHKvbZ?-fa#2c$PqKG$Ig0I7abk|5RJ(_ODK?Z}UkkrBy)<a;hIE`|{
z0NDt0S+DF$$gUGGnaNdWVvj>EH9uJMh?6636A<ZUmOb_$7T1vAEX}{hnnADHJqCmh
zdF%LD!@DXpGYYJ2tv|C}FU)SbJehEuc)MNo`Fu)s0;W}WPCy at WDf~*gMp4)1D5VLy
zhywBU)6sPFSI5xzM%;PQN-H{fj8a*F+V3{$*c(@t-R+<>kvCv|Fhl~AsZ at hmUm)%I
zmSU5DuO)#@2|rfC#s1TR<>W`=M)C&C8`396DS|DTB_k);Rp13cOLk`|&!593853xH
z7miCG>ZLbE06y~E0_>bg_S3OPp(ID=+C!}H9awmkg}$l?k5A*H+mfWpW|{z0;TToA
z45x-rMXt3rUN%{RRk#bko$CUVSVMU|7Nd@)O^0S@(k4nDfaJU2w&D`8a6?OtLWu`>
z at +~znBwyMEx<o_CXIG=?c(h%7GQ%YO>oLizKf|gq$cv51@^3*Oh^fUD!>hH$^)c3G
zr1j-MeQ~UBOaJit3`6Ss+30JvoYgmuywUUl+EQ|viB#m#8s)j>Yc=tvtExorFv8Of
zi9s$&Fr&203iC+Xkksa0O!b21mjKPiaRi2^s}CnGOY>p+T3{Z!!*HJrnQN6 at r_e3h
zN}saGJvp}hFn=13IF7DeVe5=P#M=0uqyC#V%C$~L)~su_sp9jYZHl?*l3-sYC;%Wj
z44swA>FcRzNS2X>2X=@9n00I_D{=KrcO`VLf$46iw9yIF$O7!7l};c-x<&>QWPY5X
ze!+|e07c%Yn=6CHP?0CQy1?R?NGfyXs#C#Z!Wf{IqcU&J2*9MpI7W42V?cZB19h<e
zKoXnrgV+T7=$Iz1F8aPIsDue!`2g+(Xo2eDBU62ot09)5A!Z#!toB-n<qt({+CPt2
z&-t%I?30nh5X%RoOd3*H#@r-3M at L?(t1WxnIgV4w!Mg$nZwX|;?qo%05w8_gn8>9O
zQ;ve#fUHqgK;H;e`14fU0D9Pwa|>e2GLq8c{;#hT$Lt&AcpG(XbVklv4Ts3_$j7G0
z2c{|e4G}88at!TEa<QS3iKEj1DbhwW6#i-^PI8FB&R7xyCgqqq2IgX#rTMK)dY5i#
z{xjZfG;)HSyd`~*aXfCj7)_smBDy9siSYB8UyHB-5N?;cbh6ucG>&%$Ndfwn33+8g
zcA0n=BOU)(QvCyEF&)na1qHN2$-{X8u!yGP(VgO$NL(*{Vu;-i)kV{R%{eXNI86O1
z?2=t){(7Vs727Wyor<1wu$LT>WG5D2CpL^=orrbIZf7)oG)_9rua3ZaEmYco_ST1@
z;x}nnOQOitM+FOU^(JqbjCpbdzMD=NQtVMij6>+;h;{YqTs=T|7`id*h$JylkNFzB
zM>AqhPNQ0`ds!r&MxUK<BfD4Ny+sNeVX~7x8QrvT*(3_Kblr8*#uby+fu7<A{Kp`5
zD_LvJ*xDbPl2yNBx at JFC_$_<P<#~^ma9C5uO1ZRRwd(dq;s)ph;`Te-OY8qDo(*@F
zJw_M8*$=Li7q}5f+UOr!|F_VSs9T3BR>{B+3qn8Zg~4`z$i0ZKjB+Rx0%Jq&)p!8j
zZ%5JfOWAb>Mv>Mvy-;B6ERGV|4m|BO_M9$>`wd@*JDB5C<pV3dY)U&ZHsOwOv at 1cp
zINn+p!AI*#&^p)LmrRM@#L7IFag}mo*?l;v-#9MTzYCAhSY*1Dr2K5MsWE)%X{FR~
z)++ieyALG!al_SxB})pG>9H`<X-m-3kgZN4!|f?`KMF{)Q4=;$X4l7Xw!_lLSazQf
zA4rxyDdTIJA1X085>Wb~<MF^3wBKk^hWMQ<<KNQ1He*IA<3-H4NeYjQ#51IayEwFH
zFB0zxU<reFnW58hXx$xXvcNM~wp}abMU*qj#B;>G!r)$31T68y8az~CGV99|*q7td
zlj;*bvhgq7b%UkZkd95<i>FO-qSpI6Fh at 6X&)4#hx^`KVLo0wXkxp4T^2<!L8H;(2
z6+oZ>K2^YCEMP^HOQ+*|S*R2X(JME8MIr045VSA`g_EWE*))_6SyY53((Av|)X<CP
z57aNCXMBP|)J;v-UbIfj2V``mfC0<PpoMQNR%-qMqVBGd2wPhSsyG;XWoD+Hqc^~W
zIy&TXB`m?efm$Q|h}x>LcZ{gQERueWkAU_9%{z0P7&pfYSPvW0uIgdT5H-<${_2qd
z!{R`5m~D~R-fIcs+89W*$RmA_TGa=$v1NCs;gIG_IR!ilx*}A1{A0rrzyaz;u=re7
zzhq3-53wI;I9PU<cWD?H4gn50P!9nX#}&(-^0P3LRV)~Skl_%Z^asfE0S-2qHa?lA
zqfZ!5N3vYuYz~Vfqv_Y9e0T+P)9rb}bsD|c6c>8|W1Y#~MBhWK)qrM27zC*7E{mpT
zQ)-q$m*4G3tjT8$dDU>$2u3R6Aa-mlt3LzOAf3n0+7dtro!5Chu6vTA2~)+BofDBa
z#!-E9F>&)>(MvUkFZI&mt9pt5axeYQdxyWOcmAgT-|8LyYkNocHN7)PaC8C1uE%;i
zf#lF<NcD<RO8D_#Mfkb;f1dEANy10dbLd#?g#tL*$Zngfmv~FT1}L>1ad>B}&C%R@
zNyN}e6~lMINd;KrGePSgVQ^2g9kuO`8*QjwRXFAHQxI(-M?rgZ^?-TcbppX1RlRG`
ziwESMUe#+mWOMZZAA&UjikIsYjQ&=mNp<zy+oBUcDe^ik!5g8Hcn(AEA?jM}X>~gR
zL at n=a(J?U+8$kRwngHbAhgeuMb=TBuSS!m-y17|8cdqQ}22xIErzvzx8?77<im{NP
z998hGV`azt!?jR^Ah<23o3x8JvK6!lXqcdA?x%|8l%v%0HtdhYatslNJ4Y}x+ARZ_
z7 at yBn&WRf0f{5h_kHse<>O#ZUqTS`F%@s<u;h35WNV=4mWO?!jpQtMHa~*7lc7Uab
z7|yjqX|fK at y17OsL<9QxI}Cwbx&i47dJ^IpaDy*_Ffsg9GFaL;jbkN<R_U$@4c`PJ
z0#O`utwJu|Hkgz@((Nw7sA&2mR8t0GbOUFDiMUSK<{L>(x2?{qn{U$9W$9{jvFWnw
zgfJs`TA0RMJwqt(`-oEh_V=i5BF`^?GSEC3EnOTbj)=NU_<jp$a1Wa}>Ec*ngmiJV
zV6-2Mr at ewZ`H0te;oXVHq_a-LQA3r<;4PMYGlF5!2z8~ybYv7qNeyQ>Jck^Qe}Pt?
ziS37p_qiobu6wDId$h*My$An-S|?Wl|EfACcMks2GADP_awk^<|0m)9bNJu&pp$zE
z{=bEP-a}4qFZ}=OVJFuPM%+R8Z}vO6zrlY*0Lp>?XYkMdu9JHc{tH(*xyA7R4gA>=
z?xtYB0HX at se$z=sK3H})5hpr2O+5M$k5*T!Yjc at LQCgWx&xcL=_)@E1_OK%XM%B7p
zN3Sr7)R>FhCSjCxSEev3=?H}faS~cL$IjrJZdMPkbe^H!CFE6O;EVX%WWH7TFi!h3
zGufZ<2yss%4OT~D?Ks;h-tfK$eRB_>3BkN_pxVsz+1 at gAdMcH95G`+<fhLn1&z(TG
z<rB;)2W3uVuFb4|r%5l2#>247@}%Vj94<*E9mHg`JzV56uf5yjlP((9+(D{Ltyxy-
zqJE;<^pOs?eC~d?DT*!<$NQpTZrsv*jPgK6!1#deC^_VGxXkr`u3I9HPWhXuEAU-Q
z^MByLc|6x~$<q7++!lF|BQ_PA)?@@O$9{^9oxHdxLzpjTkom==6OE>C7uq87{9-9#
zs-Hv_7Lwl9`GwLsQ%h;K350lwys%JSS1esIt at -HwkjoTW=a;_0 at pOR?`fQC6B2>Hb
z4S1YB&!{u#=9#3sjAWh({lq3p^2uaPmPc8u&_O8AGs$bRs-qbr8Rdriu!mAmDjX$_
zl-3t>Vj9eVHSI$wSXqgO)8Y04OS1*Xg=ltMur%Z94XMp_yl-i~$h<<1sHOQF5 at KUM
zOm?_=bkNUz1ce^VB2h5|hV&u2M>0|L_)HkJ_YL}qsY9GXCIE62^(`>Jcl;pmWMFhP
zE%N+JL>%yVm8ocm%v%upDXOWE?G?N__Sb(a^wZZT;@!Hbwsu=2lF)~msVWOvESbk&
z9mkV-t4KrQ>gZKLRme_a$E#~*`jnS5*g;`H+Kn^i)wzQ-Jvd0yY(~@3(MFu{kZGY`
z^eKL%Ft;-p8!<^2En*rebH=ZeF6M|MNee14Hh9+C50XZlT_asqL!_p?4L{YQEjvHO
zU9~TpRDs&uNL;xd+4ZtLjC-^#drtXCd*nlFz%;VGI at ECH{BP|C<t at 0^si at q#HjB6#
z!FDVQmAcNXRJpm1a%+7L(FZI`?5gbAF4sIgf2Fjc2IQORK6r4vzowTt+_wi$i<8Od
zsH at FMr^hx~C#4(7XnK)n$2_QAMP=6x$NOu+*xTU3BAoc#UJn-g_BCL!Zzpe)x4`Hs
zKVvv%J7Q@;Lu)QjVr at KlY-1)}*%x6re$O5b=vT_Fz11s8>8RIN8cIi<ks=TS57Na+
z^)b@$vi(?5m38ejXidn-uapWoVVq@;$+Blb`Rgm?tc7qN!dq2W;;6FLpF-zMj1%VG
zBjifuo7JeRW%Fv71YONX-~xtPry6 at 2G?-WLZK_wT5QhttEwA$0U31j68M`z-N^WRo
zJ8;L+m9*`|wL>a at N+owuWzc>a8ljVGo(<ir%5*VauGuM9ZI!EDltXy#plE8kv<N7*
zW;C7zBU+m- at la#E3HQB^r8?Nla{0E_&YR13wv at j@%C}kej3I{{<(nHaJ6vttO1bLQ
z_%}9Apa~;LRkPt>Yu1>Ssy0&9vXYp`#M1$48TtguU$q|td$)WiRZ+LfSndu|zVmq8
zQ1f!g{LAT8FOzp8AL?yyNDVJ at q^3>2UX0t1h00W#;n}$U=*PjM;-%m*VMOQwb;>)2
zcY!reORjDDSJ0)iQn$c$1{x~nI$Td%n%}4IgaA^|0_3l`to5X7yJNrQ$r*S{+dt(E
zz{FAhl%+Wbm#i9ga-u=5+DXcHgo=NRhgI#gAG39q7$V2dLb+?E1OFhWqLR1OvM0xO
z92g}_3hU>pt{t*#D^TBX3;^r9 at D=7GxDfs#kh{ob5=S*Pyoi*xNUu>P6{w9-NN$U?
zoud0P8AocKZ81MVMz>aNZ&}o&BcsXNwxf|tdfD|9nAlBvLYoo$E}n^xodV=_LdP%)
z$M3 at i2-hc@2JJ#!ZM*dFPLABw;)4F$Nx&!|<!!S0Uz5b8ls&Fd_TCg_VR-$4xLyR7
zigf99>FhX4*~E6K)7Mu#CfuvhhF{-k4^%DIqzXX4vh{nwrkzBmNgA`|_bw~1<XJc_
zxsSuFJTsa;9ag8}j&F79G#cWkPt>W4X}E}n^iaa73us7R_nlfwLnjT3X;?_ZnKYb1
z!)Y|kr(qrqb7`1E!z>!^q%|&P_0n(|4Oh_6Ps3F-TunoPhU;laUp1aeUqznUOv4r$
zK1IXLG<=$dTWLslflu8=!xw2tUy+?UjfVL&qz460ZKh!(4L8tmJq-mKuBPEC8v1Ft
zf`-dzxRi#AX}E}nJPjAnu#ASKG<4Fin1+QkoJqq122U|8qhToxoir?_VId7?(vYWN
z9u4WczEe#!%%Nc}4LKTS(a=gmGfSm)ZKdI68sY)?hll(^CF+v)(2MkQU7;2EpgXjd
z=9 at g^6j~&U@=X`^<3f~>-I^)w*Uf%Ic&quKP{|_2_(*Nu at s2!2GWV%hu52U`a>4$F
zq1SLx`c##ARr_1^4r#x!=>txuYZ7y(;zc-)7ahn&JaDv8JWz{Y0BR>C1GC$OJDS77
zC$m2kzS-O at d;}&oL}f$N8Hh at Us1xy@)z&ebORhjZxO~Ab19&-n7+Bwj-%23mR<tA{
z<fx&;ab>LuH*9aiE!P*(5~$CW=Je#^zWT8~uk?{c`n$ye#ffRLk#jljLX<WyD-zR7
zXAROtQ~mVwFRA%kmi at p9^Bp=YI4NeVH%naxL#LV_6u$4|)cnwDNZt(BK6u>R48czL
zpMd|Aqpj&J8Le(z%Y0p{TMxyy%-2gD2Hf-kg&$589=c}`mO|<9xVNYtp?;l$+RR|2
z4up}SI!tXDT80lUrSLC?|4jJLfPX&xbK#$bZ7BUww_N(;Zn!FNRp8nK*B-d`!nGH!
zeQ at oAYXYtbxDLQ|AY=?7n?Ua-lGISK(d*&g4F9bd<1*FO9c<r>7!JK>t=D1z$6*u!
zawK6x!fgYg4MhW5ALI}A!Kg3Jzcc{#4m^(aUU&y6z2kA(-ejL#WPM`8KH(mxeS*N7
ztq{zF|5Et3x(!o~w#+w3=P30)q15}&Aw?r at 8q8o{okJ%vrSlNT%|qY-Xt2-Dq3a%?
zEl+qspbsy5CtTX#ABKM?{Exu at 6#Tp3fBtdWH at QITT)5`IH3zO)aLt0N6|Ppen&E1O
zs|l_qxEkSV9NssKM&=FB-|)|ef8mB9ed9I&)<gP&J`eAQp>f0d?(py*$Oto8kZ**k
z?K at 0%G>64;O_%5>8=V|wX|ayGI6S6ax at 4@s?ZP|K2L{1xI|@t;>>JaG{iGA*jRBVp
zPz5H3pwEGrLi+jNLcy5~?qh_53hLS+G-`-I-DV#yHse>u$cB8AmvN3q7}JWmKz0;q
zyz~jlcok)o;Rp(*{ZiEU?^GNqWc~nv-3a0(=ifo~<^(gkhE(w_V2}7H{34ABIusXV
zj6}%Ky3j$38$sRy6vd_Sn_9=gSOjBoPRn at K9$~r$^EU=lh}$F#!dMDOfdD!K8~%?L
z%aU5wsFv|?wJxcxYnK7Sh{beLd`Y^7F at fwF&S#*2H=Fx~n=kCA7+;51K>2{2DrKcS
z9`r$YXz}T_=VX#&6j~Ib{(O5(!DBd7c1$5%4X2+fOP)NdIGh|;)6M{Tve+9kD%f*!
zL!aC*;J6@;RW>XDvu9kbT%f at 4=SW9<ktdMvM>E^2yoaw>*WmH{pyQ8GDpQ~f0W?01
z%rlaaj_9WJ4PzZ|)mx-Q#)gTTOidTn$DBW1J4U%F39g-ztgM|6lawpLD_icR=Mz|h
z at 8hfQu0CGbnT+`hjTzvTH<B^0q49E`kvM_}Hw2(~wXx5 at tzAZ31JBqJc$VtKLteQ7
z_x>q=ov)o|@#7*_!qV)()9{oZ&SwQR&!ARN-!s!)J(%tKs$Q at 1TP=qrSdE8xy7TBp
z8(gCRtMx~z#A39?@Em!sQpk!EZUh7ju0AcxGoT5l%T=alNP at g;yEw7N6t|Fcd;+WQ
zT|ji=y8$jx?D5f~<>d5W`1>QJaIq9UAg4>mRW0q!`|zL=;x<B-0B1-9ipRbS(ci`_
zZX at I|YkAzp!A#F+nM}z{IW*JlG?R&C%8{Z9Jg`hTkh%ghbq0 at Zux&EZ{RHkDLnM&#
zOx*=lS7DaDIl2n4nPa7R8uPJDpKk!5HJ<=bs8pBnOdx}S5jR2x!<&vZMIHevKprVP
zS*^&D-R7v<N;fjT>cgM%pTMVwDIa>3)^d)X;wg;9PXW^R#PH4Z>I+Azr*zb6>{?lg
zoT6s0r=JH%fJz<U(zwRR&Hl!pZRMJd-dOSAl}cWD7Rr(?Wo#I|DPs<0yEHHi$q_If
zp;c+JPOdZ_WCh|TJMw9V+l&V(J*13%fRcxlt&&HRGQV5_hOuMR_J5SXU?iiK#Y?zg
z*=jLE3Hq?Rpi3NS{*NJX91=Q}Zc=`|koFD4_B&VW#Vo08wH_+b#WRTsN_HAC5n8q1
z$Tfc7%n2D}u1Q+9`ipiFNsh~0JOVsa-mNU6zDX;7*)c5W<$_?pn6I2E<G3h?%OuJ>
z#h`CB^kN~d9xMcUsEaQ4W`WRyP`}{_g!!8e;n^#syxY?{$rswFlU~^Y*>xMo<Kfko
z-R%JruT(BY)3qBv_-G|R>0}$ozzi&ry3p;B);f89Jlc5q7BO8a&(X)z8ZX;K14I&6
z77U1%g;;GuXK8lRn|#ZU=jiaAW%1_5%LT%Ss4I(ZvACl(qj<eAs(3Mt!rdhCDR4tK
zGh|8$tC$VoqLo4!ix-ROt#vw7m^xMau?u1r`2!**S0yaF->~d4SCFI9S)*XG?0rLu
z6~wP^`oI8{3I(D2e%W~OdWc<TkYagK<e;NGYt00}+f?KlsGlaLIm#1jZ-i$fe!)_l
zLR>iux0}Q~`aMen9-|KAiZ3Bm1D4-cWf_jjRRh at k*1galo3<OpiQ9GJ9H~n$jA&}W
z^@qlFBk)@xMdHBPZz#ne5Bgm>x+r%OYT7`q0X1%c7=3_SY}pbvbWq2Sm3C<%#tViE
zH3P%?5rjlMCkaz<RTtOckv5c7>|s9jS&yQ$?n^KSWcYUg%f at xQ@_YK3k1TEY1h^C=
z%m&K83`>;eU|xELxCWCf2XIza4lhVIte|^_7lf0}EszA&%~CGm3#=R1sc1P~WeR>@
zvR8X;R5|X#({9phQz#%fC*~;QR{<uIl;r`AqqB~ZU%;_#y-<wK$qyFYcw0$wGDGLC
zbh&HYV_x52Nq_k+EopqJq<6nX<@ag9NZRR#c&;i8-!d1!5ir*lrRD18al$B%GHDe%
zIp^Qw8OnozGR$>L=!Hb<YU5cR<qP~$iZb7YgVIc$wM$YG%VR$+*CdK=NPyBLn$Sb_
zR~@QN4JOBB!0$R&Y9w2VVAMeR>o`Ld)tJSqz#N})r>LDfHIa1M-rB2f;yA~f4NIL~
zURfxxZ*i`v at F{J0Fy(4pK<8Cnt!Eo$T?t3KrFkXR2Ec#*9*vE!qeXaq$`}DpwF9dv
zp`;7!aFr`-jE;`_Y^9+zh13rUVd}dH=U<^vkEJiIrw0JB!bj-Xr(1bt<@f0J9w at KF
zm@#L*?Si2p0hKJo=mrxWPVGtrfFlPU)xP#Hrl<yH<4&sKBx3jl=b{^S_Lp#$=2uYb
zV;|u21XQ2LBiG>PWfG3d!uNnI!dQ&PuZMcnlR%f6(1r|MK<`ube~)1{0Fi5a_${*J
zclm?@%r_T5&i8vf)2(WtIxwetrED&NDa2_ at _(I0He5y?7>2U~pE52H-d~Y7o;${?1
zlRyXY at CuA0)`YP|H3I^kI;|KG6#5RoIz*4_3Yh(k`${-vIrLs2Lz#%3hyn$Nph@}Q
z3${7DJL;lGX)7bBBdc3k2XO5Ge+f at n!a}xTA-N*mZtXII<N)NxDt|3W>RhMqpz7Hj
zkY|se)uDajXTuk%x2}H&@Pzw{`ZBcoT3LO5e;Dg~y^(gB-0(EaI>^4y+QW|XP&pp*
zqpX3#<Q%2CB*i1%I~e0Wi_Y=_(2-s{Pj_8P>J^X<^BDYe3Xc`Xk2@}JFgfO&nmCWE
z&r+ta^bv#U|AE{7(?Z5z7eL6at<p!6BOj#`&a$_(&?t53gf~?2X=Teg6dpAoMz<2K
zA5wHMF}BZ5mLiout0tTKUAn6MtYU+PwW~7=)$FH%yQZp}@cd_(uW+>ok7T<6&np at W
z?6W5+p`MwG2Oj?sPe;yph06ov(&%XiE9HuGQvS3&TCTu-i|}YdXJUmB{$}`R%C*zv
z+8J_fo?M$R*XGEzxmbotuFZ<!fmoi9Yb)>ZcqsA|qs>qsYCKb1TV;1vY%ZRf6<#U3
z)8P*#x-;Q#bV6VXxwi3x`JTFsouGa%E{5%Kr}w+I>4c0?`RL|O8?_sESV190H7|>!
zifY;r14JqQK*;qJA9B46+Ej~H!XZ4v$900o6g9h9i^X$y0#LH6i-+Jn49;NiE(Rwt
zIKe9$zmEbWS9a&g-u$AP9U=^ko#JTR#_7%>?tIyuo2+rikQx_%WsN2OOpWGbjXAP6
zx2WbttZ}<m<1||1jAV^34yp0)Uwl=Kcm(5rTjS5yYc)=jy)%dl^zAI9_b7bd1xYMV
zl54Fo8CTGOJAWo>Be)Ak)C1qceUfrbw>?Y+KO0LqO4i+}K{UqB2GO7C`~mWc!U$*N
z29r;@QO|h2f4<o%KIT*UT5+r=R6I%W3aFn)BA3!|iE?t}gLH#=3yvFL)UI<ST>sqs
zP2zL}y&gfcz#6}pCUs4Ybfp`NAqLn+0iF4cLYDHxT`7z<-HxNETP>>T7N_`>FE-%R
zjUOVyFKGLe0~>KSO}EdhY-*sCxmvjVW;KpBkVJTvSv8vvL$0hrbw#Nqbl$1?s<a2M
zO2b3$wWRsi$ade?XDdi1wY7ky-2QytE%P{UAgdO??%9SLU*hSGj)n}<@dBpc$F5h?
zFQC0(y#Wu<5GMtUUU?R#DZXI|X at LogYuoL|UcqwXY0qP{Y}QMWJam&@G<BD78$J$P
zsRf9wc(gOw58{n5 at kTCb(#@EGon&%!2u3{MNxluTmo!~WK!y!(*1@#Wt~?yVBZR{+
zNpeD(@?I+*l7n?A&HW(iS&Pw}r|om}*5A~0MftFVTQ`BcX`|g9u~sU0=1fzC8M(F^
z)a{NuJOz>+8ksbSq(oN3I4Nx9m4_asXM{DCF?axRf#I0Pvn+!-Xv-au`pI)>g*i>j
z%qU!OMK+BVH2o2po#lOYNZxWh;Z?er)i74eLy^3+>Pz55{8N>o1^Ff$u)D<&nRswy
zq&haiz;UVAjAX3Qko1G}<avDd(}4_oxH{C(E!T9N|7}qX7#hk?9VvF-{4F{F<08SA
zTt$=P4dHsnd4PFr5N4GI!?&RofM1#HTxXEWyO9TBR9HhGL87jn5;RamMHai1Up!8k
z4z!o^!UVOvdp+pzT`f6rGlF`Qe<M_{jZ&pSW7!-&<*Pxq{Vp0)s9g{G=aT-he?f<g
zhrBcB!6F;-t>VZ?OwV5Sh<~#+9o<u!PfoBkhlOtq_hT)WK14583Jf6bl;S$^A4$g&
z^Rx-$l7+B$Ks5i`$E*;6B|^6Tr0Xl?@cQL79bPk<`-MrG!^=GA at QUX&oyGM at xEl?3
z9KAE*H?5#ldl<_#+rx4Ot3&LEMrfy*Xjl*RXX5$+-4i1nR6qL<DWbdZj`WGH)n)zy
zo}#+K4Ep6$J&6v~9ZcHadANJmm*f~=7Z<Y2ilP)NEWd at Z!g`Hef(M1`!8XrUoP#iP
zG#JlS?4pXG4tGH>YrF!T4eY`rzdZVVjbDQOLN4+PjE}AkT(U-n0ZZ&Va*|^-T%njD
zhMiKZYR1^`@nW=fP7Gf-GNqFon9B94s-v?$lSHbY2DQ+b-+l|~G(j#NyQ=lo_AqUI
z9c|gl!c at y1nn7E3upP8g;qP9h=-YtRE7(eC(mg5mhqgK*&}0`hIg2)#efz2kzgl;2
zP-3OzwEs6Z%;l7|>^;b&NMaC4DbGMWUj>pZWc{rGaoaTup&+Bb4C0gCQlYU~%J=U~
zHFm9y<3>i~rTuQRBoulT?nylKHK9EAJ9H)bB|Px-mpf>`1;gJ at gA(G`vHe>kc|`$Y
z(`{PPN;8KBV-0ErTo|;1((kYd7L)?q^u at IMY(>2zRrA2jjDbc$)lOj)Edpj%9x}Fj
zm64aw>Hv-3OM88&L4hxJ#ZM4)r7gacnjGkdG=20PThMjU(J`KgS<u|^O6y>yKfD<=
z5Vnhuy3Ecp*UJSM1M5y&e&1ld;5OrSF5G9`&_~`EOa#<0R|0nsCMYMVmgaqQ53jlD
z1Ki{<e2bu~QkZ6G`8~#8cATo$lY|eq2;HINcB|_2jYi#F_|oV5x`u)HLPt%aej!vn
z(yRPSGqb)MaBC#FER3)pBkdQ&gzXY$_bN&gr1OgPkL(pwm_(P8w;a)RdeW&YAF#dS
zh}QF at p)WoiH&yP%Z_|F`NgP55IbC%P0Pgnz^1<*XL?8XO!PA!DT;_I*eU7I(R+#fh
z)YgvfCv)t>WQ?mX9*3^X!>;`PxAA1(BGD||SR`77T+raeEY#pSK+C&zR*JT^=}24U
z$KR%^QI=AM->Q}IotGgJpJ(T5Ue%q@@$nAK^TR}{L)msD6YiZeNnumX(AeuF#ne>z
z*S~_4&ft~h=jh=M8XM%`ad7BgRP3jf&pyVcDx~cMj$1IO03BgZuJZ6hAem<F!Nam2
zfLlX5ZbNMt$N=e6o(L^9>FfV1G!IPrH1_FFSwxw&f_fQU10CtJ)tNseu7n%E%a^0$
zy~@1h$)md#c at -0u*sB2wKg=BldHr&2Fo`#NmG>S*$YkC1FLb1HjSYQx*d6-AdYP*%
zfyaUH_*0gClj9D9pd6zP;rrZVgS(- at I@;iF*5J^(LckmdjgA|2ZGrMA)TiDdyZV$B
z*f24H?d>zP!?dNA4`90iUSv(rTt1}f4`S1$s2{MwMy)$C*r2jy$)?}$RYpC?nogna
z90Z!OEZOQ?fUB1$TMaW@!+^QEemiY=Z?fS%UuyV6-(U?NF|^_N$%db?tBNT`_qmdt
zw5J;eNDcJ#FLIT~mt#-=LU#2itFhkbke==dZJ<5vE|gupAl&I&(KWs5ngXR1v)PeS
zv$4Zmy+%f=sLFDQZ>zh}C!kD3z}@uK(NoH3`mhZbHlv{pIeO)bWf*}cuAnDJIY%G2
zCm-Kmh6iqCJd7XlKvw+MIxIyxkb{Sk{R2<=TY>&EPv|wg(hodfKZM-5a!oJ3GbZ-Z
z*UbjxVhM(<y1JXR+oA^i+Nbh|+7w6nl(oyy`Q3|^0-Ri|Qws(me^{I1NT0F*F$4;^
z`izuHn5F(XTI)PN5RuZVFK$V8%%Oa`#)R9ci%mmIy)9M$37^tm$6Aa#w+ktzLm)F!
z_5a4F9IhLz-_^s|gW~XWEra|T(wb2mG9Ri*9mf3~;0>Qbl2s+apQYf>GVp(^(dx1U
zXa6taz6Lys>S}m5yGa(Z$t;pUkN{CpsqrTog2V+(fDJ(jE(Ugq7|^Qex?)9`;inRk
zbapY5VTx__wY1fWX#H*Vt%7I;5`sw(s^O;^fnv1L-gU7?L9&pL`OZ0acC(4Jw$Jl@
z&zI-P?9BZ=_uO;OJ@?*o&!ObE4^IA+DcXgQd})936iR;8;N;Jkq8$v$r}ig5)`!Xa
zplRAnNWL$p)lwQ!NUMtzz&tlg>reg%NM2LLXdAo}sej306%DNU4J(LE@?@BnzY#}x
z>qmfOnWh%hjnvJ>x(&jm6H691$<xfLP_}ZEf9R$~-90tCbL)l`>1pbSV8gmZ`K)=>
zKh$JJm|dS)Kdf%l>^eswENH%2WbEUjsW=cn7xWe^u!;F{fmyvizMv7s`Ve(kd_mXG
zt#{O?)s2{2XDf6zFaIWdwe#8)6Xt3jbMT-zlIK*%L0;&|y7aMg<vv{s0hyYUe_#$L
zD8m*<7X<Ulgq^4oYWISme^!o^3mgBJe9b&Wr!2FDjSYBE6WEBGSj;K}R$B07h!D7+
zUNS|$%(6sRiFmQhl7yg$n_+kcDAbiFU<o6Iji^o+dKZsES2{otsVl^Yz7%2O^_X~p
zL!JL8Unm2YQ!6tuKAYl`gpDI(@mZm7 at jbcObg7=Kr-Zt=fnH4g4FcK+)r7Ey=1qQk
zdG{H0H!gGMEmZe~(B-_$N`=7x;09t+c}}Cas-#4`68`NaLJ-Y}h3>_y#hD287BjjX
z7dHNe4wu9WwGtigQc~Q*MqD)}ZzUm2s6)fUQ}HZP*!UxguR?i$y+3)=;_g1 at 0bv8`
z{S}7LV3V4J8HxzAPGKWj<_+D3;V8ZcbrX0*2)D}A;`FJHM$q8+1z7%;aaevbyl(Q}
z4ef)OTHWWj$_>NsYq;C8J1okP`-P2TsOK!y;M;`2rSy_41kl%Gi4edsQX(!W5wD=G
z+KU`>WftNPwbg6;cq5*sB}2MaZ1!8iS?Wr=+-DXxpjNTmH%{0nV=j~w{0X<QX*e=M
zcNqtQsORtXh*R(Y$Ho at W$`bG<-X%Lt;$rN)Z0tOq%%4EJCecJf5P=U*_M5`HiA+|H
z0TQXs<lR3xblPN)$Ld5Njddg0^;gEko{8Bg_Jl~i6q2X^DMaQmsgw_~l!MTi5Sp5l
z*)r~S1JEK?l!%2T;`kD&iQNLTI(q^HakULCk7R>vg-2*jFomh<zYed1-Uv3VR-x4#
z{pvn-cc=#iss3gs`^_OV2je$|E~Y*ulEDL3bTP2;W*xWg((?{Z550r^%ZV4Y_lbB(
z`*nc>p|z>MK-L;gQh$Lw6QFpXRriqj(Iv5QE1$?6VA36JFNI8aP1WTnQ!6r2%Uf}^
ztFA1s;yNY{pAB-{cI0~DG<Ewky!h?NW999y;z=!_g?iDRu=$y5r<<h2%}<e6>cgt5
z{mrGxCR3%QB)w88JyEHaI4X<a?Vs>whu?4D*9O0*;MZEInkr!)#kt7~VW+jy6Z6~<
zaux&w{Z%{@))yRBTy3~7iaxDCtelGWA*zS702=<-1LTs`V%onS037CKKkejx1ctPj
zP}GFfii=_1!$hQQAjG=8s96EU!{RJjK?$(ROtq>L=x(K>ex#aKH%w2OrKdo6by$}e
z%lnr6ClqS;>;aT=&p at O8ro)Oe?_j}j at iS!sQ{OL|KG`gug+->YvsFHGx3F<74X+Xe
z`^@D+;ID|iGevyILOxR>J|v$h73auj?i2z+g0Ev93qNlh=UgZ|%_}o%fOQA~4Y*ev
zSoMOMRA=L_$$<vG)ex#cir8Hujw}&Jmxx14q*q>@9=Zl{zWT!u`Uh-rF<ef(dVlCb
zWQLG3u|ymaR-)l0<n_as{RBEM8ULK2rjjVPB!<&{SrnQU4Na0;EJ{`9tII;~L0-$*
z)4PEn&_@%&6F7*J?!?=X5H#g-aXK^&rVTesJzwiyF%M{+np7{uwNBa=8VRM$3Jo*b
z2aOw7BBlW=-UrpZS`@k&^1pg#Xr{TpjdzD8A<J!)nNJ905L-(W0;gyoCkcT=#Mmyy
zz~Fk^^`EYnh(ZYzxf+Ws525GrSJ#BTriD(syxNum1Oo$YyD`wV<3NMCRS4GL3y{r2
z!p>x9rJG&x+<BUaCQHuKM3|Uf<oSj5n>hs#nm+&idCI6W{W~I%-U|N^v15Z-D)c9G
z&t#yYEPQn={MT{erQs2=@Snzo&jxx|_vz9x^#fgM2Z)$85_Pa(gE2y93cx+T?uG6!
z_Gi$*l`duF9o0%Zl!^$5<}BxLbZf}jBwfPZzAVOi- at MRdnp|-Lg(haGhZOPyXf#`O
z3Hy0}(w}`dDZ1VRM&+o>M0ZI4px()ZDu$@Q$7*O9;UcZE9%23O5M4<(G>L1bTq+g;
zV1QYW;M8Xg)Q-*DTU1cmyK)5Z`pKE%vidZ2fvs++?y{k6$gcV%wbWK;hR<U74qsDH
zkuI(&&TFWdc8QcwSnSrNQ+(4*EA4gHCus|8?AYljo~9QURP?T at g~!U#fP}it99Z47
zU}NU1rA)qa*}3q|XdcehRhL;%5s|Vn`Dpg&rPz4X(Fl*lydN7o0O1eVnoIlle?|?)
zOaFGQE}=_{_|<zkt==<ZIv0bYZx|FEubPMP7e?d#c3&ZGEsXV^@9Zd at wU3Vh_}5Ij
zAhrfKlI+Gwt#~}IVe(l1dWg+`0ecFGBbEJ*GUA=z at Vl_wpFB>=W@@Z3e;>MM^5M+I
z%3kC;16y#{%;RONeow;qc at C0ydW^H4Fa8l*eEJKGCS6C{Z1%Waw%}=LI2$=WdWxNq
zNvGK3xyLfDrFf3J(?G2_+MZ2j|F{HCv17_2=iSq{OBrm}B{9UjJ(BOAmD0cvJ3TNt
z!3-Qd#NylaoyN8$?!>Zx-bGE+OFPxBL3{OIk?SM1IexD`{^)7di-V7);`e1gec9N?
zKmRU&(|4i=(aoekkQ^3EkmVjsIq8E^46HxrkN>uQ`=DsM8$+Lb5t}?HaQDDKhubJZ
z<J9uqh(8R7kWXNpT4@(s(~cagOWw{k(MAyAS-46GdncdM-UVt6$%>^myzh1?M%PsJ
z;v%p#g5x?WZE^J_5V}FqO8wQB=o-gbM9E<&QHkpe<EMk5IQiiKD29`FGLny{8z49a
zfFO66{~Z7q3;+NUN2?E>zk2a})sy7iH1Yh^C;T_nCwx!!-+pkO>aCbz=D(=k`rlM<
z{hsPqesCTV;9LL*E$_S}fYJX231IT?A%U*Ho(Bmw%y47g`H^7zZ;)X79wa<?zUm#A
zq2apoSMT_5s&{-(_1_#mPah;3!*JSl=k0^!|85v2fB!ICdOj$;1{B+`JuejA{|*Z8
z_e1gdq4Pj7(tzT+^FuN6zk_1r_d{{Vq4N+#HfDGw_xuEr{ofEo_IU}Swu%fYjBe;|
zk5dKcsIG_#I>gHh&T_3X$tG9XmWT;>*}O28#Ks;tOY6b&M^g#w&i(5Wgl#UHo1rjG
z32NdK#NAKPJ?b~kR&hk|w0J>IYgv6}eY&|W%UtIuoGX2^Xz_RMv(Ppg2%BCt;yk-@
zDXhdb>riyJ;|W{vu94KM9&vWBy4bigSLV at SoxjHhYt#hwxCJlFuMBf{4eHlwi}Pdg
zqTpU}jJhx9eab(uex5MrjPvZO-!ERYME$JdyztbXFmc)1j%U+BUAhoGbh3oeG2sQx
zTP|6Q`O%XJH(QZzl18%Q7sk>Yg*1zJBDpVN`Kh_WD<>`8EiPPm;SRqdMO0mF&Or|)
zCky3>ZB>Sfx(Z&knSI73ELu<=V8ScymXFK4`hs-c at +)zprpehOUZTFAv+pKlL6@)%
zTDc%a*ygB9Hw)Vqq|`ao1zm-~gVHCS_<W at fwb|JxUXs&i;1e<?M>8h#jD at qMkXqI2
zDU0R1g6BIfUZnQq^!@8BfN$r=E3+(B4rkAbj5vV5bbh>Q6!izjRYg|W<04PwNDk-8
zm3Hh}9#s9Mvv1XP*vMvT;(OoIMCWnoVfEv%Y=MG~ugK!%W%QRPe(5~Ed^FXcgZ9*W
zon0%1xacqN(#L{``mTCB=lz^^=SOREoXsmT)Y4N*fG!>@uWKgwL6eTovnvWz=(!39
zbYW;J^b>?o(zkiiNBfgDuSiqzB*y_=9l8Mbttz1QQzfu26Y5aWRDCpvdDK7<^C%0@
zHkR6 at o(+9=F1ntqvYDh56uMtONT-BIl^~+0;&7dCkTzn%rQR^!Junx02B>yFA61!-
z>Pr`T*gvQ7+c0C~zK)gqJnT4rvk95~>d|-#&PHa&>w>q8Bwg_Er%WFiAN~ptS6jmG
z`qO=P;EKq86COd?)E-<E?R9=6Wfhd##gVLeWNchCrO<}s*HjzC3QsgR8^yoj0?Fb0
z8dpV);`^BEh=OP2jYo`=bUbI59`LYV-u3 at V!S14dAjhJ`w0k;Da#g2Eyg>(OuG8mQ
zR}WRwgl*;`B`uunVNX7d&3AP`1=3JhusbkAIJGW$mQr<W%1~)<bFwMA7_%FTv1 at 0;
zVvNrIZ$A=Sjm^X6aYiD+nkn>aNbHe&tji^BMK7?PA0yv#+3Fo~gH>*{1`dk1-Y~CM
zDy?^)gZC*n%sVGtU+?aN_sedW*C$<6 at 7B?i>J9UBDMfbmS_`D!<-5aI3)>2HVcTpy
zTnuk8jA!?Sr at -4ecsm!q4&Hj<tv5V@*9M$7oLcXIf`;8NOiC>*E^?k+{uMXgOoq0G
z<TQrAA^3fhpFnzhnS1lh at J)Ck=3O1Hrr=eCwzzqy6{j}xt^6va*zdQo$7hj7rj0#O
z%+(P+Y!V*Kb$Qq)PE_Q0BN?AReG#7rp2KJR)A($Bn$}f|qs!N>a0(t1hzWX|+-!A9
zw&h*%8YD1Q1em-WY8p%u3Hkv_V_$wEreKFU6|hXr%!m;}#t>WyFRW<V{5JO!|EXd|
z8!iLVv-DW{&ur23+rOJ$o at yI|_cKTN at R#W?@xeHhkbyzvEDyqb4d_nndGy#=q#HBx
ze2>?6>zzd=_6i_j`%@6N^BH)Q!?fAFLQs>9Mz>g<eapX=r`oZeC5y$;K73=388zAc
zCVv7tJ;hKmMU(BT!Erku5D)lID>f9>VOlRpY$culc4*d?J at 8uZay*S1j_8a-2+~1g
zz6r`v^Is>Y<!ZZ9(FSv&PtWhoLjQnjM5#KgR2);P+U2jT at b2tcelxrMVw0&L8F+Hf
z@@e|@n2pVbASGEp#LL5=Xb}Y!$E3spSG$;o<y5rct~{2iR<wm*YH at Y$0UXp;bsmPF
z6~j<*z+ at o8)oBfX-s0+Lrvx3xj07G12|6eNAD-E`@rZYge$Ya#CfhQAj+uZCB-ui|
zMuSQ at HVBQ(Kq6(8E*#4J8%ZDm_Qh|e_)UDNx+xm!H)BGk at NfKt0QM8(lk%`PCv$l=
z;d-cp-->w!0Niho&tZg3N at Tw<lHnZ#p6bb7E-!8`z0G8*EJ!q&3QeLVuc2x46nLxM
zj^A#8SUT}$3M!r#)MY}5bX?vp!f)Ejzvk^NsAKRdJl3c-Hu)F&o<h2qG83<N{t8BO
z1N1REV?BkJWl}sIzuBW_ybXZ^YD`q5&hVtcb$&6R&STL!4?&%;8g(kAo$Qr-x{_w|
zXE8g{J^SPmBf!D%yr`V*eGb*vdYPjXBi7jbquCye&@;9JBwM-wHrDw^px6C?C^qho
zMk*V7lCmo=8399>h5>#vyBqQ5Y!;K<)Dz__=_R}$w#O_c32&6PhAsY~<@4MgAGU?v
z{|L;|u8sn!Q%Z6(6S|1G91VhAt-4OAHg$+nddxkK-Sz@*!ZfM(Fx7Po=LeWWFg+@`
zv!p&fdiMdSkzE9|)Wli=&=ArE$bNE%fCqYwIAI)+KdEl~B3ZmAoTU8*#kES|fh72!
z>wt$R8y<^uD~0N0_`d~$s=W|Yy##_Ds4RrXkKOQCc?Ue!ErW<3L0I(z5LUek!m6v6
zY1?pBq3y!wP0|+NiL=ok5ne7I8DC#@vbNHpRXc8yzLGx?#PMn)UKUSPM<^q;l~%3V
zI$Ju4Gq6P*f_4UqXU&$n7cO2>(exHx9L#CUd3T<=JDOlb-AGE%$OaTqBAqM`p^}1s
zsGhM0I}@+61N~MCUp34tQyU2{Qnk8U{<ON0C5zV^5-fmchW{dLe-XC72vJgmZ7ssK
z7GYb9mT3yMvP5cw#$At&jjW<T5+UZ-W;;rx)AFZ+n5FK{JKFd~f at o7lX|t_2NfEij
zA|}<1Dk_oAE?U^6ws#+un;bcZ@)~Yc56PcmoVn;G>1<;d^FT?~o2AHYAvB9`tR*H`
zfF3)#r<;`2WBANy$LE;C_{?v^=hXf1tlW?hp`X+f^fRWFeiHZ4&!r9YbJg4M^V^My
zUEO%g*0iOQeyv*={Aw=SmQ(m0>;Rf>NzCm=K4vy;#>g$5Fd$kI+u=FHYHDanJZ5k?
zItNvP?T}@2fL at QmtDbQfyI=z3gfX%Q*1F|5YqX&|XE#mu`>#chv6#RF<I~KZ!ZbcC
zThBoAF~BieAxZyb-YvanVyfjFDRCZ9L1gsGJ-V1&#=KaN{4BP?<e#GjJA3g|*v%4l
zp%*6%=Fn=v+;e;znjlt!9q_4WXeLp4tR0_E9LDEXyg{Pu*bmRj4Ua|WM>|13Pqflc
za1Z at F+dw~mcpH9xyD`{>BDl+{m0A_;6dnmteTYyc$S`hpucCG0OQ~Ja5H46HK?uQe
zB8Edhh~OM?8iDQRs6#0PBy+pb=pW+z%$?;fVt?6%XQ^ChfqC!@qMK$|$%e9bJN68Q
z;x*-__yj08`OP~=LMM3q3GC;5X7LQ at kj1gHkpX+myJM3~e1YfyphE8$ocJ+J9Mzy|
z;Y!U-c?}*Ounh-sKNKkhMfN}_cvTgl`sgrWH>c2+i4s+mWQBtR^7{k)SNa-oc6xFu
zKYwXeDh`w1T at VpK2<h-Avzb%*wH#(m!Q+(<yh_b39}0oaCLxF#u$t?boBer+5%LEL
zX?L>^q9Mot*_78X_kLx}%dn)9-`AC?*_}9I)8Xk`2qVGhx-Lc9<2)&flgEn7HoppK
zolW9JZV!9=MZ+XP02NoFF)-OI-2;=2hyAtyCKflVm`s;ecr-tx^>|n{M3xu2^?VFx
zzq_9HmoOeLHJ9NZ8;Wk|jZ#zHYy_67jKKh(i57t!fNeA%i0b=!dyAA*Y{+JeyRTu2
z;_9p{7*h-%Vw##U9|I3gvFzr-zsBGTH$Tq{9|m(<PU8G%zV>hu$F}BbbC>yVgt<)5
z_4=%5(P6Z-U!8gk3HC!YH(gNCCJiOYt8U?q;bi`n8JBOF)vx;&8aXMC1M{R{%0eq<
zvKg<LEw01JwA89jb{X`OGFh!U#vI05JG0YURH!S5lm!)sh2RmC<}4n6p<30UU(X(V
zKBl+!1`=nprDobylC8znie(pj*fBh{zPG`VMz^TylcwZ|wkf%5Go}<&4=WCTm3LH?
z_5g`>VfQrEOuIpv44Iz8On at 7+t23MkDU*vKV{X;A7 at rC84`ck`$byPiyj|WY>`YQz
z#{kWv2u^*KmF;`ZfKnV9a^T*<ENH(fb+W5$biY|T#zxW```ZmsK~z3LSK~oIH<L2C
zL+w&qgkTRe>r!C2HER+}<kns^`!Ctm7XRI-=oUOEjnf`RC6!HoegqJJAuusFH+Ceb
zuRikCbaXMnKW_gDbz1D&!#Su)r7h8SQF`5f_mX0NGHzWoZR*x>Bc;l*D5p(X5YcAo
zn_!N#>~4%CSeh-6;=_9nqN0=*NVxR3y1uEqM|Gv&*N~jE+v3V}F37A-(!``Q;RH*U
zT$P?^C=^tkG7SKC%y+;|K|_r-k0P)`==F}T at RrrOnesoA!#Bn^eLz8 at zf;f<b>dcP
zb27YOdo5DdeS4=^O0(%X{@%Ul>fKU00gVt!BbEG2<OZo(F`hs=MraR3$sbQq6X3~y
zn#lF!XR5B=dmFF_b0S8pxuBMQO}Af`sHb9v at Tl$hQ9!|K?LVMjJ(0>H))Rgr%6Nsd
zv30=-y9esbJMBi<m{|=&EH6W=VCgRe7NYuxH at z(H=nQ8DLMhpu8CaMQ$iy`H$P<LX
zcH9qqBk}k6 at kZ)X at Z*NhXN=#c at wc)d|5s?nAOiw^3ojmwc at kr8EeqSD?;g*s9(YFv
zQpWB&hnHUyZ{?-VK{mQ)JZ5tn1<y4Ko{0sIgn*K0!8c)yzAC*eoEH7^c;FigN2cXr
zNhAV{56|~o7Wxy)TU at 8mh>21Wk<Z>&HQaAqsP2O>G;Pu1ilC;x2mj{XT2=<BSu0N3
zu2U4IOA)NegW<3CVyPu+D)#PX#J%dxa<*2Da2{BDv9qmutn<LSvCg)t3)LpH_26t<
zd)j%R`Wt84I-BzVDKIj1mJN7;WtJ76$-K{<2c*=zz0O3W7U7A;a0-54{|di_C0F=$
zf`d(tK)3pBz7Cw=c1)tX3;C}jZm#ervHK_Cv?lc$K`HEONUkU1N0jZM?SHm+65bw9
zVsrBO&Wg{}2*v$)5-M at B36qRfK6@<^TaEC1KR5EF=NorqvoYT!p06w4$cNUXQBCGN
z+6Hc;fI|~w7fa<64!Q}$l?z5Nv>wKl3$}NokL!><0Ro~nj4s at Yonj}YXz`HYGywI)
z<%nKAVy&(AOrclTSJ>H#Xfffp(UQ^7>Mv{0ynk8IFIRn5=JlI=HF=+yVKJ5iqd_Yv
z)@q4q86#a=1569eDwW#QcC`hq=)e^8OK3<=yXuO>c$PNP^3^6aq7}WR9@%uOoBa{y
z`ka>0hy12L*UU4U${^@BFX435Wr+-1K;BZSOV?V1`ifalOl=FoATKy&Qd?_3K_;ZQ
zY-<u{%X at o^q*UNS<=tn13*i}5BJrU&2|5fbvh-lS at O8KmXJn4%9Qto_CPRnN6zQ`0
zaY8+%6sLO`vOvGC6lZPn)%>wf2e|(Zf{6iiujwu1mr~+e$U)WOEK~-XZmmjH+lvaa
z>ers7#?DseI&!S_ev?vchyE#pX<N at _`?2ei<pyi{rtUL&N6UOTX+o`D#goZiN#M2G
zHu<`~*0I+6q1H00);|SPu?-1ijt53bPDGiuL|L4j*ATOx;$cGK0MkQ%IIrm;Zh9nx
z{m>lSg<JA1$e_3jr>0Is)@keCvNICr_b0xtKk?-AC${w`PV7&dJ1{XUV(gyaQE?(}
z6s?>HZ!qPV_z4mkElme{zE+Ny#VZ+dT0R1{ox%}-W=<U at aX<TAEaC|sk*7 at zHsBO6
zi9L7?h>GP(a_}g+h7D&rU5=HB{)-oe)AUKGMa$M*MFJw(q27+oZrVPXp1JhIVq(n#
z)?@ukD};!{i{vv`E&p08`BFYJY*m^+729V0%l=MWttHMxVLq+g**d!6l1945#2gOV
zlu6p2`#BT{VNL9uU<6I%LH20>eM<hoZ1WW07r3LNcCokdq$4-lcWgJ$n&`Jfz3g{9
zeH>N|t}&EtI7x^Pr?8)3B9oFt?kagHYX_9F^k0`!94lp3d?~T>Kd+}O4=<{wr!-Wh
z&r;`)cXYRRACcQl3WO=}32|A`xXk{zEQrfYX^=A2IpZ at iKY6up$1AV!dnjB4?-(<G
zd^(052p{<9z!wMFQ;tffAik^n?(tb_E5u}We{MOjJk1H|R at s&(J0a~#^W40HYV$2p
za`%z$cKL{D(c&e$9fnoWGB1Jah=OGA2g#wJt-zTGR at HE<xIZcrqM(J+Xn={}A!uhp
z?yuF|c?WM<GdEmD0H>?G$@W12w*tVKKZi%U0j&d|O#^7{D{VQ@`q6+5__f2Y<CZm1
zz?Uonxcg5$ViUp(XybvX{<*JdLcsM;zg0WiD^aU<K>EYjL$TCrAayuhP2p2Q)i8EP
zGz!XSLnhd`$-Ap&-1=k?OWW=}Sktj4VtH3f4;Dk*c4W at Z*0tkuTBpNLW=`vNQ}9zW
zz9&x4X${91X`|vv-?R%^V7I;t86~jMdmE6AT3V5LN{PFoeDmP+f?3w86t#VNLDu7I
z&jQdlDIVaOk5hJJoEDIf{mD!GQ{>8Q6R=Gbm>YM|O2d;0A4`B+-rIoO($WghQvh+t
zRwXUU89hw1bG9f6?0($qF^=vQH_7W}nk2zLp4qQJIiYwa at SJ06@yzG}2}2WEaSZi=
zzCjGN%)=>$2)Um$+704BLT*)WkE4swfulqhdx0)a5+P?2A*aU(*<lc}-5}(}NCj6t
z12Yodda;TlWtJ-1OK7utyA`JErtKHd(`v)#Fe|NYU^&y}LziKBx>lU!b+d0?M$KE{
z4M3B!&Z?}lDeLTwpEyz)wRMh{UV7=x!p~9Cv_s;Y_jX}MR0MDo-Xe8t>+!b4P7{UM
zNHd^&$>QkFR951Eohh#tWM^^PW~Ein=!8Y>E)(5t;fwIRhPpr^3P6R<mgT4Fga3r2
z&EzROJJ2BJYEOK17X2W!3fnBs)>R{N8VlXpqp2A0&%Tvi^D=GF)Xy->O$mVp=>xw>
zUuoBZy^sm&b9)V^<8)5&tKZ{ZM;U}eDA2h#7VU*hW$fl>k^9dy67<F=@Sz0_N^}_|
z8jpC};KFLqMSEJ!oTM?1`VEO#Y<Sq|#so0~gR(IQ3aZ<XMAu7_>wZfw*w$U)TR9qA
zf}Kzd^6k96KcIK at F??!)G>o>iX}4v|J)>3)t(lWH#-Yv24yVdzN3F8sXSO!4qs|ew
zG at DFC&i9u$M>oLszl<ATsAP-6=bJe&?V@=)HL{uP_{~}-j*+XE;tlClJ{SZxe>U6s
zInFN4>_85RpQ+516BSig`4p+snNP+5CjsGK=+QGy at EtgzwhyU9O!lz9{R#4K#ze|2
zpGv7A8zg1d_Dj}ubNgqo28Rkx{vckyg{4&)Y6ndRR;7&Dj*FbWK51-ABEBLQ(KAj#
zL6a+bMVFxn6rLjYos%wzPtpZR!bj!4UQ`R}0>QUGGQ0=#CWBN-cT1c5Z?a?$*hVFL
z2VQnJ4)aLfX{E~M?32>eCiYe at DXMSAyWvu2UPHn5WnbW;4;?S*u1>ijcPcs=UH*?+
zot?v*8X}~u)kE~|!@C=Aw7B(*h+&q;gNt|<1KOiOfkD^fg-;x4+KeoZo89^XRCsVY
zZqPntRaV#w7BFEwS>vnvr-|P>(4?>G(*k>iKr?Bg6vIf_8$w&KamA#(fO9$8J-lyk
zt|E14|69ZRCY)1Wj21C|AZ(i^Y-<Pu$~x+6mO`X$rgIFGW}fAYto#BkoHZxZOfyMs
z&~dt}LvFUoRUK9+VR=Yx0oYn*pm=9u_x8Z3Oj2gpwHXdg5uu>lD%EQ%m0Y<oL2gL6
zN%~qn$v%WcA+)<xGsiN<TIg(Cc^Zpfr<;UeE+Ac-G4{<qY^2RrI9ocS&akp!kOfLr
z%4}havchKYEY7MPLRJ-it{@-#SqRR@?Wk5gW{<w<h1gCo5SibEB=+&kv}l!A+f3pG
zs9FYeB4)<4%M4{RPA7Q{FpScDci=EuJ^?Knbm(j^daR2mRma$`as9i*2Nc8dXf<bZ
z&aesr)W!4RHA2>W3GQvS<8 at xN8~G;Qx_|+t_MCiHz64hnHn!5Rm)3zh4%oe_bWC6A
zi;b~iYO!xBA7yT~>J{9cT<j}Tr!v|fJYBpjK?r^U*-j_o*ftBnzo7`6$^w^12k;E*
zmR7)yI>WYQKmFRbw83v)1FSyfNMe<vQk^ryQK{HnZ$oflm{H7BB%!L*`Z<|db#-?z
zj0o`v98Xoi?lO at -)z$ez827nOV?GA<aN-3qz<2(U_Ej;gO#d*-56DMxE&%)arN|7z
zm!c*}c5M&ORmSQt7u$CVXJ}kJphKh%6CV3r0j+D2r&{rpUb?`4j(PCxu_X}$%rvhU
zYYLB=kC?($gjfGSeHgEs;jX+JKeoqzydMA2(Ep(=aksc^xVW!<C~`O8SRA5Sj5zrr
zAeNzk;plghLoc;SPyk*ZNyH){lok{O4qwa&0hu)M)O<wN|2MD}FH&2URK)Nk+0^xK
zBkGQ#_xJ~<wu4M2`qcFZ8U!pZ$dqnV*Kg-vBjIbfoBadElD-Xdu}l9*Hwf0hJ|IDJ
ze}ac_pTAt+hUKw8_J?nI83%y6zJX_)2^kC3^?Ts!Dr5w1_EQ|N>+#YP9kk}OxY+{~
z)Mk9$Nrhp4<{^o|p{~b<PW2&LMi=}FVM1sQ{~m8&V-&lJYSq at okXX%;I803jAW{Gb
zpjsOyDp=AhUZBph_6L9c5^7Yn5KdcQjfS5C`WS7HIJu>Yi5 at lA*)2}+DwCO?bU#mv
zqdn}OxbHU2RE|?<+X+5}qH9bveuIV<m(U%V8ss}?frqdKc*(AdPv6DMK<--y({~n|
zhQZ608guyB<9rTJ9glOkoz-3vwVIfZc7EmNr5;wU4>He4V{j*={^7;QtE5iUpQSUh
zCOxAUes)_;QOzSgfBTm>#!cv&p$$#^Zhrksery&WMUwSsJ-_{I^c+m>iY2gKM+a~5
zYO{L&u~<qh*2arPy|WQ+J-;I^QclGfee-rBJ`JW+8<Z%gQt6 at Mi%{>x_Y at +o5gOz>
z at l;f^3JAQV`1Z^{K;lXpNWrs|b?M5wWzFkR*?30tdc62Iqovq~%m-M~%!{MQLuMQ=
z#Y{s6YiE~W0yH$?vZF_)2FbP=u?+9}%B5^w5Aq`;2Rf2us~~+7R10uG at u#x+{vZoy
z8yZ_)t`(@~V++*?dk(X<5iaNY(s3uq%>F!vY;qtG-QeLV2O<wBF4GT7zDOVW<;t)l
zZsuBbB`G|_!zRCg`i`feCUmN at gm;67RU2y>(i7QwjEHD4?s>K%8h>&T&PjM*IDi)!
z)#CAJchk+n&tt;kEBV*o_}4`K^*;Za!oM2%S0Vp;jepJLU(fQd68`l#|GIrDb`u7y
z#{fXrw(RI^w$2BG>q2jw465_#!pq8^kHfi__fi#RjIKo2q2sJeylfdNayzGz@$2+j
zod%#?zR at H>Azz-2D`YIKpUqe<djm?su|VCIKaP40-tFuM<N77psnjLn&7^jExk2=5
zJ`ET&);c`eX+*9c=xrb~EcTnu*Oe$7;04kctq<|z=`W6-iYEP1`*l$lGpg>5Cv#L-
z9b$;9OPXMkK{Z0(gv~V5__FYK%VDhN1D}IF+WCi#J_v#j<f)hf0LR+4-~bdy$Wt+)
zNlcZe9-|ku<u`saHjRqdjN`B+5i at T1sL-TPW47?Yi+p5@(GDTdNSbf$bU5(=O1?BD
z%=!>8o{!np{C3iZ<7o_FIdTkOIa4rzr8-!`7 at 8XIQl}#NeDy~QO}sSyL%nTFl%LFu
zj-&@KjE$t+fg|Zd8bzaV6#c1Z at F>b_C=4gF3c3%!cuBv>A+(QI%9#8#?zGsn8D^4_
zRtac(h;B0oZ&(+GC8fgFSY at -J;1AQor8>=T#rGMPNH3^&+58E0u1H<QnP%5nv|*UH
zx2_`6>^fsAf|C4ZeObD`%!<cjWG!C9Fc7XD$3<y2szgk7or+lw%4-Ox3val3FLBw?
zs1V+u=t3EH(Z9Vy0jc>F3er><9lhSTxif2qscAdIC*D!`8s{;9d8D&h9Paf`Dpw;Q
z(`G|+$YA4=*oMh(09R_sGQa6ISQiVA?$(x@)de>BtS;sT4~lv6S+h7!J_{>m_V+KM
zavtkAPI7#Bg#5|5utnaRpp+~NC(C4pUMIB;;<aiWN)Srwgf4t1)9I;K;(HBVF4;1%
z3*AuJd|k-KUdxKHF^x;eKg^2q6tdry<&KxRtufKn@=P2<ScK=P(@f$N821-v^|Kaz
z5*v-}Cgs`TXp|*wDxcTg>^G<53b+h+&QiPn at RpLK6k9#)*)7Oh7G-g*W`OGGh5el6
z{R?B9r6QDvJIQum=5A=r=c55hMYvZG at tgfNwq+y<UtO>$qfM<}h59$O!i(7dc0<iy
zeuZb?OO+&bmJh0i;_n<Co#H03_fEwDc at 0NU(df7a;`UAaEJ!|jo7v{k1bHVEcaZ@(
zuI at AFJv4_b{Td>s7u~WJR5;dM?9n6#nw*+sP}%REkJ<`KndPi<to{4qB_K_41&w=;
zMNetD_fOv=B%_vj*|ooh21)k%B*+?QAjR)bA#Tdm(zW~+_7#4?tv!q~qu=3Xe||V>
zX2 at 3eJ2WU0evj9X3^n))pPp{=C>3_5K96E(NTY*uyGfgpTR%=3DMtzg8BKT8^js~j
zb)$-bWD7e{Q9v32kt=*PJxj#9a8yH_3|wL?TC<Sm$q~njIf0{MVolGL(hMH&kXenJ
z<;38b2ysGSD&Q&r3q>@_p}XwbDl-R)op}y9TY0$<yiccLL9(WCiXEC7)c`^f-r+GY
z`dT_+H18-BU!)Zm0yajteI-yH-oK<IKO()NbZtE%XmaM_MVMk{d<s{eVQ!J*>Ek2)
z=jFIzGsCyQf at j62*vILl$lry$9Ni*#wbj<<WRsGquUz=&d63BGej52}0Hzqf1-dSb
zrizOf%6l?_oG?^zMSOE04aEK8_c4o3|3l|+5v|0bU#pZx^j!9b^#-qmmEb8d%APB`
zdhJv`Dp0t3^<1h!p at Z$r+N$2yq4>2=lM=)N^n5*r4|37r)(-)8hUhEZY}`{Mcg!CU
zJfGPp7`SQWd=MJvphHe&U5VNfzAdUlu<s+ZtJ1}e{|;@gxYemxc-~R8X%7W`7%hL-
z?|AtGg6Fg6d9Y7eJYQKnM_KGv7MH{>VAr0&Wy=6xnzTxTL6EKlX at km@sqDBNkAs4D
z;E>D(Mx)i?%1P1C@{2|+QTr7#$wU-y6>TA<_Q4Yw;WKE<Vh0vw5(1B#xe7P%N4)em
zZH81<v(9XiN`3RO^CXA96;rZ>7eoi^<seO^R4U1p%B%$Vx2gmNt~p^MPzl7)4BT-x
zko9D{4$|fq!(kzZ3*d4k=!PWDmK9fe^sNXJdoK{x_CmL{5Q^}!?XgfAmCqtqF=;_O
zrSiC0M-SKV7lLRKg$KLK-0ZI}M(HT<Hch}YtSX^JF&l}zMy)$YUBO;64HwM at Ov_W$
zAl9=pJ%75X&<)Z#heeWOx=)uPb30wI6?;G&=1(fq>6QK97gSuqR>X!l!f(~LVzoMb
zvlJf7tM12Y!mub-Z7TIo*iPyUq2 at khp|KsUum2~uqg8tX^{ocj;VDx;@+wa(>!VIa
z?dmaj3K}WXg16&7wia~LcD782!kbfWfCJOj^WlOb1g{M13Q}E-f45qW>nlo(4D1Ry
zYRpBQQ4&5B4IYkU(U9m?f+7~U-$4!wf=l~|B3^{Fs at 4yfhHk-vXd_)UDZvs9DN4Gp
zA<5G0Pl6)u#(>~t1eP6ngiKUvbUSRGs)<y{9L!3k%Z<HqgLNJZG9hNoX$Y>1DOT06
z5=fxTC=uSE_A6$8l7R_8J_5Vy5pL6e2LhNN1V^F151~wc7ONwNHxHk}(2ZR<jyQl1
zw_%9K>U4;cREJItS8S?=k;-F*Si9S*lmOWk5)3wZ2PR2W9>WxC-w9u(QXat1C0d|`
zN^>ZW(=TLv998vV<&{{C+|qLNTb!<ubs0S6 at K^g9kg?(+$7`A)3W`(m8s60L(!fO<
zT$r*@j#MxI($`0__uF5hI_+x0 at AjQUd3cIds62d_4l3m5xSC+GRpE`KaAiH3aN<}p
zOG7w@(5FxkL+)#^d-O+Y021WS*Q(Ud`c~`&z&(2#XKU)|a^5G3S*2bC+=l9a{Azb#
z2HJ$VTBSPVmPCuLPwb1yWh3B&t$>2`74zAB at GIXn2jw0jtSB`kTK2Zk9-v}<FH}zE
zWjOm8cQ`tK)t>m3Y4FJL<Q-MN at hUVdo%_Vmz^d(T_Dj6o5W>b=_Np`AD+%qTBO5eM
zL{&V2E>KaU6m`XFCeIOqXj80awRwgRyo}xwmI%QtL}A3Y at M$!A^x{D@@`!F)gn&*v
zSPGRV1n@>*jngRvm<cOcYE-flC&+M;N~wTpO=8J=iC%HE!WX$sEudI&m`>T`W_xWP
zPJHY3&fxPZd+m1!L*D7~a%Z131gi<wQg34V#Oj&eGCq=tIk=g&E-IbOS2fZHAk5SS
zredP#pci|%g{&l<e8F0JYHkD`It!jcFqLG#0*c_rB)o_aR?Ahjw1b!=yc(nn&Xf2U
zce9=d_txGd-ma}H2_6;m_3NW`zPQd10Y)1k>OOWNdNcbXLPOYqXNKJ3kb4r>?L;^*
zLb7pq#6*^ds#8&}`kSBkpA%Hs5<T8k<5Bn%$L8s?ydYoCut!&m(lF*c-Y;C^WlygU
zZ+NkBcH($RIJtY+UmgdD!iT*49KgckaGgP2_R8Zp6TU!cK2nq3#H9jz_8WxIj%MRW
zu=&P4 at llYv5u|zeDf<F5iH}p?hp&U7uO`82kWKu|aE5XT1hM&#Q(}$h8Ao{vDUT!X
zba*HZ>B;=j9GVuD9V<e3f7YMwE5y}B9Wv5;I?y9=;>wZi=D)?(WhDpb5Uc>mlI{Ky
zca31h!EOzs)!=2Mq=pFN_z+TPP13GZ979q+&G%!zOfz=P<}Ov6*q^@U7ERe}$d-89
z53z;4WbheJL<0Y7$l>BBAF>9#$os-tg8-5gTERl8kEijK3T|d<>z0E2_aHR9j6KW<
zS$Ik!-DsSUNR#yIeYkpLrC%W8{?nBt!HKJ$@YQO?F<9n6Q=#gd)aa_m&c at MuIIWDO
zF|2+w!wLpoVeMc)PUA}^xpLW8u+sLSRcYLFbzBGRXfHJSvBoWU0a<Nqirz#{#|?-}
z$?sFsX8hr_ic_`CX at 95VMPQmkfy0kj{!dcbvA)y!V%%ks-T`s~mm)pvO at 79Cv|QO?
z#cS9-LSU&G6}{QQ19U^!ECiByz^nsY|29>g>gdE%rocaO&%6)MtAqerNAqR9Jl*6=
z2U&kt*I8t9|JxQ5<MGVEXGN8Pi+f-}Q&zd<igVa1^m_c~o&?f78s|Il(scAexF(tp
zjo@>}UHKjo at c}EUZ^@A<E3fddJ*bsvb)nv^+M4s8-*VuLuM-N$`3NMxd*3H}KTzrp
z-!TZ>iC}rW?AUuz8S7bnD>fOzT4P~9_c^l7Cf_43A at r`la9b3MY3UPMgQMe=o`K$=
z)h_2ru~_cY#iG21di$)p4T&}=tFj<#mS`)Sic-RI2F%pTB`%C}*H!eeZ)|AG+X(RJ
z86s}hMH$eA8lBi%*x%mgs24NfqwRf;_HhQ<r4hbfI%|O<_^rj!w9ngrM<~-gBiijA
zzm-+v7}WDI^gCBz{8mcM{CKB>_EbQAz-uh!P4PL5jrzC{ypupzl5q?slKqM}J+XXr
zbQK=&C38wu(aw|{YLf7Vb+sIsDvqs$e4}9fkDDdZ2WoRpBIap~By_i<LR$ZKxQi=0
zd4WtD)c0YzF{dC|93nSb3*`cn)a at xmPbR-l;>=l*dT9 at P2>bdSlrr#2Z$?g^n at CYf
z!V0a|BRap7FGDlli~BtyIB;E_cUqB7kx}#V_87<W?58Dn2p7p^YNl7I=ye_!@9|G9
zV}6{-BRHRm3!EQ|^YR)h3sxlvk2b(UbThWVnfN+9rJ-yRV08<HG)t>DKMyZxO+C-q
zEMCL*!_eB&hPN$0Z==hVUgn_}aV|UXVH6Hr^`r7qffNyf4M1X0(rD=5dr&cc%kxyU
zctpu9AoNSaA?hZI;<bvqlw6fukOA<o<y7_RQtts>sp?|IC^<!-4Z?<VP)|Xg5cn3E
z=)^z6>|y&kvioxMEgD2V2;{1yp<<w!+k;=_PgqojKEhBLwA|9<W)~*LaB>?Oz=ya|
zMx2*Dxj)7dJ|kY(mA6;3&Z-0%w=`mD>i%f--tGgJw9fPD8Ow~#eYy0M&ffh1(SUBs
zyi9rokL09?n1*Hl=n=9DSPrdooeCYnw#>E8QqlnYf+Xo=EiSQc6y&)$e63!cki#5_
zv4vrNv|~a!@CL<70C`nH_s80-1ZRt|AqXW-<z at VY6p5@x8T+mLE>W`(xD#t#(5u<E
zE5nort%#m$d6^#}iy=YhnY}o*_p&!OM&X57G^fv)eIcY$waE<$mBGEzw>d7`fk;XJ
zc*4#NU&O~#Z)`lJs!8?M<SA3dF at d<j^bro8=LZd@=l`3*RBjnOn4Z}^U at -midj}J0
zRg-7HQ_dzSgW3NY8%#s?@@?H8d(>Pn)BudM%s<t`t}&=asXF285euE&xO$nq#B7Wu
zBJaeP`B=IhyNp7bq&v{{-FWU>Pt0OB at o{q#+jKa7+~AE8bjTOP9S#^6*CxcqOp|zA
z$>jNI%#28gjhQB~Ny+5cS0rTluk&HU?lwkD&)QoH#)@;bi92DW9M_O6D<aZpw8owU
z7*H}pKQ)$6 at Yyv>o4CDTtklIxa)qDB5esLv3C6WFaY1-4!TAZEg!jaeA at UD{43SQW
z3 at NWGnpX&1pvRG6Ig#NgY9!+5epTv42Zuk#_5q=}*@I?dp!SGvAkYQT2rpZ0irMpr
zVX3y{G+SIJ>M{%Chv(Ax;hA%&e|Ubdf#ZP>&(;kFxo6_=#Pe;wllWLO9}dsQ;$b+<
zj}3<fHjg)WP)w$SbZIzy_h3|EwY8Zmb(8B*$y%2X{#5-Yr>ovpXHO~&>=iAyNGBo7
zu;v64dlYkBTn^0T>u at ud)MKj5F#Y<V3AN31tt3Ai=C+j<`8|HL5VcIP8H1J7?6 at h_
zn|B(A;k_G(1fZtN3lb^wIHN>uJ(ZYfl-LRqGU~Lv%blad3W=SsT>Tz)1ETvsE~{x!
zSw=}|ZxT!h)RpMC=07a0 at jInOFR5n4fd(Zy{?ih7 at Dls|Ia#|K$;;CCdb8Y!8fSBP
zfb<pW1DcF$=*Ev~9^mu5G3N8U2z{Pk7w8nnbD!tK$>+J45dMo+q+=~PjZIonU+nE%
z?5)>$Gel-U&PoBgx2C`(CKnbtUH0Xt`mL1lle{kW=6WK{yraNovRO%6jEA}Q=z6>=
zA*^4Q0ZE-ISZtGSKnFnV-YS&I!c&E92TsqtZj4pDu&~~7!y)ko;f=k*wu6nI*izmt
zD78x|CE-!R8wUy&*u^1*!Zur_bDy*i(qLQ~RxvWF>6kXK!k8KE7#U5A9 at C*7LEh<I
z6QE1vDc|n-5{1Swn)TZT)J&M{dkR)|dam4(38E~Q<m at 2Hj$eC-ta~@f<0&B?8hx$m
zW$G9QB=YRUFt0idW{lzTI;&Ys_3DSbEL;b5UItvF*;d<!Mu65Hqm)bN3~UIdlq_!j
zP=EaAix<TtRej<+4WtjkJ)r60cq^Gz!LwVEY>}Sn0 at Z3<lA=t4DjQXuc}EMz;0g%+
z-=2aIK9-F<8I^{QY$sJB$)-)Dh5&!Isx9IB{h4eEt|`&aswA+Vycc&m=JpR|3r+m4
zGcf2J!jU(MA8DkQCDh>&ohz0}spt%+DAU5pUiOcN<4(<@H at JRgLiL-W@lIM$ywrG$
z<!Pjfbct^4Sonvr>3>EG9Ft<c>f-IG`JOsgXu4a^r?G)|5|)m4Xz-uYQReZ|n(kUx
zZ{9m@<sPO>c>ZBP1M{Zl>be`Z(LsbS?Ydh@#n<vBXmR|rig~f|nT(d5Qq^0mmiO}P
zx$NgPK=-%U)mb+B4%Nc<ckH|2i8raruCV3h*O1%4q-K|HYH{J}$D}>v;Dye$THepI
zPi9lFP;{Se<KI`-(BL{<Xst9hTT30<0;ZJps*CJs#<ui?+|ws6(PqOUZ;?7 at eY!St
zy+d(zp`+JGaIcuIe#io4CKFU at 4mPYVtj6nNYCF^_y;oBO++n<$G!TS0t2qcB0^tVs
zLN#fDa%?miM&-hLfiKh++_mEV4(SK-)Q&8)HI(hcU$UAd at 4<s&0VXKF`Bpsx!{t3T
zZWND=FC%|~1q<!s1wM|HLuxC#j0eL|R!Z!Hp}J%cRKp3XF15r44SefXlj$w&%Yrhy
z5V!^R=6JFD*a3(Njnez&N0=}hR+l>y(eLbvd1R*xxbf%Xv?*k!OBEVFPm-s=q?~Uo
zC9(gcu`)A>4m8^>4KMSb3fs#3--az^{?mHK?YPoSR<e at v8Wx2|uvz<%`jNufE$}L5
zbIGcIvIK$8<8|&^yU3YJFqEn2A5s09VBp>$lL3a)GjoA~Op>SM>SAtmRXZkUpXit^
z+GhU?C}evQZWCs(#&=^-?1fh)GkO>rGwBEfkjeh=E<wnC5lar~Dw+U8Hjbg?7c#|2
z^W**^@7t;C;lFa+*$Hjj)Y<8oHh}prs?|nHdA~w_bPsC&R at umzui6cbgtl2GQaf8*
zouq+!6la8d-~(rIlN7lNe2*gbq7~cSF%Dw^exeuKqFf{wS78;M;utDB>Ohl9)@Dw&
z8}2EQ&s+vDH02!yFrboW&c-tvwG}~+wF4TV%{1F%{wDpIzU|nG-vMOgqz#sW$NVYm
zXE6hpu;RTFrR5Yhg`ltMMH^Ilp`bZ&xK7-G#o`enI<!`#4%JE_i6$FJ1YLrRC%31I
zVFp+vud|t?$pGO=EIjY%48R11js7kw5|xT$VGAIG_Sz=U*55IcG*Vk^FXQdTGR4tl
zydiRPVOUnH+Eu9o%76L{`N_cypEpA?IZe;ua5nZO0Wv!hEx21LS9R*rnpq)qdEqbg
zXR{xjjwxV^cWQRZp_pYNlx%fa?QUw*?iC}O3#}&ErZ*QR4wdh)ndF8-$Q1rt<3AE%
zTH=)OKDVN0^j9+yj+eC>Te((5_29|kPQXeNpt&<*Om`jFF-Z`Lozi*T(bF!wO|;ZB
zWp}&mrb6IHmYRJv5LkmR4l;c9D4D2`MnugDHniyEv71 at 3aP-ZbShKG%45Py$K_*y6
zp5t4$c67{>&ipMn2GD3aTMn<v<nV3<*E%*2`z;-=*6cH@&FHq;&PQ at H9~kPey4w at 1
z>M(77!uXntYt$h?WaDeHtBny5ul-n1)hPtfL6h1Xx<@CyjXWI!VZDR}tM3g!oCb)i
z$?o&8E6>Hb`zrkIMUA|M+Gg}q<3$rDuKkK at kK$^O`-+7Pjs)DFoMT0wGS&pV457=B
z6yf0ropPs-6dwL3y=6Luhdb#l3*L_KGjOx80Z+X&>l1V_t)y2q<usD92B*tW<x-mm
zSwv`#SwtAFt*86M>c{vg1Qi at D6|Hhlf)K3Yg^v+7uE6soGzm)OD5Zx77R4_o3(=z9
zr%xM{vCg8q4zuh=^z*#m&2HR7ge3$=(q)o8ZgyKVB#}ZI+)RpwoWzNFJze5PixZ3d
zCg1(E2Goktj6 at Fo_TSr1{%Vujt}JL%n>Wd<SUzI9)y=x at 2e8{!SKIL2imOd^9o}So
z<>_93rn`*2e?NI9a;2+BHhC?r{wc$cl+9yr8ljm3LbqUOX_g8yO9Mn$BEyfUjqn4-
zl25bN;YSqdM2TFLZ3c+|$|UbHnTqR}Qra$F2;sVvC0Fe?i6hAD%+DM6QIt(}?ct at h
zsE5K?(LLmgK{RBwd*b#5Qrcp>ufJUtcTHrDhr13(du_-d7JJytZ*Uak?R7SC)+iuB
zJ%W5;3vr8l<Q2doCdmzna!HR~*;1&RhAJf%co}CJ+FW=MeB{-YT%+dGw9-(hxqE7x
ziLrdJ{4ZtR%7W6*g+Lnihl at EIxfdlh6OXN3y_Tk(m=Yu(=kc`(>hXdxSY6e9yE@^A
zSlBaP8z(^X47R1!QI2G1<BDqynB+SwrkXp()yQ|`nK*p#%pMBBT?66)fMj_OfN~yK
zeo$_)@+#Io9Zpi|El&>~UAG)%EYhO99i<pAps#)i-hV4S-Ds0i+?){s6jNzNB#ziW
zEmCIO3hAvk)fHR6!~D6H2J(Ja#5zlN^*Vdj{tRZflUM|y4TUFNOu at R7YUWyN!VdzQ
zuMHlR68)zahKIrk$1`lX;aj({Q6G_YU7QZfmTBG?Y<Z+~sZ2wzh@}*Uhag+D!mI5&
zFo{<JJmI03tOf1P=`-XWi?D$-H>l6`3>)hEG|=8G?rfdL1=ubw?m+%Yyd$6+F4C6S
z<#l+q2v*OytOBtHW)h6m=ALr4F8@@&p8e_}n2#@qB~^>HR!8Y_?VC#mS$zHv*8}L9
z=zEp~oq2y at TSQ$C9Y1Nvk+d_y#8f>04em4!+19cbWK>?rc6QOVd4X-B??U*#1D1_?
z;-jahn+&h1(%dpHh<mFOfXHt&{TWZTr0g=b3mtSS$#^YDD^B+(D8)7<X(9TzFSdqL
z)f at 5h=`>|=rn1;tJJ*h?Fo4p+MR*Y+<`SdIW)d$)<GoN7mMf0(urlbc+Dg0rPjo|@
zX at b=#s`i&dp3_D4LNQ5R1DVF_v#qOBV6IBg&3Mnv&Rw^ha~O_NCCiYcCOxU&0_t#B
zjnt##7CYOD>*{GbTBo*~s{auM20i9=sUNXxf#;yxdR&(DibLgU5NoXFvEiH8$OaNG
z!xPZ#tVw<UX67fgJ{y!K4QG*E5Iy+{DOG*{)f*X#_Q9johuJ3-jJup4?xNFa#THxZ
zqjYPsswTCtH%{I)*;Jca6jA352!v#n{po5?tWFqYEH0f-o?cyYs8x1Ndxi|XHIUIa
zGW{0ZPR}lS?x!cCCmDkazD-XQY}g|b>XJ!0Z2Yd+9?3<o>3YqMS0S1-s$NFrqC1wI
zL)O_j)Wi)D16v)6r&Dj?)<B#!Vl+gob~W}Tk~QM3WMnu&eV0rT|0doPF_&=TOc5uj
zyU`A at 5PXmnvz&cG;79OQKQeExvX#u*Z6y<TTVID~-D6+DGjLD{6aYlClpScpu7HvW
z8!m$&ZF<L)g{uT%=WbzVP07muV~2nQDeMe1`ry-_+!(QzE5WBA2XO3%_kl#Gj}IOh
zQDl-e#1&NZC{;(u+Pc5rmfluE>sCZx=uyZ9b;vARyh&yjSQ;^#cxg$Am;qlxP=aV#
z!}PY$y|H&|s3P`m4$Xu2T6)Jrs?hXUR6=MHyw{w)Lb_6Jvhto)7xgMnAS}+~f;O_h
z#BK@<B at RK&Cw#rHVW_b4U691uI01ydz!_yLwk-6qjTd{_z+#zEY=g}d#X;zG8y3h0
z6-cFQqEcpy3u?~##F;f`mx`G+XIBZqT3fU|$Q?t=G1-kvr4h4?Kp42ZyFy-D6n;nO
z=Gc37=tg+2Po6SK8e3Cso+xF?EeS^6npob^kY-9ArMQl#cotLW)oARHQk((lYs%e1
z;A{N7R|tgg_W>dB3I0k#;3NE9Ed&nW??NH4HyIIx^dLWreQVN!IIi5nw%u-ar<0Cy
z>w`#k<>JMvhNDd*f at 5=g(ASwkgy{0 at 6<l7%r??WY&H9o#twin?HllkiA+Uy=T$TwN
zzoCP8?0=aR!IHj2Tv&qZ`Vt|yArbJmJG&+L=sB)W#7Upys!-d3wi&nM1$SjfCk^Z0
z(n!EA60{O@^+w%=m*hfQ;Io^!LN1_B2%;KQTvsWk_-JWpf0Rn(AfM5tMDnB#gu at d$
zkgEDg2q6#xFM-(ZJT9ed9*@={f at CC;o-M?4uo0m(cml@&?S}v+XzQ9B5SuQCva!v-
z!pQGdA?6Bi%;@FU`L!T6+^vz>OE-J^t*EuQaV^B&=+gM``Wd}-L2kXW!wBRVIaHx*
zpd!^08wSp1(W#bLo$rYgdEMA{VV8*;x)jql<?KEXiEG3cs6fpb!N+LOGdtE^H`|TM
zBcWFGa~fGDY&=CBehk+Tk$Z#<+bH};!p|n6(p%(S at j*HAV{w8Uc|ZvM8sbh<^)(!9
z8*abfY4irPJ-k58i^0sMZ0GhEZa{Melr3AdSE at lIyh<f0Y~!y=Qa at rsjn?RBE96z6
zi7=G{x*Ktn34y0kgte$;R=LSWei)=-HD`Y$-Nng?(CaOr_jO5}Bh>D|C(0-5rm94M
zwapb~yn(gua~L2*w!m?beWRi_N0hP^=~az{hw_3kJ5)<1wV`Guh`NR9j9w+U0f!SG
zk~*<w7)v@;!w~_YzojIY!|T at bOTOZFwA3fCUGko++P~un6UWE|s7XpUiu3CE^NqBy
zSl)qf{z%FM$uus3yFbB=S4qQ+&M?#5gYEE!&=e(a1NN7q;S?MmFS8Xw05z0>t^<!?
zXXCu^2B{%pipx!dI@>|405u}(DS>rfa}W)==GF!ON`#Da5GqQAQ2P>k%Yh^LRxG*6
zdb%-N%;e}e-3Sttuxmzd*ovcO6Uap~dNI(l3Fg6r{fR~g4_1#{YYjH67}nh`A2f9z
z>2I7d3Lb$zIig0SguJ5$?yBr at ba0_eytkX!&_J3{TT+^&q>Bh>O*+Y^5}mk7u%S8$
zqs6OKYWSvG-DO_(&>KLRjk(GboGjEM@|l8lNfyFpUE1964$XBkr at 7bw4A~wxe7luK
z=nwH8qWWG<L9Xc4xpi84Hk)$`!#B>Zgz#j!A;I~cbTWs???5Cxfml`cAXXJlo?SE9
zBqkO at +HZMUUX#27N0Eu|2dD(b^M&GdFCe<aA-u1y3THlVj(+5XQ=U%{hw+bW-hZT>
zOH+2v6CLy<$$}dFyj{9n?STc`Me$R}tJ$}(&rf0X_@#^1pkDp4x}$-bNZ6(Ffg#d_
zlm2a#8Q99j3H;3}jSG+BrGea<do%l=0p%U7{=2+`CO(y566XU9Zj}%#ypiPgCuy!z
zQ2rxW&CPOi0=sH!RLL}3)i5}?7gzJAqCjlKOGz+{8pC5`GEA(8({(D3Cs6mXrI>`n
zU|M^%0jGGWN|=a)Hv4AAPJRbkWF;nXxK1J=8}(zHx+$z&rMb91xsE36K!cc}YB;s4
zMD}^7>)S#t-=0^><=is1w@~;a+*{CQo8Cz)GVQS!nNGp~t*J$(C*l7E`2Pz2vxOql
z0E1~Cz7`Xv4?jmr6ClhNI%osh)HL11IzK}w$Px*9yX-@^AE>(YWPirr at Qk57bkJ2G
zIVg>IOsTSa*-I;tmrA|3e32gTa&JxlPn?3-`ym?g9N%w7`|lTf*~4h8sw-w3*{d(G
z!MfE83xjWn-45O>&4)HOp$6!kD`VS&@phGcb5n{;>`3(1(s$!8{tLvv^{?agBM|@V
zLGh00DJw7jp??`orQiN9qp9$z(P+QJmyP|H)d~HG9x(l8cHr;)pulfgqEvM_r)FO@
z!&Eh2?cVGdGs9Gn^{VJnt*@Rgw9BI4X21N2(P0*}KBK3voj}PT1+3NGe2;-b^og&s
z8}CEwJou$#y*ewrc`#;={vCIr&1~_fF~o9<5XE-2wdNB`-qD&f2~yz;Xy`>OP>XF|
zby`j&sIR-y>-MneI4`@I|7xy`(jp0vFVL_?kUP#P#rANrJlCEr at 6(q+M!C{zQj*ZQ
z{XoldLp%)kG|I!*c-UHgHYz6Kj><S(@8iCAx`%y)_P^PlLy)e!y?k_ou|a@(%ZSUi
zPmNu3Jk2n(pMJ_uE^wH1IP(#kf`)45gb2<0YQbc2v1%fOdY~B}t)N}LgVU7-y-{4M
zCHB*evUp9w0-H3<&2Ea0lCgmF at Th_+o0N{`o}fRjF`^{P5El%wUWSu+aX65tt5Qd_
zBRuR=s-!8}0T<92hs_L~AX-${F*fg0-V=vAjPn2=w(RsLbk#_*A)ZjNzC3(6p8J2c
zoR4CB|6?C%O at GIrsQw9!8XL=5K}DL`{=R<CIk=<ZVKr!C$7P3ZD}Vl{(nz-OmDtG{
zb{#O0YoO<0no4C;DT>_6{=F>kC`?l$l*QKP9YWw?tZ=SP?&wp}&{SKoUGDfwZcTu9
zNC9;H0&Njp$re6nY$%C#Hs`_UW>PAS?6jA;#%r>NU3wV1x!8_0=jCe~pdWRbR$^At
z)VY~Ck=e>ztFvd_7}Slkvv3ZPpW^Bbm&&c#P%Dzp8gxy52HDyfWNVGUsMG_%+lX5|
zHh^1Mv&D3OLRr~7)^N~dx at 0%ZOxV?zLap_swmMsQ1S+>{E*n+1Hdb9hRj)Y2z!O^9
z=J&dn#H?_tNd+#ORICdA1h=!)F6FRON9o83H^i)@I_q-qD=Yj)?Dg#PMO?{Wn8$v2
z%(&|z{#8jna9O`UIXvbwsWrH3I>5tRiH4$)u+wELmy+a;k7brz(WKvGT|Gn{O1_td
zHr>iDDd at LZP-WA_q>51A!B|0M>H?ddM3(8*cC at gcCTweRvy&P>$oiyz^wyp*4cJ>!
zOHuoeJioz6)H3m!l(v>`Y|&*Q%}qk?cz7<x8$~;EF?2^dJ at NjIvl}L{k6w;V86P~w
zC$WG4OTreh6Gm%cnY7%^{(=W)=iNMNZ|vclM^6mcJi6>Z**p?6+3o$6mm8HQ3FNw0
z(@>|IJ^4cr43e6Ii|A$;UCL5+;4%zX?z_`~O#6gw4Zx>1a5i?Mz7^Z9)6F$)D_xI!
ztj}O1X*|-+s!_$he3q~++0E*CPU-7VIF)uXE)|0J!Q13nW+AXJ6{mA0m<8GDg4Ymk
z=hL%<o_ACDLVA|d^DcU>pyzG$ysr<<?BP^qR)Q1ykhwt3<EWQyDhGS4N=4~Z?0pSG
zwV9c1y!6mJ$QXL&3L9lwYiy&>E5v1TPq7f7J7PVvMTguoM-uy}me4ODu>KZv&6!Ek
zSZ!89&E$#F2%TzHBg$61=%;L*0?+XMHD~f9J0-bJvcj_N_L?(yi{6?u_lmdHoOwVj
ztvRz=EU7uOP#P63>Z7KG3*;UjEPZ>Him7tXDse;~wKaUPHp^Tyd8zm~hoO&J9k%yr
z^rhif%??ZnP3WVKyLgYzgdb^?8bs<<bCsZ}kKZ7q0GM-5*X+2DQf at 6IJW?4_CiGL8
zn9 at wu=u>7$$^6v}h?VzcD^K8ZOYZrxc$3_77Z764Lt;Abe1j%xQAH^{Onr=~g<qqb
zN!~E%VjEh{$ijO_RI5r*sv33<NX at D8j=OnF-a*G}Jr4*Q1Buu-OK at AP=Pn_T0V{U@
z-3y)VLIAhQgrEHk)u4NRv~HH%bFX+2044+<!mT2X1(oPp2)qCb`%v3ZTqe<#%O?ny
zo~wl5`XrO7nJCO0s!l?M2bo6jRgzt$+m+3xt7e3U at W32tj869$2ehuTC)T<hC4|Ie
znNsP(HVO{kXAmKU0#R1h8 at D>$R0`64oi#-ZA{&8K19BSoj52M9o6w4EhOItpFi;`z
zH#CA655Q+<qX5u|O|9eOu3n|v8=SeSrg{?}PdD(CTzP!}TteW0X;9JiXQN>93hMcg
z{2pNUorwXPI}~mD{R=d34A*N*`_W*x{M(Wr>@OKTbPRy?_?ZD{NP5^ngS=xtC#ofM
zQ5+N8gQSKpE+IJE{9QccQy6u>)pF0jh3Ml*45FEXA)0fhpYE at cu8fs<)!-7 at rv6g;
zfUf%q?wWz1;oU%d3y&O7(cdHeP5-}!>%@MT{I)?YTOJvJ>t6>AT=VIH1Fz$fl=9H^
zS$5YxI;)EI#t2(%m<qv($x(#sL7as6BsI^ibLM2Vn1r3g|4Q6?{+zGkOlj?Lgt}qe
z2KU1Hhnn0%tRCeMgTbu>7KRgsc>r)~-yrbzyvxC(Aq=zYAd;xJ3_`&J-2<2!8i+ua
zI7jYTAq|%!L)H$FBdNmA3TTTnTbc;0QV8Z)aP#{K97K5saiUM2e&|zNds>8 at b5f7x
z?Nf=t1`h}UlO+y6UnbzkZ5(q4;iE2?9Ywx%JooB1kR;kp;}m%j;*wwD;@qGmh*HXp
zD5bsnGVKFra|*y<H%oy&0#d;bz-%R6kw^&LgZI#zWVTEQypLP;%pwGy>f?KP??eNh
zKTDf>Vjj%>PJ_khz=``blrUlqxfw4>&|JhPqR<VA-|eWHYV%@km0239tx9Mnj-&gt
zHP<n80A*fam^rAB?0>2#Zg%}6JM<*Z%a5TDK~r?`l&ho%0|&+X>(gq^REU+uHyl`D
ztD^}sY^!?=f9nt2K))-ltS7R%Vz;pEtgx*Ob)S;eme<S&|K7+f+RVgbw#->KNsM=k
zu#E}<`TLXPKba4H8cpK3?qGO~u&uSejiLtR<~i$=rc?;QyL2vIjZVZ3bDH{yzC%C6
zU6-C5>1s}IQYuV_L->?z4v!kpuMxC`(5 at IWSgsJPHxDAr58_hP^sE+_)buPAZ<BW*
z9IIPs=;P=RFN at N8no(;K7dcvJj(h<3R<DMH#;ECuNqNAnT5zcNa~Fk at 2UlKxDmD#9
zVGu{if57q+`0Q at 38c+{j)Ci&F*Se%)E{cR!gSap&w7fSeZ4Qty$57pPEc(~@0df*;
z8x!jwIia(Eyoe5Nxgf8hQZa}2kxd0+Dp2o^1f2azf{e)o(hx%)2q*rBU2 at OKxGvc-
zfe+FtcyHbi%z|ig&gcNKg1;;i=aZniq=u_D1^ygM^MEu~?wKrTcsD>Lu~OZEVx{m*
zx25rOOZaBL$v;#lNmHk2mNgsiJE>>Gxm4yxUZ!~8pxoB7#?P(n|Iqd}a8Xt1<M_M*
z1B~7=!B8=&uq>*j(1I>1pde+~&?rcX+Ga#kTWa^JZK>EWEyHcLwryYfZne4PcWt+A
zZOfNlRFDF#c2}*;(k&{oGmRw*0t#_|&-0vnhZ(%EyPxm>??>j|`#k47=Q-z|=bYy}
z_nhbX^(kbxg7eF#g22rEPg&bXpVi)+rpr<`$<7-<x-P2DD^3m6Ie4KOepQj(WaT^f
zs%mytP;c0Ys=iQroYW3tD}eO74|@-ox<By~$WNf)UQ at X3v~0dVMYQ0L^cK8?YCB;)
zuk8xG^%9`<*52OujWsmsZZ#p4MyVduQq6HUeq&=#oIIxuw7Lf#nz(<6I<Gw$QRn-N
z>%8vmh&oG_?$0?>MW7RIqKR){{xgTWubj=hE*}lFE+mcS&E$_&eAp_u%fwl;^FhMd
z{L at 3$D*tq at K=;!sZZ_BXL(6g}$+57=lFhTD*x%KT?8ERpn^%D+7n|hO)Id8Y at M&aH
zR3?8r4ts(|Tih#O7d4B at qibeNlIJQu#MZ1a-zyg=J at s)g$oY1mTmC6py3m*?Azsi#
zb8YWn6(NtqX+3S09qLxp2-xg$vX1itFIT9k(92dfRa?eGJ2g9<)Gm{hfCIV1^Cn|;
zV1nW!Aepr>^Fr<$W-+_V72Yy;u6-lvy?<lhh at BI*Z#?|o5cUmj&G_j<|A94Q{^WD4
z8JT<joi$_9S_5l_Z8&QN%9C!*Sc<>Y$bRx>(n5>bNSlVUU$<%acVZ)wWkda4*tpR5
z7&k8b#yQBc(ecgyPnL~`2MS-W6+YIfSvGJ>Fnha{TQ(N=M_4vcl5pz%NWk?7Xidi-
z)W!pKE4D(ET|?;~uxl)(4*SOjasxq4RU~YSb+MNo)T|r4{esKUWJ0$v*H03BpQ5Fs
z$Sl;hpru0_Oq<El0ZfspV`m=yl4Be)y)^qO5#3ByCb)R`<$iuy!Y_C83pac0Oy>+;
zK%HUqPX`%2uz>$hj2?3}qeqc$^uThJc0Y}oej4I*qeqcu^l1M#Mh~pq&_<7<|I+B;
z;qw- at KN>x-lPf8HuE?U%0|6mR))C$4 at yx9LNTWyWP)3jG-hZa~ccP~1RqvHtUKNcV
zDj7YN4s at 7Xb)(19fsu1Uw9%s%jULZ%oe#NGh$vT0qD&vxI&fZ~`pEfMUV>M>Uy6Z3
z<!iWR&bQP?*G<Xm<8|_LC8)<NJbW6BDC&K}W4|FI%6v4UsGuA<aodBsOsJhnCY0yV
zgreTLZkAU?6N-AT;CnnK%ma7sB-HLk6Uwm!G`}o~u%G;r>?hb?&A~?p+fQ&v8Nz-N
z(NLXd2ka+#{r{Eygq8+F+fNqI8^R%tr3~0lR$v6tNCxhYwx9fcRoH$)M+_qDCn%o(
z-hL86I_0d+rfxr}{12GDd%()^_VD%-%=B;9^bwRt4N&$Z4C3{kX!}XC{C~Bd(Cas}
zpG0u9e!$9bIDQaEpY{y0pJ)`%wV&h+P<bN$KeV4j6tv<$v7h|6ZM~^G%BB-lpefpZ
za;r3y{e<#x<>=x!qU<MsvWI0<@Rh{r4X%>X$frWIpUmq2xAqffT(tcJg>aDl1m~VX
z_LGi5?BO9QU=IeYST!(ZK$_1rrL3|JYK>D}QA6c4D-BfAO)&69no=f(O)2Vwg717X
zrR+p`GBl<96OAaRaJfe#ZMdmEL5l at Vx6p{=;;@=a_`@sFc9oaT3)@v9crA*st6&?u
z_$blhLruxRu7Y3}d-Zj)tKb9KRjl47OK=u4*Ftuczv*U_x_)j~*{lN|AF!*$>UNdf
zShTAwj;z&9WLKdtP&6L|#h7znU{THV#j?GKs~H0(m6vCpYf^b)z at +js&7^X7?Lp~I
zZc<q~oJr-9|IDN^oH6D6NMi~h4t~Y+aWl$&ni*wtOn6GASFCAb^Z$)8CE{g1FxZ%~
z#yqHNmJc$fxX_p~XTXZ$h4tuoy{8W{q<HQNEsR<sB3(CIxJ|d7*anvt><Ej^zq6ir
z)+`CWi)It+Og`}k9|47<h<>BYCR~9%ww25#9YXC&Tg14LY(=w4Hc2ZsA!r8{Ygi=E
zbb_S0=_E*|6B<uI6*w}4>4a2);Y}wI74A6|X*x;ga#$2;I>8U;*vNNzVZpzQ)Z8oX
z(@Z8G&<nUvzMRY@@6d#d3aJtxYuyWt*2Y$=_C=9Ep(WgOauW?(2xnhhXVQFk`hP`9
za;c1)cp1|DgDBb>TW#)0k}TQSoMNUlqll*7KO)Quk@`=hSz***vjXokm%hf$3X6CP
z^$)6Q*oZQ~SMXC)L at Vyny6Sb<iq}vLkNrezMZeaHPBfdW=f(zTx6o963+so_<&-1)
zUfw1P8#f`s=4NAwb)IgJF@<W(7aoJnNRjWqJ)-Uljq9HAYDC?o*zRYLp4Z5v@*DGj
z>O7ryYi)cW9<&aIh81cjtLD0MW|U#YiiQ;{SJL}w5n03sme4(9SSd2g=Ax)dWNC(#
z*dooaLdh|BJo=ZTrd#UZbID~<8PA@;sb-``U);;hT+s%W at io(7HM!HIe;+|33y)K;
zwAaU?q2)?=3BjjLx^AY1)`iD?6kMoJv(?1rJgR$s2;Fb2Uo^df?c74P657x at hmCm@
zrx+RwcwUJ}#)dMRV@;uqs1c_2l?a<o1lfCD8D!HzErs1*7;V$Rcg1Zw*y5T^$4;+g
zx<Vg=$fk3Rm#h$G*~xyYgzW&U*Q?>w3H&<;H})Xau(9W%>0x7!<~vYn(AN2`jdY^1
z-z>*>)zkt>vz+Mdx5%kod9%#Y7>|W5g`^&{(!<IzPlebbrIxWdc<)k^i}}It1b%c`
z>4Al&TE_mk8xIQOxnO=Cn4hn&Xr7g6Ghr;)a`vx!e#Dt#<t(P{bal8<>hEt+00wVw
zzdW98s^@3?>+2)@00faq-;p(Taf0RwV4ari_HZ(`bRBetgGv*gdDgrabZ{n=IAIsC
z;cYcb&2IMHZe#;P2*h#E1`ap-sGsk{3JGk~K*145za84ftSaEO37B=W!iMmMEN$1_
zX0LR?X1g>_U1etvgOahK%F#_hCn_**fZbnY)6b&qXd4F%pLVHgl&f%hPg%I8{hEw8
z^qUF4IcuHdD*xqJG&{)?*?K=7`DS<c!=2*CYq at bqLC1RZ8v5OVRNf3$?vbGWrtEaf
zzWrzX&!hv*y1)$htvO?nVrtHq<x7<kXZL}wMzcJDUFheH8#_SW3gm+mfOglcY+ITn
zcq}lrn9A5YFVSw`G8X>`55Qjg6waI0u32%m8le^=9kY_BaKV00*1nwLBv2HgRN=`+
zmts|?#3?7$WD}mo+=mBfmqKdsq~ypZ)`VIYe&tBEVJCZrnuIdrKAJ1AQ3{>HBNyYh
zC12jxxYoo>I6~YB;#{AoY)z-cHD?mgC7CZ3o|IT?i+4 at 7NlLDFO{tsTSyyt}yENP6
zvEcsY&>Ue`ql>)|$H%Vgl>nBR at t(EBnbnX7!__03(7S>q;F|?-w~KxCSK3WRO8gU`
zX3SKHk<fUL+07HV*zSll_u9Bybx%y7q_fmx4g at d_u3E5KT5dJ@=+!(L6RZqy`v>UO
zSX);a@~HT*Qi=(hjyt2o7EiFzM;=53u(wzn{XXnFIa at KK@Msq<Bz9u`Vbb`!DS{^O
z5J9xLuyaHd;a4alrZfwWZXw+X>8nINh$gjMvt-M)$QKIRv$FPi`=O;9LDlyXGZz0=
zte-!CC2I+9Q3=NOVBoPTks1ls)L0G?wP<`wmw84kaQO+(eifBCmFsZC2XdnnI&-Kz
z;o&oQCdZD;t&#Pkd78R;!W3nsf0mFPJORBaYae#aZ0wpF>6;n$8IwQ2NpGeN`uNs!
zN}zB3fIa!WtgZ~|2mxO){E8(`(D+Bs%=bToFRkWmf}F_tXf}<=E2?wm6>aEON1IG5
zKT_IxmW+06 at 5%ff62$m5&Lo8s)0v5Nu~~Rjq;Js~G$4r3-ycS=&cR7x)-8hX at 6k--
z;V<tdY!Bd_bB<jWi(QP&&lI+gwti;)2j|}l{EstlMgBb_7FPLF6arhD&0CQK|E=;n
zt<4*D;%z_HY{!3Fv%Ada)(kzBMAZyKQwQfzN-pbH=v9&t7{EuZViDCkqg6{(enp*q
z`*~*S_11r2)kgA44OyMdFrck$$m%L9tDZjsU0Jt>Kp+DFB%9Gl2ftiOqpPeMBZ6v@
zd06}mR4+}6sP0gWW>=tgDrPon0Lfw9iV4Nf*1s2W at L7|0ZGbFNsG=EKrL*<sNJQ0U
z2JnJ8ODX06rckG3hsh at MHuY|rMV*-PM$`Aw9Ac91@$RHF(v_Z=#W^H`auU1L8=gCV
z<i+^pp&6QZW_i)Td$nE{9L)11fxnoV>~VCaJe_^>Fy>Fi{3jmP{R at R03NeyFLJ`(R
zzMo3Ia-G$iamGLLTEvY1D$mP)`*7rp|K#8q|4}X3if}S^@2dZ7#_!!eXvWu$54hRA
z+>nMd|M~3v0m>7#`WR>c%U;tpfSEf6-1p4qlQ(F^f#Tgo-ZNuYTfGfw!nTCK1G@{n
zDn2%%hku*cD1EvlqjB-M-s^g=qek%^kuPSCZV1o3emUBA9Tcjr53R=!T)r+jo!vH&
zbTK523Wdtk-h$Ck)+Cwa#4<N4QOVKW)ft}wv$iZKxYWh=zKBjmka>E1{Y9G8i$HC&
zi9OQC89hqN5{)qTZWlh`p4E^OgZ{kbOYwW+`Rs$5FgN=pRV4;0o6xsmTV?P7YR;PX
zJN%BJdB5Y$0B~%D)7Ro6q0p|Bv at 3os2v`0jJe?TDK!h_rJ2}O!sL)7NqZ<x{PWcmR
z;)9_VL_$4g1SOse>Ul8|WT9>Q=YkGKfourceJ<#wNKiFyiAU(K4WTtr+3g7W$+ at 6g
zqd at 3Sh|NA1G$pEpIKBRcP<s@#T!Wt4Yy>?T1wCJbHXA~>L_$4j2zusRP<<q52ew5O
z^rrC*-G>MBxpcD@$0WYWyVkx$vY;F5yuqoiA2yZV6O#U;RNwz`m{ibhH}190G@&Ck
zkVnws{gs{m${v4ZdkD>sY0}yH*xcKsD{@y#7v-*&&S$T#4a>)t737z{2qx?|&7ib|
z61^pT=1}~b at n{1o>9b_*%P*>rEvFso=o;vO^>5&z8s9#lHU$qB?`oi9<oLx>TJL3P
z++V+!B}%sxOEbMJMY__<5~K^g%*OXkkxyuh$=XubL)N_aoWUlzCVn2ok3L;Zd3>qu
zeJ?NgXG+#i2Zx^`B<LEC(-_$2{i@&F+UI at GlGp-OCO6yOwLK<T3e!ys-RouZq+7jg
zq*PceWg=6_UKT6(EO@}Q$<$yn$%ToZhGtWYCvn3aeJU)=G+%_Fs|h+Oetw at 0nW*I%
zwc$M+3qryUJOb-GEZMU5g)E7Oi at 0&16-Sk|?V#r(tNJ_eSj(#4ehKEC?!W17a at TpA
ztvb49`ZW1oEoDsg-j^_b*PX9~qnmk~W1vuz%@ms9u~+XWba5owj%bT1l;(-6K1%4z
z!ss#H<~T%~O#`Kwr1RLH9}M?{&G*49mRen7=3n&-9T;NT#TsAM9O6qj+g`+7wxFA)
zl0JX2BWs_(*ygwUi{XE&QsVFzJIQA<%&>cLhJD~Kctnj3R(Z_qioftfYEh at E-i<s}
zl_D)fHzlx!m5X1*7RCr<KX`kbtIrD*IbCe>OPcxYNj(>xjJkC?MPtwoUeT#6hpUXe
zLg1p%FEHeGTj+LAHd{_nLPyYXHrp#=lQfq+_e7t6;~snnCXdE5aN?ARGjO5t;e@}{
z56UUITk!1I5{K9;joEOggPcVyvH6$S{S*C5QoT1j!xMNScHS2D!b>=RQ?sOF5a6cw
z-^U<z^U|Hltn?)1ru3Bgx4246t6in}y3ZcINPpWuE8V`#KM5g_G*ek%htyYOja8OA
zy#4)>2sEa6&-TNdd1}>Ffhns3i(YjqiSV+#586!f`xM_ at nQ3Q#fZp*s9R`Mn*We+v
zW!YooR at eJ>$`bUqivD-=ZRovW2kl+Vg7WN2u{~=q+jNBrBTsdTy4;~IcdE;i!hU2a
z4OGK#*@2#Vo8|)<yK<SjB2`_HqOO?ClC^|;Y^M2T<!<HMtOn>J2eZ1eRQ13 at at!&c
za#Cr8mQlChQWdcK0I#aYcqBiM>6Yp)XqHk|x8GzUCyw)#d(!Q<l&VsC65Fax>3i%Z
zZFEe-h$Q8nxQeWXz}mKsKQ94AKu%^auL*blKi at -U3z*I+@^V`lD5m~G27=%(Y(<rz
zu+`O4*oJCEOX2YX%yM)GeN|FR+LZP+cBQbj8Cq}zCiH-2xtF}jHtXlOA`Wx1JE{K8
z at YtOOoMj#4y!q$1B75_ZJz;=7ht3|b6+niZ8Z$sr<HzNn&mgxt-ww3Hr8-D6;ipdn
zQRNOg`MP`%Qp-pOPv;Ghk&xF7t_{X&gbFoOV09{?Iysd|atg~|9j?vvySa^shVivd
zoU%Y{#)=(K>2U+e&gaQOca!!8y0O@^+UiFajH%QHDO%0(Rmsc+Lkh3Fzc5Mckfw at F
z4_yQ=XALN!t#v7(QTS%utN{HRlJzkL2C<L;ieqJ4-J<EL at Jxf3Sr&&w=mAxaX;34L
zrMjm08XmCnQ`J0S%DD%LPxKq4#0Ys%#p_mut2o7 at ozLbcS-G#M)gxF^I7#U0Ncv^`
zpztpSs5i%&&~fQ#_JypUtz at 6wMN}788r6iYP$N$nd)Fo*PtVI?o}Rl)<H at a5I%zcl
zO93b7_|6>JA)g1T0-DQ#S<T0~lU0Q?(^pGYCZl;dl`}5(uDV>wp6S+DKSbUzQjq7_
z>`F-J&Av#kU>D2eJJO}3lxqq9!V@;nnyyj}$3p9=pxK|1c%Dh at goJKfL#faV<F#gR
zvQMROGkjdFh9h3;Zweb?;9apZyde!6ig)ize)tbwIi>9DGf1hOP)=qAQn-O<0AIng
z*!R&^E7YDa;qh3(_YGbxQX)Tq8azxZP&3@}v#;@GZ0=Kd$~i_s7ij9L6m^xojG4(A
z&R*tIJ%x!9Y8A|jwmu9a&{gDkSS~FizhKn!Gt1a}{JvjGFE3-e-~raIW!mDEy$sLZ
z)`=Ck5iqV|iFU}fKF^l^aPGr$+=jUhQ<}-NVO<KI-;|TF8g^;qi=djA<hYii6jX_n
zk?LF<ZL%C0N+REStxj))Grq`yr?`3V1T}`Ck}z)*OpAZ at qIGr+48CJ1tnB^}j3IeV
z${kFfI2)mg>?e at 6i9Jk-AA-adb${?R{H$)Tw!aOu?0{FN)>t9}&J0BlRABY}>MiB@
zTFm<AG1ovioLYE#z7BsL#h=G5=*l1Tn#owq#uxCocsaZE1%6H(PjgS$g;~_8wc*0)
zM0G3rO9_qNRY%CWK}d9PDz-=t4BHdOcGi%uoCr+;{hW>j#cLdv*82zUrnU{zsyN)W
z!K{(TDu4-$F0P;K9r4;<K>N#a*(5<Zd3Tq?D%-sc4zYRV at w@jqtR?ovV&nZWh_>Jc
zTXpKAVV;`UWVARmENkMXhlZtC<6^AwU!R9(m_}i+Mw3au4LU9^5c;h`?J+V)FA+Z%
zYFlVCW3o_7-#&ZC2(?@3CRV6 at iEacQpVQk5UB=sMlj6O-iGmNKiL$H>s>&_Szk<iz
z7{@(l-6Hu?b?O$lWm})cwk}$P9b7^!mB8gL)_DO<`0A=f$_K2gU(*mvQOyCp6y|3<
z#%&R5 at mz(s!4{f;0TCM<N;0<7-3J}kvPFS4ed1Zci-HC^=;uLPcEL3M;2$)Ljrh3~
z1J#nJd#61Kt!0v at dd$_gFTk$TlZoFA^3lJie*_{!W7(a{$vXu%fx-K1B{d6Lt|_BM
zdH at ze(kL&Bm*&D!M4DVI_)ttE-vdr|-O_z!TE|30=(a(f2NKNH6Cfg#r%ru*P=YJ<
z1c(St9Mm@<fkRJ#2)*Bpq=i%~ta6mXwoo>_ZfJ`2&r#p&HB0H<UaK_G+dD!U2d{G-
zw9BY<PIlXU1NNWWY2amz8_^#@T6Hz{pZhk39V{Fsn_J at gIa0FH<grv_G)fo2pB?_-
zUY^M=Ur%Ry*B*xHB?&c!c^Ci;S=@*}q50}+eAS8QJ0h^$uEd5)@uZX>U4spJVKFRh
z4&EDP=bt}@h0W``un{*>OO7E~+(?a<unU`J<KvdF^KF;jKCM{|&<bXu_7KWpVXGYH
zv9f0u;uoJbjLp3mTO_LimY&#|6QD-eM{M$V<>saSk`Mi}mjYa#uH3xLU$Vbt_OeHL
zx0kO_Mr?+T=Px;`jCcudtn`>ua&+xjrQ|4xs8YVjKWmg-Ej$|f7yHvgkwZeVMq{G7
zdYN0D-&zqG3yrC)Jq&|_Ny7K^F-l1j;iB0Zh2C*FPq9kje*f%cSq<!h=WrFG4|%_}
zgu|7TmZ?*J8}2MhJ9jQKhW+#>dOVdiw~<F?IzW?VDhILkVTj%8o|kZ+TYDxpVISow
z3g?-{^E`s-+8`aYb-MPMNuJCufON`K{xMfQ<YMpNL#{vBNXUiHZ{c(3Cb!mSl^zy=
z<!gC0@~IqFlRGmp_Rc~n9-~JkFUZ6=W$5Jk5O9&i8t&0Q#j~yVpgEa;{|yJkecTke
zeIKK9Q)tg}Wo?R|f<+2GoT<H=FbJfHOl5&*(A|jgUMbfGT<oToaDxCYm%HR2bMg1~
z{8V03R;K9-Tagf(L|-eDc<fG?p%xUCx!Cysp&cz1z9Ukxx)m}0tyq*hD(km at 4woQ}
z!>~MUPeH=CEc!YwUzoF#LR7}NS=}W5l{@TAsN({1CNx(qbwg>v1l at ho=z%=*CQ*+L
zy;qL^*yT&mis7)x#mdy<ILbA+T&QfvAv=eZ!@%hU9*djZ_LP2PLmKIJY3yR7zouTt
zOh6O;(gtaT0qU*btHQfYSRML|$pdi~CSi~XSX4vaWGoHG at LUx?sA7V;xFDY63wPD0
zBf6@)jJs?rhh;Ka1P-ZF`%<w>_$&K>&vvmxcz6R2!2KD$f!Q{1k8P#wW}p5EW2wS(
zg?RY>;vM8`_wfA|rODbPHmwv~7-Z;!-*V^3@|eI(CqSnYbf*TDe$=R1T!AS&v at w(l
zm+i_ld{RHANLOX*$IlZpg?8TGXnj%Uv3b(iWkg45FN?@eiJ|wzcv2QDZt`9NjlLLN
zxzynpn(;LBfE(ti6!(&1di5LoZJGTvYDtsl>B5a^x2q~SIqp7OK at q~rb}ZjrVA_R0
z<w}p(e7`_$he4t8w%Ek}l_!@hrc`S%)tY~ksvK75+cRm0D^|t-GrWfsUUl-yW4a$=
zJ>J8Pl3UTVYL at r`pZr{F<A!WkAx8DdI{12`8Ii>)!jpTHJy8Ko!U|4tu63`lJwM4^
zCTw33n{}`}Fw33-0x=#|BucSEJhL)hSzxz*BKEFKDDXB+77wjt)b`QwQMl>1zj`yY
zE%%MQ5v?CC?{WKpL*$;UcU)oD$9~ct at vhor$}_RcX)T3;J>~&lS0c>CF)qT`=>vXV
zdLx_Iz2Dnv*4|TOOcfqPL at 7M3*s~69$cZtT8mQ(Gnkt6sJSRigjmw5?iaBz*ca763
zrz?3$)6!yoIaW%Zb|GFyPP+&%annqBPnqQyR at aI2(DqV&{Ku%i>?bGGO-f@~j#C-|
zYEj at 790@^NJh7n>?@(K`0nUP{XidZFSL=$}HK=6GU8KynD~;tkf!B#Zi%wu5KRL*A
z*?k9T7YWAY at t%#59T*V-^w?k<0bs(#r4J}=Ze{UO|J<btXlrNef)7v4c+xABb&I^q
za_lB=qhrGvr2o)&ib+|wY}(JE>E!s9qGh-vAhd4U<N7noe(2t5ztEp?7f)#Mv|sAa
zK75`#EucT6HWr#b?J at lsr>oFa)1J_u>+$)5X<IGYGfsP<k<(toXITF%!yrEDs%0L#
zda%O3ZdoV}D_DvTi<d5pjD4~L-yD9h8bQIIp6%z~k9b5(l&PF)Hnc&;u#y!xHMVPG
z0|l0^kIhY6ZLe*RuJWl;dhSJXeAYf6ZfQ}@&_?Ql&3prixu_`g0VIth+q8UoiP8)M
z3lT=j9WXA#`1yVp2zVBHW5&QJK at 7Q^J54grE at P{nL at i5-HB<I)J+|59?7m;}fMNb=
z7$pwMe~(jehqB68A!MkTKCL3Kz${(lF}qp*FT?Z0j54>2-SULCMPHr`Lxi=XX1Yn<
zs}ccr0Co9Ecx!@Lqa~&Xs!SnK8Y&jTIHJX_`!l85OsV#&p*G!9|C$AQm~NaSc65c~
z*p at 0KPIp#AnLkcBrObD<pbZpsI=d8)x at e)@<{u4{e$DiYFou0jVc)A42~Rc at p+Bfx
zHO_ZXve(DfSql8~9rbkPtBAGzFK^w^Y8-_aPJsSeAFCER>dZw at 02Ehy1k};BeJ1(E
zn%*=irlvPu{yk8#H5aH94;X4K)CPeKe36nZH(rh{3U$m4eMN}<q=VZ{z+fR~(5afU
zj?Bc*3`O}h(-%o+klRaer_ at 9&Msm>Ut&8Xk*a$S5LNzD|V&8$FZ=ZDD4OF;gQ2|tF
zpL`PQ0xwjWPdwUzg*mzL(rlR1rwO|nT#)!;rf%Yu98n(&)#H^@;|6LP8o`cgNvwbX
z)O<%#und)&gHl|x#e^+}8Jxk9Dur!Yyb#lZzNnhRK@%Jl|0idH*42Lunmdp9`y9;i
zW$wBOFIZ6zeG+tnjVJ;BsXKU(#W<*2c8YBE%Y7KVu&~GFb_dpWGIWNDU!LD~Oj9vn
z;*Cm4r}vC{e}U4|_>CoC6U4 at q*Sgpp7yz`rLhO(()3RIp%gd0!z8`b~#m_&DK^&((
z*M*~G$g0PL46_b%cN at kFIGoibenuM-R#)X at NluK&nUg8^XxH{~Wg2eVC at U+=Xev9<
zljm}mmH7)hK}#rvSyjq*u|tp1T;2yym!rPe1G+{hq*6ZyL2;nov2{H6*ydJ~8I}pX
zGhVw7YZltqK%Be0cl1z4bC>U)do1rwP}EgbY>`Iznxy#d{m<7zlF%JxSZ_6X4eHZ!
zUzXeh6FAa?#jE2QemzRhFb6`qRw}nMtFS$*UF??QcHIn=Lrz}@h94O*YPQML*y>Dd
z_furA?nC~mSPB_cy^}s1KhvbyS3C*)i}@|%BEP<))mcL<8y9I+t_(Kox?g4RfPSl|
z{p0_V>FZn~uM@&KFj?}BR+%J&E+;#4D#@HlY612p^o7~GdNljZQhmAdt9cYM@?V(6
zR+kbwsLXeYAJFY5-nB`pvR59hv}c^EPpET at DY*VU>7twEj?e at OE15L1ZdCsDA4v9_
zr5Lp&N&X&*Sn9@#y|RLNWdY>K<EmR^R~H0H!%blmmJWoSd>HhTdFeL%c+$OxLLTNS
zmg~*(RS6B!CD-3(mM0~&NfR2G^ZI;?JQjeXuD{JHJH3rI?;cx1n|x4#dA{lK at eK!B
zy$$B3?mhGcC#Bxv-D3ta-*_9%km+dm9yCu$FH|XjK>GgxXfx7(2k7tgHd;b;yjM-b
zq1dDam8G73J1qL- at jPs><YsXTDH`{UJO!v at c{G4skFVnDpW|n at p3tQ(b_w2!Evv>V
zu{F8b)8tX*^qsNtR_$A*B<K-oKhPp?#s+3(n?s$tYsvPkBVva<nw?mzzo+kRq4zWs
zL#JMVuM%GE>NtFF4*4)VTk29UTmj2cRUUp-`cXN1HlV6`75-R^ahfI;I#$^|7cHR9
zP_9{r|D@>i6xOzl#~)3;MW15IFdA-`h{pG2VOD<3S-BZmxei3x;?Klr$NzGp- at jM;
zX^AI(Ce3lP3!wbKax<>sR=t1$SF%*@0rPy8yg0m6O<0UeRr)H1%eM2wERBE?K$<NW
z4mk8VU$8w;3cTT`S6nRgKZcqf%yGi68fXE$yE1GNd8-t0p&7f>_3%ouuHyr=!MYjO
z2hxY0I9BtRX8J<x*&mG88J|Cf7M?iv<DY9DCmEJp3s3+~e~f~5;rHGKWvyN8MIW+F
zz{s_gdTUJqKKyc9$m5>~(jdMk#phHySI3L*$q8^HV}Nj6HNh)<7my%5xL at oi$P7hN
z&n#ny(c at g6AKtiAx=<{1u8MCdY$FeoW6HRJo_*z~HiM#5{FUJ<jMl1<idEpR_Ielb
z{i}dh8T&g>ne9I(;0mlEez(>tqdCn at Vs|alD|4rdS4Q$*rxZH)yN~dl`w{lQS16R^
zVdw!Lxml_b?g7#txcMGB0rh~<i^4s?z6g5&ZVelcJs?@D4J`Jt6zT!~wdYi;5cqB4
zz2f$psRp|qjfjVJQ$$D)+B9M>_g8)h&Ev0Z^;g2e`KVuh&0o1AXK|8HJJyP!ZEQIy
za+*unUX)pFbHXYqQ1}|?au}Y4wg(8lcP$hmd88lrMDE6Y1m*t157|t7Hp6Wj%hqpO
z*_Cul-=h76huH;Gt8{<i(VWT;h1&HN3S=kLuEMR at O+xLx1ZWj%@1UE*LhT~ll3Ms7
zhW}Mcj at H@idDBo)eCSl55EfsnY%nit+di+st*C2RjPSF`7Tm{G$oz%-y*=i2S7ldz
zFI^TWJW+3lu{%xJwni1U?F%IWy=I#L&-U5knRO>&3eR4k%AZ2By4^rI2FrnE9&MC3
z>Mv|S9d}hMzQ8n}wn;`QX;li3V(Q)K(6f9)BQ8Qp%k#8+tCHMo48;;p$1IOg^rpi^
z9TS$jAU7qpXo-WiaN-|R;x=V%YoHE~BxN1+uHA30@{dyHANH5L9e4~)Q*}$$*WJ3l
zZmhrLtw22j{3Uzq#;%)>RdxkRPWVgO>PNx!G)vfa1JwGUzob=scm3qRqs7Qy$f}gQ
zuNJnxf%_PMGE4*hlJ}L8Hep+QPD$&!FW{D7ZP^v7ysaA92-G37rJz^E!K+;#_!%`*
zIV+1pW$G|M>JS16W+CK}2HI$l4zfK56pQ2hFh`#92)dlU5(&E4+vj0I+$pphtB}#+
zVy_TrzxMPzMy}q5l-O_2BaH#N1a}wWrvjA12LB^_>E>-ekyZ-d@)Jp=aIc>Tp)vH4
zm*_+CQC4~$3TRX4K2`pZ%|h~W8_T6 at E1N>s!|aOla90bIHZ$}duLw>$S}pv~BEbJF
z7S=*#?|8WY?y$_fSMd%DZFmjuuvEUf37hF|N<=dqd#)PlxmU@*M~vD0T>+j6OkNs-
zCMsPHD)NLXJRpym!>SFmU2J9W9h~4y997xG77j<`@E!OK&DO-G4wve0l*-=3gyB*>
zdIx?iazuxldY^WJ+?4K2+zY=BIUb&E-Cyi+n%v!AD2EZ-y(~S+%J06gey|Wwx{XM4
zfghWPVeM~#3T8AGS4Qi%{J6^e6dpeGgLM;eSJJyTWT!~>JeWbcy!%vT4`dVftTpHP
z3t{l@$*D}26S?!-Je$8TU70$W%pW<GlR>oQ6d0*-hlTAO{vkk4R}bNLh;~rg&|+~5
zfY;6Rv}PS#(B19rv8=o<Fl&Z=8h-c$y>Tt*tjgQa6H;4D at 59>;jdHOEov7 at 9!rfx}
z*T3-VlO2@)kkwz=nN!&*y#$&@C;ym?`#saqXe!jUVxOG)A!yoeH%~y{nGfMg0fxdx
zK);Sf`bwOzaw$wh;7caHt?sesIpe938G~q$P}cT{z3U1hn7<a87aLcPVNGL!^FC0E
zs$1fab8m}1G|t6#34 at vEhpZss3|OB)5$zGBfaZ3Q+nrOHCfnTZP^>Da(H?-FayQnD
zHmySq%GruEpbGg|bsDX*Dgt-3p;4=(FYE7Yu00}}9&R7Sy|{PbCUki+tU!>GMt9%~
zyo-HJAL-MLcIK9rM$dHR)C*E0dqL_zFG#~)kVL(}InWDIu@^uWKrL|ny4($FyQ;2V
zJtgwpZ%8@!-LD^cPV=G3{EdKZhRb7ev%kd9OkS=T_^}71QZtT%+PP3+RFn79XOtc{
z6DR78bv)cy7seShR&D||RysA-pk at luZiiH(X2PYcuzf*6nQ~ItUOdZR(g&(N#Vb4<
zXQGuP%-Wrx1h_m`y90%t9y5&2$55LN6xm&#YjoHafF<@|96V2!4trXIIbEJ9I;`#(
zvf at H;lFKty2d~hQrno%U>aa?Hm3gjn1DpeH(h{Y)JeTW<vIpp;yF3|gexit7s3o23
z@?4=O9ihRlaCxrOVQ0SPuuPZdDjoLq*I|-VT%I54;D2aIQ(c}+9rlI>%XWEY>9GIR
zV7V?&p$>aufMlM_Q>23*)RN9}d1mXdJ2hCb%Tuhw+#2jAm*)l at He-OK%jLOI2T#_L
z&U1O@=&&RWw!r1NNr#y<*dmvwM28)33zJ;x^32u2AGPtM%UqtDby%YYt9E&^b=Y4t
z*gY;!jt+ZjfaG$Q=XxFdu$EMEc|;v{uLfJ=^5p8UTQ%52F3&U_Rum at r2<iqd&vYGg
z1yB7*ErDm~;A9P4N8mgi-2W8^KT6<y9sJE#Ve*d?ra;I1UCZz!foJOAZ5sHu1fHye
zf3Ja`Ch%q9{y#weIl at d-<vtB}kCx>HLZl5K+!_MUhq<b)<bF%XU8mu;5H5ZI2Wr%K
z!r_MLw_RM*2|V%^5$CdOaj~8+dG-bZU!#M+(7<mKI7<h=tAY0tc!~~w^~-Rj-Y3jd
z9rKiyVLySd)xi&I;2i|MP6ywufe#b-aveNxfc#OyWayadwG6EUzCs6ItbyAIe5DR{
zXkbR*t90<`FT&)H6Xr)c=ExU3!-oXU)WL6S;C2Gf(!qbxz?}px)WN?VAm2lnA|3OP
zmZ6Wpvvu$t8kp2*Z4dzPTn%g^@C`cnx&iWb!rZ81CTJNP1fHXVV>Pgoz&GjO6RjMa
zMBow~e7H4CK7}xIb<8d;Ln?u9cJo85?2j5ajlkJ@>c=&3I)QU^@B;(nClls+9kWEs
za0P)y9bBw|GYOolgRj=WQwTgw2ag*dpKTr(D*$8CGUS>E#tHxjKj+{)^T1dE;DZ`?
zmU&>T0PvfihshV42gVA(Y}7K`WF8nR09>zuUFLzY0>Jlc;CW^~R(LE60RxNdTL%hQ
zV2&6q05wC)v&bAVSOEOe&oKhpQh=7}BLz*MfN~JE+{BgvlQG|>DAeALhgw(J*c?zz
z at c8&lx;mIhS0~G&YZA+#YYMv<uh+6vdQ4+UbWLXtx=v;`x?aKhY<SINophbTj?*=j
zwb3=39i?k7`_P7*<*BRk*ggWyVvTeyX0OxrCiV(lUF=1=&SM+tx_~`J*G23XbY05)
zbX~?a(6yR9K-YWN3c4<5chOa1x6ySCtDx&ctW;xR8%`>0CPKI2M8dM^7AFsOCEenL
z!7id(oFUlxbc?eBbI>i$1k6mgIQp|LE8gO8&q8#I13YV`TO88aM|6uLGkez>UfAxY
zTO5JeYjlgFE_;z~ahPS#S~Zq&bY+hd0!LKlqgxzB*-z;fhfQ`L-QrNmmeDN^kF0`j
zaY$ry>Gn9)pKd>-`qOPY)t_!Vss41^L-nWIKB_<6;=sksbc=%(>$2c2j!rCO(OAYo
ziT#TZI1sUebc=%zYoS{lZP;6Miz5tsg>G?FVgF0FIFhj6(Jc-g>~Xrq;ez?-7KaG-
zQ at X`rf!#;9I1aF7bc?djD(DvFoz10NlyNqbZc(UNw$3ujGP|4*D8FnX-J;C0B)UZr
zW$|>2Qpx(wc#ERQI?S|3SpWV at agx02(oE%VR>N9aDyUwD`wq=aSjE4u`c!TMy+LVK
z{>g6X<iQKe+3Y at 5EoYm|bcXV?mY=<**%3k(rB|VO3f3KtnAd3i!mSd!J|sH>8Mv=G
zm_155-(6O3&dq$tnVYlTaYbgGIX`=p{N3V(O}V1nsWjFvFxREzWjp1r&^HldgjAu#
ziZO>z0Jm{4!y*Stkxh&_szF9^h+T|n)gY>gAemx}y`4k8Bgm>L;#3Dg%GeQvM4m;}
zT~NsF{<WPs>r&<9oOLO()4#UQzqaR1EIxP#HkAt+>r07moDx6BxWsuu3LZ&f<VmVf
zdOfy|P3!>)cOO>Z61qi>cQX$b7&-u at __Kk$Q2U9AjF+X7_7Sc{9+%Zs<YxIMTu$|{
z91}m#5yXDs&la|?n(p?DEQ4hhYG1E^LQA2UusjlU*rrctWS$AjBc~4gg$9Fl2G0wl
z{@PFU!F}cwJv)G_2%MDIA_;B^99H4|hZ?*a4LmdLq4VnPHD at v(I<MwT&iWBG!OS{)
zUQM=14u+=JoDt;?rM-Txxo%_;epx>q`g$WanBTe)Uy^^OZDT84?Hloh_-AHr#MgjL
zJ97%G3MsmCp5F{>Oy54q0ymFfKT at V~6P;vrsUIt(XJWup7k!>gQMVz0jaK{h5zG#^
z&|rmqexALs$4{C3&%UL1#C`vljwsZAYoaamVoaOX(|*<8k3G#P#xM=y<&Y#X=C}q~
z!67MPOuGhI!Xc?*Os57Z;gB>jrbmN_9Fi`^^l6aGI3!z)acaH#d=AMKW0EvT42R^2
zF)13P;|GGw5 at S*|$QK+^EXJg1kbe?n)lK5mbWJ*TBE(2K;FW0tl7a$~8Z99EEt-Hd
zu80;8!AgDojumQzL at dBULaitcDMIZOZp$xN5f+D0ZZ`FYev*YNDd|Cyg6zOdSnDV2
z9em3nE(oyJPtsveAL5-J7W!j!Se*ugh5q?EOga=61Xx_B=-^5%DJ=J0I_w4w25bFN
z9X3^i!CHSD!C>Wc;Q-0YT%NII9ut1XW(iu-%Uzy%deW|sI4r~EnXkjX)L>V*JY_oU
zA0LHDUg`3b>)`EL(yLsaTXfj-8tg|dk6VX5ropoHMgviQaDZg4-fjS1rX|hO+YMkY
z4K_<}H-P18uwuP|05*Am<V|`T0eI9$`k<2TW*8{i&6f7^m%4ziear<{bWiyKg}zN4
zdZbA+8fjp}-G!Y`>FwBr7PdO_;u`Ny)b4Ju;gCDWra!{Hp6G^5|C~(C?Q0$mL@*pd
zZ-s7d#wckqc;FPqBGhcemaw&*k3;~tc;F*KiZ%rK&f;i91Jh5>hDW0vLykr)qZH~~
ze2+Lnvv7|f3wJSExc at X)RX0usfo$5CiN8#B4Py^~Xf7J)QBiBscg-m!_OfyqP_<K2
zqgiI2{^9VdDfG=aUzzXp9h765&8E;7%1Jz+Yb&~0?)ItD at r+aTmO9&*f?61VZ<afN
zz$i$@j?Wm_FtCGvEswCj<5;QfjDmm4d`I90Q at tgjL5lb8F$;gTrH4+U{;^L5xVO<<
zA4{lav+%qv{r>NjM(^8ci^KjE+*wERaw;7U6+tZ;r0Ghb!`k#z#va-kexN^)+pb=x
z6gt&RcF!(t&uoHH;`FxI{5he-2V&>?Wk<*wSZo$69qV>2S)8 at c*C0IExKL at VY}zo_
zjtZih{61Pci&FhXDVp&X^bHrb!<_2pcH)8NZ$Hy^-d<n*Gyy)*0P+M}clNoe6HTTx
zb#<z~g%}OwefyfqnD1YFBnzF;655<m3DLN_uZi|T{asCNhmI7kc@@06DzUB(3dH at 5
z7H?0|$`BpC*EZ^9b%oLb`M)p7jaeO2)A&g!A&|ct?yWVAXM|mi)~<lmzP~=9cAxwy
zZoSKDs81-UIg|fTOwE~F*V$`=x7DDVj=T`l2l$5uOxC#l+|GW9-RWbcojpby7(8nN
zg|#l;^KnP-q?mS9jj`ZI*>W{`FRxGhg=9d=3*}>CZQZf|Ev>mOC}$U_+^^th at 6R!z
z&A$sJ!@rAWYs%ZmEVOG?cb at V}d%wC*KWJ21rnK{>RGKHLFr!q%D at +@K_Hb8ZqlPXM
z<v!^`+6pordX17<t{h_B{kZF}hmFN8{bJ7&=@2yN;(Z1!;O0&6cnLN^U<<9J&|RxC
z0V^7AjH0A-TH*uTH|4G3drNOe&jr{Ju)2NsP2LKE54Sn$1e`>`f&|QA0 at 7~EbS?X}
zmPdAAZ^h8->rz6ubQRex^39-xK*}pzTGDsD`l<V|>b2gvc8h;qD$B$us$!8tz7R8}
zDrNSrJ!Uznoc-np{u<)F at 0$H(c1WwtweP?%L>KQB_X at SY|9313wJGo>wX#pVL3=Kc
z(M(_zzsQ0zp0n5~C5*rog1^WfD$ZH#ka8jM(;khdAC-B`p$U*mo`Sd^X~h2UhTdDs
z+)4|mGn()TNEuH`Eym4v>r$YE$gV=4F at 4`h^c90H-7qKOeeURs=+*|c)cbVog+=zf
z&?1dJtIl3RPLWf-8tX98yUuBnGrj8^Ch2l5+0oavWMj)*P>UHqXthXyS7QV2vBje+
zfPMX)?>PV1U!=Rp88C&7^_cUj8z0SwhD=hE-v+jz3)o~EcC#iZ?1sD0j9{bG<3Woq
za<Xgn+~XU(RVk)CWU-<G@=Gxu%YsmxGKK|vX){Dq0O>k7UEqm_^-g>d-=bvO95+zR
zm(^jKc|giJK<Zge>dD6<NJX%yEj!Cu-i^>_c05gUp`E(*%`^y;BMyI at w;?aE#OAk3
z$@mr4>Gq7N-v3sCiJjn{%#}Fropu~v7b3b$vEtDWyp317*=h9J83#9R+ylSfZW4TG
zK`Hm-RquTRH}C4+(4{J6yzdBP6nVzCFyk$7GY&Gsnir9oh|F-a_B##U!EF5<%!Ue%
zMV3ONTV_X2CbLugvr~zO+7Q-NwkyqER at 432_^ylF*>BEJI0e3(cn|O!`q>ZYw0}3<
z2kHJ*6K)!5hC!`I+fah11UzPSb&8tYpdD19FRX=Fr_oi)%_&uWJ6uw${Kb|k|8kpB
z>4d6OD^sx_zn)~r0}ggMt@;I+QapLE$h<>ukqP=v=9e?zJ?6QqQ39|e{4RKfCl9s3
zY74>mx55-pg2(9%)u6KuR#`(E9<^OlwA6<ri8R;#zA-Q>UTqS#nS^ce8I94<DkZi`
zG)q?t+eQi78Z!1sLe at dV?g`8~4;_S#6SftZg>5&OA>+u%jHunjLe4vf%IV at cOU>t^
zrUJ?WD2s7<Rw&PERGx|(?}BsD+n`yrNUMZx?ZP%oM!PgRs{vl*?;8TMOz834*BOU?
zU{^r#1!e>EM;r|-6d2{+#?in=ffdk+I$AQJvPP#FU;;r8 at cA~ez$UFGJ_>9Gr0(XV
zVgMaufWC>NV*wp&fWDHW;{Y8uBqMfW#4Z-tbw=z4q`r(LQt^O}H$XRWbON9g4A3ud
zbRwV=hhzl9c`Er1vB04-;xHgp!AXq(^aum=^&CAC&?61d<2hOYv at j$iUFfGg-zgS2
zbw->9r1r-UDd at ZfqYTimaP)bAKF<LC1V at hs^yncO`3W(SBo-v;j3gP5n$1Zi13K9N
zJ(;7&0D6o8I-aA?2lV+vGSY at 3lb<3Mr09&K7?9d!BT{1lJ=OsIdyWPPEf{BjuHoqM
zfF3_2BMXU<RIwmcXC&2t)KpGt0-z at tpvQ3Z1%ST50NrgR^h7{U9FmcP=<%~L&ATVf
zdm_!NrU~8`Vg9uK)B3SjohbYa9gnK%J74}|KCs&+7PLugfLt4pZ8Ip*$4mSgl6-A|
zuHxupfIepQ{yF*^Kz}nNzZaoX(R?NrFumcJ0jWL<kqQDjXn_6~M}G_GZ;jqRM~46%
z8j=z6uA6^cEI6(+a@>H_{hZWyfd0+^J&&Wm2lV$w at 1LVj0Q$s`j5vvrcCnycXQbVL
z)VF3LbrR4g4bbm#^eI4}GC;q?(H(&97?P2nq18FRQ!MDz8R;}2bsHyj8qlW=&;=ab
z1?VmV^u-+A4e0J686hwA`8{GmkIqPs0V(_{1f<RY`iuekb&fs@=(7gs|KaFfK=%&8
zi2Q((-zOIINq2E3`XHSUMMf?M5<dXyhjUT6fa(WS|GB6Og>Ct&u<b?_bORwmH_(bD
z#ivQh|4J<QO1hhu{nfctj-U{uFrSNRh!EmIs7(<9Y*^`9CI1_-;2RnzzCm#|XuL`l
zT}!TDLrCv*jvh*SCvvndy~ce24PQ!rNGu5HeIR5&>cf5_b$kfv-OABJN$;;YT9;m9
zMph6bC&YpiIwL0xNX_A-hLYYZIC?1Q9l_DM^cpk5(43jyAr^G#jC2@~+VcaE>KsCP
zpXcbIq_>u%b?G%`WC=0SEf#d^jC322%HgDXhLGNI96glu_Vy84mtJE=4&kCZzgH~i
z)fwqEAhm^)>eD26F!~o9txNG>^h%D_CE1vf5=x}Yv`{+ at o+IQscqK9VrC9K#&ghp0
zMaA)=zS6{fFq-ueS{M1j=zScmi at h<UFZ3cK$HanTB;UtyFfgFCmebN_^1<lEy~B$C
zjNT~mH|As<aq_KL at U7k?Ml(5vc#D|H&sqPR9aj9eosAOzA=W<_X)XVIvEX~15u=&>
zZcggN5aNH+*<r>1%Ck}8Kg9Zn7&#>toYEOFn#sRBL!>%}5dWq#!;1e4XQIS^i1iQJ
z6!N>of-apAqnW&dlj<Hq{I5SVtoV;V6D9sbtbcltk+WjKS)CE1nS6f_k?I{n{9oxA
zR{Wpni4y-I)<2M_O3Cl95)1l;+Ddo|eolJq7h=H|BuQTYjV}zyXL0gh4k7YMJ;RFp
z>Fy|zH)d{sH at 4E(V!_vXD;eqTf8wNu(%qHrVI}^a?kI^jW at I)o5)=!9IwMB2|ApOA
zv;SbUrF&S3|EeoW;*A;E)rE|FCl-9CGh#IR|F$b?_8*LXpleu(zqKn$;*A-ZN{pNo
z3r^~c7|s4dSJdo37~Ot)ScyMyI!fY=8F}e6GIClhIIS~cH2XhtI%@VGjK1^quo7Q<
zI!fY=8M&AkIU^RF(HSwC{eS3;n*9f(KkFP;;&*pONxU&5|I<0_wEtjd<g_o;UeJTb
zO~XlovGDwO?9=(CH-DdR`rY&Srh8$9{n+pFP1nHldGP%8|K^(#;Q7U8^G*Ig<eL`3
z^M?P)H>JU|37$XLlyB;JD&O>*XYx&}H|Cpegy;L<c_ci4|6IPQ at r8WTvESyKYN3o}
z at SF|Li{LpCo{vBoFGCsn8Q!%{j0R{DYPTnuOvOU&@A>5(ez}leo*GRaN$?E0C+*hY
zHE6)d6t9*fVOyrKZEQvdw80UqU{gREufmNlgUl1l&BC?{vjN({(H1~k4A9?^HDI|F
z&{jYT5omY^U6|xu97C7e#1%F)fiAZ}Qkwy#=Q*VqK*t!MYdJa=(6I*SJ2*NH&~ZcX
zQ9yjy#T9nq!wyO929(BgO7Vb>H$Zcn#qtC|Cm5i)&0={Xpc9AS;|;U~EO&@29K?qM
zk~$11{gP7}0q7A1Xo;go0(ztYdOk-BfEI?};~L__DXwrL9~DkW?lhp3$SIA2B%=(_
z$7!j*{5(LPXMp}YM~?>d=pp#{6B;CzCy6VPs6CP(X_5gYFQ=3Y=wt)*GL9Yt=rIQ9
zLXJKk(B}`q$3?_Pint<$_(*}IDF&2!$)vD+ETE0V=_p5!1N1lp^iGZ*59skj at PRf9
zWqGQ&B31H0(o{&AIw+~HONMcE`2;{sI2W}DP!|B|f^$*%fSL%XiH2p%7g_gM-_1CS
z9wwX7zSv^@C)pQY;Pyq!P8f}vgTF;Va<z%2ZD=!r39Ym(;}m at v>B27~(s@|Y$50Zi
zQcAx*7xfmPKtm}#b}niopg=n*{bmqK<L_a`#l%u3$-GzwsYXW;5PXZs?64e`C8a?F
z^fZnJy`=P81M~$P4SGpw$dCni|7a<29T!WF>uel1AoLNf^_Rn<r1U!j^frzLt)%pO
z1N3h=8nlwq6GN~e5gYAdX}iuwy8)rOoDeKYN>3V~f5g$4`;-CN$<d&bly(fk#&>8X
zaCM5MohUS=pr0)7G@#T>c7WxuA}Kv>fc_&#gGy4`Wq_{ZXi!N?yNBT84&tLnEbY;o
zqsM^I3{D8vBc*2y&}keE3Q6f%1GJf=K_Mya9fFO|&;;P>6HEJ~pKvz%B2&%-LI>q*
zfe2_Mr9YgDf^lIvXd|Wlk;M~AvMGB)fX-9#ApDRf#f8D&VI+CiS7PZ`dP{s|P?xD>
zg;?IE3GZO^7>?Ejcrdz~*8YY<thdC6xbk;>BbI)nv+<1qp_e%!HiR%g);p{)FYk>K
zW+OIAh>eg~8q(Pa84$XZ6FNSGFxz{F73SdCC}B2YqZwEIt`lPE37w4-285pDgxZG?
z<_%|u73LqGjS^-fHf9hT9b##R&PIm;p|PA$C(5${`s|ruW%<aNC|NdQV+WcZT-{=6
zHw_xyDBA{<e!(gA3?a-b&kQTf?lV!sY{W+<@zE=m_Ug^iYd|Q06YA51c`!Oei~F!Z
z4 at SSw(YjC at vGF1$LGKoMWLL}{WLKO_gUXj;>6bd2Um6s2J1^*~Aq0L_&#(eNsV7R{
zjo7rHoyK)cEIp>Pam;|wQCiuDC-K4Po!!F<{IlIr0&m2|gJ^$neJhrJtFvJ=k<agr
zn#c#Euk9XI;Lq=l5_lsvI&snO`d%#kUT4E-BL7EM)I>fQ{nxHx1^)4_D1kR(<0r(%
zDY5jF&W6!MKD#SwA|H&N+%>Gg$9F{uyb&A6aKZ2D5=*;CqPuVaFrc)Xj0Zys{Bs=L
zgF<gK{&Dmf6#60fSWJAJ6-&?R&0#c=XP=Im$j=%7P7f>aXFH<=-iVElJJFKp>aP+@
z`-R#nk}bG{VIbp_Q0qkbj-1<J&;*q_*h6#G7h>rb)QDd|`Y#O1|0ys3%OS>rg`LBW
z1G$}1<A4$OV=<_`>ua&}YrPSTbbyYIC>>xh`ooT4$APUKQR9FS8&7l~8$q!&sIy_D
z1KiUwtU_PXG3+>SRY%k~V8liuvGJW)`kl^(kq+?nsbLlR=2OFt1AjafH4YfDQHycp
zT_?rTlhip*;<#Wysq)mY8vXQB!wv)!Pely`Mtt;POn295vGlaw97amOp_9WZ^xIEH
zDfENUzdac>@f)!r6B}p5(la_6MmoUFCx=z&GfxgX4vab(H4YfD at qK&bSRm9UpCj6}
z7M#8J1aC*7DzPiFL)c~(wvEZyL*)(ZB@}#LkZm9zuw`Zg^d6430NP at Jex9SP!nV0q
z)FLp<U8EL)&V~muFlaO5vWUV5p>E&>&$WbJ7 at kHNr!m(|t|IYdO^JhV<qY0Q9-_HV
z;fgK!rqQqEo4($jZ~DiZ`KHhQns0ja)qK-pc%BW<<?w8S=R at 1_O$~44oBsK7zG>~>
z@=Z6xb2dB|!*kaw`KG;F^G&b3o^NXWOTOtoc+Q9C%i;NYcxF(>8&JmcJMv9UFXfwV
zgXb)G9uLpa{-6G{^CyZ*2TvUO!IP7LA~oXViT8MVWN>o3+h5p<G0MrITwpx<LO*Wu
zPTOLgiJs(`ytX=ZmmYus{q4ZKfCi{(7-yi`2`D$7SQKh00MAr(R_;;{Rhtm;JQ7hq
z#^>WZ@%gpz^L~2Xp+7(00C#v4w|d7;qKL4!0Jaf-loG}r(u<AK?3 at vpR+`~LxAb_6
zu?>JRRl34=M4F7uNMi#fM at u~zceK=FcG0<m*sj7JvmC#n#A!06nL=3`kr%O$Ntd~}
zt0i^6zwkKb-MB-;2pnTq<>Q1 at r&4_o<|G$DZ5T5Kk+`l6 at 6<oCt6z<915iE?*(sSl
zny8;qs#p6}rI~tJiPN_a-C<SvV?+N^4pn)tH%YPHJ(ip0PN>y483%;z<|@A}!P{u5
z^3i#v?_n9O%6lLKyFPK?#L}O%n6-AdQkhi7!%Q8Nof!R0_sfcYg!KbcYJ$$p5B>e*
zmlbjlAC}Pm2(B!l50yRMUR6#}PGy|r%#75SxfGZQU8KMeFKl<jR{8DdpVzlfioIE~
z&XGevFeYmsfPJdqdw>KB2|3ACYn6Z2jr|LP%T$crY+=h2!Zitcbf2{6wBU_lri=T-
zEm(+g7h<seK35K9>=(A%tNad&#!9%oKE(D)7$_z5mVS`Tw{Oh_-ZPeU4(}POoV4*n
z@^eiW{|NrT4#p3}Kl!0w9f(MUj<KC>VaM2boRqewlY_HZGxs_zk7K_WAn<b_Krz^Y
z$4uw}mLmR+WA_cDxF?(fj}MgZ##{08Rmp75K$>Dm6MW1>@!HT))h~BLdla at Sc}{W~
zJKvshNZ4+>#@my>a)h_%*41_lT)cg6$fE2Ow#Onk5y7zpZtyl+=12+HUNKeTUg;fS
zJ2Ycs#-7l1?lRm9PaEf5tm_tvW(XyuvfXwbmYDMs4o<AJgq+ at n{wS|l5zdsSVOU{P
z89ytewT)~K*J@>-Uh`U-2pquC=erP)BRf|mu^R`H&hDdLy9Bxjc1!4!(NzVpRG<>(
zbE?{CQA?ay*@IZw{ZbP&i?Dr9Mq_AnWMH=|$i0^{>|7x0NKU1lj$q}Np^shm-qqaS
zsHKeA=3=B}^ds6UO$1z7Im`Va?Clns#KB#nUfSEQYNDvQQ*&z`fXT6|5?d}dNiJm?
zI#6 at FJ*vy?<}R(9q<lPZS~QhhzZdoaAQOFBgQQ&RrXd&)==8Z=Z0lA0K+c+E^7|_`
z$=kH^nCRNQE2pwg>cWGm+Z*uIaY#XL_4~u#>c^pvvS*-qtGqqjU;Wpa<gdQS0=))A
zUOwg~m-TN=;fJ986VP2T3ObU%gVPF4En|Oyd{tibTfYYV)?3P%e+n^=hg+ZpU2I&R
z-a<Ecn{0t8>ma#Fen%w|?0n$QJ83`pq`%n6b3K;JPVUB3Th8%Zzw1mtx)s*liMMC%
z6Hns1TijHYGg5OWZr9w2+vRq5Msr|+rQFS)%OXz^FkFl%)7*l$ELpg?3D5W(eHD-L
zIzq>E!LNcjIApI9-<8e-LOATenAu*%gEK@$0w)PQ`6hJO5@*&C at jZETWbAJkDKIWC
zcCSlVbxgR2-vO04Cq_8M<wYmUAC-|@i2qo19yyZHGG#)h&<v%pGiQMvebptEYW?|c
zl3i!$T6MV%VWqlQtIHj9jN48L($JT8WT_xy0thq*4T=*UDK8_`NFU=7;xe6!%i1gw
zmol~uW=QnLF(50CUu_^Oz1`=^N>*37G7aB0`lyc+o25IH37Q}HGLV+CGW7%Q0Dc}G
zVNbb6mzHK}Ciejk@^T%ff<AaH$V-`v9n|FIfl)bfpG1z~pWfL|j^Vv6HY`Nm7%4!Q
z;6Y3fY9E+Cr19Jl<Vms6algP`u<GuHu^$M3Epe17CqcT*MKA&Ox2_&t=CP|&*;!Pq
zYWN}RYrNA^&7gBhsbwtrayr8(AEcR0iq%PlM$ohj05bygkqJY4V5eF&z=RW+m>9uC
zC?A+`mX#|f;iX84_&P3!!YY)*<gL2$+kVYIij*XNcE2;Dqs(Kne(q)!uThs*S_WPN
z#!u+!mj$-lg7o9HO2U9+7h?{OpJ`fo9(y5-VjH`lJAS6@^|nrIJQJfh0vHmpu{BoM
zHOp-Cw&qo$XXwf38Ty$is2^l?<;ZsK3_6)DvV^;JMHkJwp(Sk7+x at C1ZK1UZeKBl#
z2M?mdyJ9~FFu>T(JaUa5D0H}}ZmTr-Lj|geI&KwzE at zqf<UD4u5AKCiFxF2Vq{5iQ
zP{f;51h0Ic(5Xkdf6W!?CO-nPV-UjO;_maG8!E#KLu7a~3a*SmwH at Yl?>=)@L(Yh|
zK^YaEZ0P=U{K1P4_>=Jwlokq9u-BZmFDHg4XjB at b99=lFj^G{*u|pmu_O2qY=S`9Y
z-9CpN<PTP_UEQGK(6VYY`_!cCTZcPox`j4P!NDwjJE<Ev3zB&J at G7M+>2>tYTqQQH
zx>oFv1R$SS?uOp{H|j&|F%!Pb%kgE_n$WLq<cLD at 1-UK}dsnBiWmxJ(<o~^s4}m^y
zFbbj;Sr^MWjpeS10nbBQ>1i_Y0B?z-)LmZYF$YSLO5OfS2aI~$Ybs<+g7H)Ek(OCv
z7vGb1`pu!&!|}xgA4VGzJA~T%@!Bgqf^K54DmT7DRS7QC_0vJ|Pk-4T6$|z_qP!)2
zz|3*hv9(_f6duQyuE1hq3;7K!>?3FW3;Q*%-*OB_p}?>hHEVlFf9i~MzKXOc?lH^w
zqpG^lMQLH5i={?or*Udu)BEq2VdU$?26-|%4TgJ1*1_(Rnxo*8O1sk3y$s-cm1ewJ
z4}@mJ{UU(OOLt(J1Hl7F4t#syaN<6>v%5oSN9V$jVph7d`<V5>%8??ZTWwz{h>&(w
z{M-ycjGvdDlywB|>~QDk{<QnB_fwPduJVEM36`^XkJHqZ at 5qDY%>#Cml&;=jTa&1a
zs<WuD7H<eSgk24#E_PzB7E)NY#>Y0PvHDu7Jv17IzxqPETH;_^ak81N@(91{ztM+6
zRHxdNPuRt<IOv+~$U{f(eNqCRSe0$&3qm)tc))mJ1vnYHP`yd{=NyLJK!rhVIxdR7
zMdd#Ga(RUE&n+|9&4BS8S^pvXfWRg>f$jSNC-FYNJv;|)IKIXb8S0K!U*z=%gCxMh
zB at o#114f_QjK9wu#$Vra^xICq at 6#`%-~IIa0{!lVU-lL#9WZlbFc%c8jfEvA`_-DA
zZvh$u<@k1>rV0HXRk!#=3Q(ITFD_%(-T)2x2F9AjD7E7;Jna}5h`*Sqv^Vz0G=33l
zb!^4a81&?KyYkc5%fG{PV=-NlK44?aT3bL%wWljDy+-h1#A6K9Ak?C*r2c&W)}vIv
zR{CwA-<ROG?pG(^xAve=duxKpG~2)PZFtO~#KNOj11M0?n!8}NAne*BY^zDx1$?#&
zw3ZGak-Hn>g>AL=Y=C?0jm);#??bTIEYxB+Xir>)*eLvLZ#?e#@Etsy57Ur0fUO8k
z_hdvfz8}%B?cs(EJ_Z?~WG_pTioMJ#P047M(u<3wBzS;20ycgtCJ$D at tv7(Tw&1Pd
zdvkCu+;5<J)X0J}!YE5H3+`*qUM^n&dM$tB%ECVXGsubWh~Q5epx8~opamcbae8+{
zg0Sn|z%2WI&Ux?~I|fO_dYOVp?40f;(R7(c_bp7yn;^KwjuhD-iufG-6;ZiCnqPCa
zTAEdJ_8uvv=Im<02a7SSLKwU+crPZKagRJ^wgv=Mk-x*B+pbr at 8Jr!yPYa50Umury
zt$abvdh--H#oJ=h^45g&o)2kqvna(iJjEtVp{|EF!&97&gA~hz+VAjsmr(mPUhflX
z|AkjssKtZExod>lzvFd*Q2P$LRNjPr11|V(O#vTDoJ-iY$Hne{fRw3vA9ltH=^`b7
zau}d)$nNch4jiX-&DsW`_E%^IjZAS9qzK*~$NNgpGT|{g`&PRegCO*{g~vM3o>_}Q
z2D~g^azY2HfIoY2vEchz3^d at Lv=-`(I8kwd;Ek2%-AV5>u(J~`JJ2VAe`gzY&!<s9
z0)+r+p%)g5-Rn7c?56&k2 at NRt&>LdJ%krBd(Q?87N}&$nJ)_DouVXVq*Wn4BfQ;xw
zShi5R2_2yykrOwjqfav*0u}mgA*sPy1n<Y#2 at D$kec%Zy`vBT;F9F(E=_e3*ZV^(Z
zuzhA955N%cVU=A09}XBU_G%BU8_ at e%3yCaw-Wy#%v#*X4wop0*@{F9T;AOaH)EX89
z$eybd+dw;>%FD*O3%gDJ0H&6bp32yBpeLddZFp3b_m<#cxZju-t}v_#pf(l3MoiMP
zTzHH&57r(=V@}T<!lQpB_?^Pfufch@=Pv0d-ky7<bZ^gng724r>!R{&_<$(gro9TN
zcxb+o6=s;Zx{zz3_M)?@%Cn?Njw;26-41P8c7E%R9cYyx9wyfM4{w$P)LIG9-H1Xa
z)IJLdt)D3~dlYwH at LhP2N7bCYQ@)+|C2HI99J*f@%LjxF)DzJ#ziyhcl_1TP=;@R_
zkq+WPowma7dx^KQlQ)uoD|S<*CzQYmV|K;L?X=z|yPtMLDKq>0zDH4*xIn5~Q4~Ou
zR4Rry1VEprB$%VzrA{rzxR;02{mL`#WJ5{a at D+}*(gaOpU^UIjm8(<dX=y7eYIY)@
zcgiWyeIpXM1`^D;QXZwf3^UC~Sda4H$bPI1 at e{ylIh5{Y_Y1Xe_fdzgeX^fCWeC0<
zW)w(Faj7Z%lKES3(jb6)-RdcUt+d(qA<AN%?<4BLIQw8=sGzH#-jowXxC|*b*}59j
zq!iv1U5%g{3A<<Zg={D;Pl3iWvk!sRr(j+ at IFM+(@8J6LAF}xx?jHp@)<IMErvnw!
zx<4r8%BM<?Y{@#JwcA=pL?0OErD3<5MxN;YptK}5$*~s_(*e1I&mt-fBff_9v51zg
zRH))l-QseWvtOQuiZo{WpW$6X`P6$RXI-q7TC;BC+|bTIVMj)Dk;WK~bUv;tkZ9gc
zVJ!bqlanbeP)S-9`fWC6=7sWZr~<u9it{#DeEZ~68PxX<^n at nUAeA;~kkX=D#88wA
zo|YHo-H9RuZN3&iUJxIf^Q3FIN0 at m2vaSrJY&Po;8KK0 at 7HJfJNaHUM+fAYQI^&sE
z`X!};YQ5PZU#j%_j;y;da`xDgb~8)F#@UHas$}!2>pxd^Zl*d?^Add+3Tdv%IjxTb
z_6lh-zq82`Lt{BLP)RfAus1s+=^a`Bm3JqNVhZsj%>y1>3bm}TJ=W!kMfcGG-{V-!
z9B;FQ&FavGTRBY$AQ*<sF+345 at meR&mq+Br&;)OQiU}pDM2{y>-ebSOB%BA+Lsw~h
zN|O|7i3o1f=CBdxa*N}LNgAz^j>s}!0?m38!73D*hU??%Xs)hpkOYN#d{$Te{@`2G
zjx at _lBlu06;QJcr8>qs3=nQ|8nZ1dBlX-Q2zG=%p@=agD-}Haxo9f~3*YI}~{ze|q
z&M>&^E1jsn*B9AymkYIM!>{Run;+oy=iV>bbKR0H>tM*5b+DkO_kJn9rWXPG0I)9~
zH%YvRt~~b%zI|~0+p_ETNF}*<Nmu6HCta2+OOtZfNEhZVkS1LJsWi5x_bw@^ruRNc
zsOgoZgqq$p7}s)vycja2K&B+f<b+HP$Yh61dMS{10_IJ at yrVJiNX!eIV44O<(~u|b
zmFFl$4rOmvNfHb=(9vZvt1xMEnmk1rnbjbcID{t~LQ};9a=J3tq0CR(fs^&cd%Hgw
zzwhGx-JhUcq5D(uUG6Y<1W=97+IM{u85GbK^zYYkm*)T9*KrHmhg!$ww-39HyQtl8
z9hcayuj9<^gV%9r*fQA_yOQ6dl=fBXi at W{y$i<yfn8e+M@}*tYkwBoX8;7!D{Pn$r
zzt7x6zgy_Hnto@|?;`kRA?S<Vz;oTWPI+coHyRq`%h}2k;nm%JU-hfm&pZhj?9q>R
z4=nC3Id5QbS0VnFi at T@)v&G#?Zt|%05P!AE_s%KA{nN<FPW&~?BXgd?8VI#N9c40Q
z9Z`Ik#2dhqd2p%W7p;y9DECtOb<yu~`rQn_^(l4#kF__CYw~y=$3qAZ&Y*&#pp6RN
zSP(@JQ4oTlARw1o5jnzr2~R|<AR4fQ6kF?styNoVJ?gFCg~*{GY8CMSJP<9lPZ||e
zs(6v#%sxo~Yu}&mA3tBt=3&p-+1c5dd3N{t at fY~bz01oT*attwF4ry~F&^Tx*f>j4
zyaF5gIv1AALN}$oSoM*;xDjh->_ua=7wr^aFV3{9mE>W9Qw=ZgE>JdSniX>umG~?{
zP2?Z1SD1%G;1^5}*xkjrptC1PNnDPDrD!D6UzVtUtcy14pU2;T;mPu&UAL3m5>k=8
zk9ZgUvg~RdNrWi0N5y5o0;3h;ANc)KWrc<Q8j?IDlVl at yPc#Y?!F;rPavUvrc~8)w
z0b8T+4|s4Q=N)lv#$UTy=?m#bEGZ>@1Jn2NQ&-5%<>eNWVmiF9X7FHvZ*nZerbGq|
zPQ2W45bH>q=jCZ=s;R)s>wpzmX2e6yat|4 at LKnoWkT7i_8LUFW#)X8X3z3aw%|>Vv
zRiXLph34}lG0ml{z#1?m%F;O_tPb;YWyjRd9NBJo);){QvaLpF!QdmYp9|Hw*s at hd
zD09c~^6=wKj)aj!reZR?I8yQ>b$L(T5cVK+(60X=G(%!<B=L9JN)k)(`*LTIjzH!W
z+8>iyv%K)@3pm(fM^NnU;9J&WL at j<yh|C#sYnDrMFOdDgEaWnzky8b)u+~uB)7ON{
zWhV?#-$;F}G{Y}5W;jXO3P}<|aoIXUWq-f!?r-0Z`zxQ?qqDKU{IAaPa(N2uL at y-w
zD3P=@RFAaG3~_L*&b?3y*~Unj0si_zIs7Gik2~~9sh+44d><MhzUV=ChaQA?=s|dw
z0ZX2NYDkGudK$A$OBD6 at P)4E$fy`&wb^{fqjAiT9&wSZe2IK?I=t0OP9)xPPvTTmJ
zY@~tGgOE);2#{kJ<{%yfCWos5<3T{if^~EStfR|d9i?C$O@(zdQBsI=N4#qxp;{hF
za6kMGHSH0nyv@*7T8I+8uo#6<K^1L?WX!|L3s?&Bo1aGn7Z`BPV3ZX!epKKdp36R^
zucikqz_NY%%$z|t!hSrjmb*n$=|*TG7DPc0H$t4sjc^Q|NmYEwS)7%OxMZm1qMX at z
zXumSEotJk7YkV8Y`)W5Hf2!=o$axgR)o5_h6|t2Jxl9-Bkvy!8_zg0;M^B#6BVMmN
zUP at S}+n-?f%CVS1!yP?AA5T(rDiLSFNe(&-c)26cjHY#Xxs#P1gBx75SqLkj$xiP6
zQ_g{Yy{hA#fJrc$bPm6bsg!Tydv{W#U!y at Rtri{Cq*W9n&Enaz(KvJKrMb6oQt(c&
zRPKo5uZa$h3zZ*jNvqru$&#}u0_D;Fjm>m|&D3sehJA#Mj>J(Gtj0vPL#sCi`J`>h
zS!|lYLy}j78OwD3haljSR;xACqfYK_SJx}WjZzMbGsKpmtlAlZl~cyV86r7L1o<4|
zJtH$gHbY142q_}Os5M1L$XFevBLuHe<>j`rm5z{sI!Z at K;s at dg;pL*vi_VY<#2NAi
z at 2(?yP)#0%O97<9N-sH$zN^c`5G1Lxz5glpQs2wnNN*ciY8sFHh^=$mv_2YYP1!U~
zPlDLcf3z~rmUYB*C$fe(TX422oh?My(PqY6HceY4lUx|wiKB&JYxnAP72|3t#Bo<K
zKOR#pBsgnG{W;<au7vz0GvR!M9M_-Tpt8Yud7FTSH1(%i`&-h4zWohkINlSJXAcol
zKO%E5Zo(gn2%jKUXwqXkx(MZcL=$t)ViPeU=mwdkL_n}aQA%oZ at q>vfHj)%NAa|!Y
zk{WR3!{2l0$Z;g4v&*H$_^a{;<@P0hAk^VtcKpcjh@=?tkT%NKGs`Iql{LN{Bic>(
z3dChvle%yi7m*}yDq(pddKJYe+IVF|qAEz65J!;=SSp~WQ-~-J=oI=(<rE?WLZ1(*
zETFejh at ppBo}y=l9!?=A;uIot1Ul))5H~=^CT^QON~W#JLzP|!iOe{MUcY6WL&Ud$
z`i>Dtm20G$!*UqTVVpx~uNIID=p0)1nmC6t$<#pIiij-YJ|Tn?cLE*pGmM($j>UxO
zMM{Quv_%QW!R(q)C_u?n92tH`1sD at rqZTNcGB=@jg&TTSXxXbmEv)dUMt6l;GCV;n
z{hAp*WNFzfNPbnt=jDEfU957UW-;xE`u7%$=RoY=$HLt$59-k}v&<<O1B8<72un4M
zKCTHwtZaSnn(E$n*F?FiYB|A at CnH9Q%6k4SGkts1 at pX?nMAm9L at Ny5a)C36er=PW{
zW at +vMC?OleR--LtZIMs=&$fp3Xp7$y-woXgSv{g_?sOa7cuv(l+;}QhR0{51Zal*2
zStA+7ByPM(632o<#5ezIvY<=0GRj*vuChceQhE4#PI8rp4>_-}_!!Y`h(bu#_MT2Y
zWMIb0ckrRo$%kuI4<{e8G~?vU!-|NXk6=#xe8l)GE>bU2cz-VO_3?7iBvX(DNlHTW
z_sPmxO7(?)i|-1_2u<iA?_rek`an_*S}-g|VO8ofD!o<QdoAo%Ef|4CO?0YOzuzFO
zGjfcqhH_o6Xh$33ZgjdTdO4OPUGJ2Sb0mFGyBxdAsa=kc{~snl(`!cdYKRP#$~iCh
zHyjhPynrgUnm8g6wO)=$6bx!dB>tgxMB*QOMp!V8NHikGlF=ATybO%cF_8R-W7h4B
z?AA)r8!5o=ixbOQ?Tz##BS2VzGy<9srqk)qRCO}mNMhD7-bhSmypjJr?O7l3?-5l(
zN)S_dBgy#p at J8CaR(T^!ntOO7F}m9uNsxH<w1+p6G=tvAB7!Wz;xc{tDe*=UZvlEE
z37+VUL^|}qmOq=G`EP7-H6z|ge4u~cjNV8RH(yF at i2`l4qMsMhhO570F&Yo(gT!AQ
zUY>Jj_h^SGdDhpl812XvGo>5%6J!Z9dcOCfhImotUX+;^W#mQadr>?uFJ9g|<Qijf
zC0DM6KO7Hnxv_*4bRyMcUr^+AyI<H at I(BzuOP(oIib7965u?YbJ)b_`qUZD5bN5|Y
z&jE%uyRxzYA|JT2k^zRaxUzyCy0YSpV?A*X)<CcurJ-E$yDm{by7^w0au*jmpYWFM
zyt~V|PJ at -3yw0hU>C(C`h5U}Rs-jb?aB3bpl%y}kk3Xw;tS!~ymAPwk#4Q at s)d1QH
zH3+frJxi+d3Su=V+W`7XABgi)n3ghk((5zZa3q3OIY%sPWr?#|S=2yUcn{rmtr9Nn
z*^QM?t3tJV%Rsq%>qjGnq6&HtK(D~IR67UpgadvlMbIe~7>5K)1n=oUXjgnqF(1Fh
zL%+PMs#IDdZII6*J2v0@<BmavsR{F`Wysi%K at LAJ;79*?7dHW3lU75or5w_0rq6}$
zHk=&(2Prfb1jA5U6>kz7i_|@12u)sANJ8&PLR*yk=q%`hyTp at 8r*z{`CB4DWyL(gJ
zAUZ;sZ>BmQ?S2jDeqDO8;tkN9IP#?JO1krSW!|<N at k0%&+K;|&+=K2mKzEB?+m;%b
zoz4=$JxNfDd?5Yj9d!#&?~q0rlzS8Vo;0Y1wuUZMk=>tt)Z|uZZFn_<6^p6}?Z?I4
zcs^W-D;KC{DE2bo*0`EslDrT6!6|e#fh34R1xV`36^C<J5{(|;b2A8mK_X7ilwdk)
zgv#mZRMX4n*;w(8 at p=B(%janY+5Rt=CpCcnr%A1TzxW;aOu5 at Jl<V|>dLi{N*rOrh
z=9XvvwTCVGL!8Y8t1g(vPuJtO+dQ};U2!&tC8~9iXe*2mQ>iwk>tIIdK!p5Qz8O at Y
z at PHZ6Ccda4@i359S>ZN0`4901vH8dqyYzA2qocrpw-IkgFr}lr(TV(>+4VRM_k4-B
zb}^%<9Ja<TW_xSv$6FYS^vR$Y(C4wl$J_s$UQ(uxp~jT4!w^wlW+NSQNW-oiec{T@
z%I at E&_V<Z~D0kcON{k>^?~ThY^2 at k)m{+3hN9)d0I#06j96~;Ba1+1L$hLCyF<!y9
zt9K0L at -|k^1<d_}<8{e)yisH_L2f(}V(dhUr12dVX;9|Uoc*e;ebHo}9@!=+TY&u(
zG<GR>681y}g_ILHV?tUg$L(=a{FYVk)_8eSa1}ZIul>unx_a(k_7^(`KA*wr5^2#Q
zQ0afdKk!|K&PjCUz?^2GfWYmATz`-eCz;RVJc<Td)#8 at cJvg+NbkP{4b9EJ}f#cHK
zka2h?%6p8P9<zV4m3{yjtDryxS3Q|fOqBE0I||JLf&tw^ADZ4-*oC6H3^fO*=JY_R
z4=p~0G}Fj7DHPCt at fra%jr)2b{=9+QP`V1gpTs-CnFqoczd9mag`d0Rm2k{tX!GS{
zb&x|G?PL|Hk}==1pv5PdI&CGP+=?tN7pn%G2oL+w{ezW5-nT%&jc4Zz-sgvYs1|gw
z=F3g#ZMRj!WLKLX`o3E5f#nJ{#%sW66b5z1YtHpY8U`y;3Bq*HD)QNR)VEXc1wy9=
zuSC#E>GDc^-c+=3^(&Mp`n31jgRVSM0xTrp7J8l&zZsa(hmeffMO#H?iE32I=tVmU
zxXcHNP9pX2&vawn2?1AXh##W at 8o9~`<IYO_>^T=g=ELzYIW>n0-a|$JAA{i)N(4e>
zJ5>8Ym8|rwqDPzJCpH0gcV7vNbAqMqAV~8=yCk8VHG(=6qms~@l&&PSv09)omh06B
z8p%GPP(`8Oo*!)sv?JfuxexaJN%T4735-R3Uki*`E;=lcmZRVv#mVte<iMgPZqXcD
zh1X1%qjx2Ta`U7{c~X3O9I&;-Ol+i}dGN$+<u$Cut-P{kY~QCtZVtF{DP63V1=T*O
z5#YB-UF4dQpbn|PB;I)b*a~Vgz!-qR0LEh4MYPK?sDrlw*!YQjNR8kLs^fA~ctAle
zH-HCXpJ+-#frX7vL&dD&m8bA?Mj_`2%T}zkqeg*Pu>=`Cz?poLCD0iiOd{(V0ZnQN
zga@>A<+I^|G%&-N1(qr`(U}DlfufbvXnNL7RS&Iis(Lu~B6Bzlcm#@~aVyt>2ckF&
zjB5n#=sU=(f#t)n2-d3C*N6L<<<>5PJnfhVRPw&7eDLF}oK-#@=(`pBJmKsm#<iwy
zR{I`4rOTvqK|MF7beKPk>G68Z3XjKbhSG;`FpK99di at QY3T7zM^Wjm-k}X!AJ9Tyd
zsf3)`&TM8 at i0DE=ogbbn6m=jwHAn<4P+O|hrvpDIRgRxA5{-o+)1a(Y2|LgQONv7&
zDEse%lco0mrJ{5(>Wm*f2ymKDKdVQ~K+};4(Pt%UQJ8LE4kx((pLIyvgXx=4em*JY
ziN#)t4$wc;W4{fN{yW5-Y>_r_tBYJ$+^H!-#^qved%98^XrV2w!zKEymegb;HZmWU
z>iGr0+_f6{-fYgl(jmFfoo$)J&&l`skR$xyneU?zWxuM(;pOfI?g0X^sg!tj0Mx(J
zQhhp0G>{$yIIVI(E0OYr#3LSHGvaqPak9VnQ`lDv-m~b}y6TTk<z&4dB<d%v0W%n~
zZyQPyfN?>-0O9Rvfu$<u$SZ*YnjZztpTik?isb at amSrsBfwnZfMx>?dV=ULy6 at a8N
z9$w>ALAg64Z&9P2SuXH14E|y>f3carI3VueFVHTAfKb(to53o1QbYMIE0G?=vE>{T
zx5~N8%f-9(?G%8AizKU+m-i!DnSu@?7lv0j<Fw}G;&;xRiI7<0RKd&3Bzb738s3^@
zvc-+P)JWXPSvpqSsm06t0{6a^3A*eQp1j;48hCqS-b~yHC1_Q2u~_kJSzr8cEIT9w
zNU^qqETQ_9)Rhntkp&UMD<R6MikJHh5?QlQ&`Lf4##K^{mzzPh(Xpv`U<+OzE;p;P
zTHDT?V~OTruVsxaHG;nr|1z7mCXOr+9Nt$U3Uuw0#*9_1^Kxh5hJ6zGj&ZdPuY{KJ
z at YRBhi&v5fTCH#;aPERYGzjwTa|e-4%daUVh(y#W3xke1V<$!CA at OX;^TjYV&Q-WU
z3CTZ=wBpL7$iD}&Am;I!Ur4LQ*7y~=JCokt at g^_oK!M=p;x;$UPNxSe?}MZOw!YYX
zE(RGK*;>Q0fIGpbE9c=#8}5JQz&#Yk6*A-UhdMcrR_a~K$@;*`=Zc0BVQ!A4K0a~-
zr8qfUelJ0iO$5m@^{iEil6Xy&B)~dWC}7A*6;lUtctSK$B{f>Fb}9a|9S{umbi5|M
zKKL0g46&D9?a>P&KqMR^P~Bv~ZxssW#FuVmm*NT-OBYdhTFU~GfrW?PWo-eSE{mKB
zssa7j<EmOecB^Fc<1|Uud(h<KU6=*9P|)HBd`7PzTT4yAuu-X6eUX<$_ncl+Q|T^H
zt|d0|b9M^HtQKmlW7a)tFfaznIiFUrD!`yn3cNyhF6oh|mA2v#)eI`1z(QrsB$h^O
zTR?&!rmc46QjwX{YX;YT^!LB3mZYKza(-q$EL7dSp_(1DEI<_#m{_gEH*xp at GU^iP
zOt*c8Ge%lXA9}6qjM@$}B@?3ss?o&d?<c^a%1#08J7%>~qp(xvO73CUMoInd at tLRD
zZ6h;hONa>UX&ai8Q+;Nj;%Sj%CFFn!qdRLrx<X{8&Q7-x4ce at SvPz5zntr_+sB;&L
z4m|hRq1H0(%4O$>@Ogq~6-V?iNc)lL1bKP6M1(OapKP6m>XhV+D{3B?UXDkEx@%=l
zNk&7~5NQ^Q{1LQCckVu)%sm-jaDbW0E74W>7%K$uaQ&4#doV}h(@6;t at qxS&-Ya(v
zhzafF<#iH`{iW<SjzAE%pzo9$A}vUf2Ua|Uvh~sWm#~r(wb9b&P(`#;s&SeDgncu#
zqcu}a<hJnKKW!|8W*JrxGf4g!??g~%p#l4q>tJJ4c_o82$oI!DVR5Ob6PgE{W-5_-
zPt8Q6pvm|0c?AOi=P5U+7wWd5;hB&r+R2kN>q(mRB+Yt~W<5!>o=mgvKi%y6Xem~4
zRWvjjOh#R3kCz9QsiOA?E(!x3%e-9N!uG_3cI8khzb)O<zWVD!Px}h&QE`?ri&4Wv
zlt$;Z9GD|n9b}u=$nKImnS-}@q at 0(#8A-0R2Bqk)2O}u&u4p*@`6cxrk1PAc!C85j
z@~FKf&FRjn0a=x2)qCchz$?)Qs`5%I++Mjm4CYYI1Y15Bx^}fp%=})((0C53tt!yW
z#m{us$_>e2lt=4dgu!rwV!V<%k5}$fpdeq>ae4oO{?JHnJ at pdo8!~j2U>SNuJ5`AK
z;92}1F()rC6%E#P43SBr8<Yf)OaDdX?J6sl+!qoM91?_TN^GOX3}Oxa%4e}cK`)m6
z3FF{x$$9O{!FPwax0yvvzyo7a&-Zp0Y10*5P;;!Y)Nj;Wsh{Os+5}hL^W0E8872+1
zG?uVWqDGDfqwz>skY9XPYzs6JrI-ZK${lm(VF9${M4@@ff?T7d^SIJf196vvnj&6d
zIZi=oJ5iS7mRc81Tq-p<Ch at j3ka!x1R~!R{XF#k5PJH)cT-uAJd<a85@&uwCB|)7M
zuOfiHRN0kBNy*=<GC7C?n1cQW(zynX{#=n3=~`8Q{}~rB?d1B(2Pw8Sn=5hSND>T!
z{Qc(551s!7exI^V#hw<@AhHcKzH1)XIFg`Nr*@G!eZPir!d2Gv^o?eLg at H$KU#{Rf
zO(O2P&*)<{XqM1h)EVhbXUJkDn}Z)PLv=a?)<KoOR0kHs0&g46s|pQ~3B8mlyii?O
z9*fs1DpqF9k%V?Q-QeYFLnW^&*u1<C9OgLqqyl#vOLlo(XTG3|S61#B&zVmR^b{FM
zD__^`(V+T^A9YEBjHRIllF)YfawZnEVFRY67uD(+(RR8^A-9)SUZ*8K#!eM!ni2ut
zcS7gk0no<zP#mV)5W1X{KpU36NFKRLVkC3$bB;tg28R3cZ&>_!5_h9f=wS>r8Yksx
zUVY`t at sw6k%L}};a^C1sX~^bOB20yxtS(l*zLZz!rU6zcj$F07k(M6iC*>7*8(Cpy
z0m(c)pDX3LFeNZ6o5^aWC$b`0M_|@LB&&%kD`eATvW?I~_YLh2-SU&_C?;wvOwE)Z
zqg;mDW_;+pT3&t<JUW34_$mtHbToWA3f;9iuUMesx8kPYtS&Y$*MyC`eJQ;hCq0o?
z4woa>%;CS2hPH$1q*)~iHI at iEoEmxJ>qKf97idf!#JpylYDgL6Yr44tjb-b|I^N;w
zbTQqm&{ZSHK~JPFu3$q_wWgk21oW3DDFnv2I at 81_q3DgZNKfUL76El=pbq0-_oPg6
zvJ`sMscKC_sSemu`QF-Eax16Mb}+;+VF!$pB3^;xbc5OULZUg4-wkgN5E%1Td!X<!
zmFh5kcfn4w<yr+AfIO(UU`fLOKqq;5b;M!K%SAWS>;io-r?uT=YtZ{s?!qgnmGeMf
zU)c{DPcxbg($yvBlpjn)7DX5I<CR?El}Yf=yjqbVEj+Js9Lblvf|AP7Y?Ql5VfnR%
zE?K$d2ij_Z5wJqHpr4eNA82IdhW4cDuMuuz8|8gpH*Sg7n2Rnz`psXYXP~l;4Q;=U
z7P0~8CG8*- at q?s{TM#+`#8Ydwdgsy8>hlCWpiTk<O2?1R&w?n>RK%TKygVsmR>{Q7
zuXKQ2Ef at tGD>TcYB8hi at 8+kSGgnqR6e=`M<a6sb|T=5%VizebQHKh7POZ3H6cz+Fy
zysVgTPKUUn%c&xLNTDY?TI{GNG8C6{AT?f3ww8EtjLB|DF&Mo{E at 2l6I{%YPz93u@
zq~elM(c-L5J?dz@;k;;xCUQzAatc1Yfd?z8PPM!C2tD~2<QyF)a~@%xE+lZ#V?tmi
zUYDr^@K-Sq`TFcYnA4OI=an`xkP%z18!crq*<esWq{+TRjh5gSueHdjS~P$Tt5i$Q
zm`c>tW%0yNOycD&=wj}vk}d2amvw!CFIkLZxz(VF2X}O-USXNj<0~0)-LJBzxGw4a
zDr*p}qs;cCLfxdS7^GnRf4<VPA+NNmiL&4%Fb1_943qK-rkY(9Dq$)=5kLpN?&|&W
zMX4?a(BCm%?!|Xq1L)N5wwE#WeCqwy*_U0)_gh=B+A6xxm+Z#j#`mWm`hzzAO3Uy0
z3>KT}6R!~q_JK>hCLP46Pw- at Oklc#G+!^r`W(4JRc#y&C>%%YVUy>MNj9Nc4=ygw+
zlqGfH;9~EL-y*krh1Y2SA9oT at lk}p*rvo%ayz>ZWe6~P&69r7uG{-`BU9K~F{xbU0
zdvalP?m0D6w`w%6T*0G)T=^hBdgpTJj8iqGTf at 44A7ab7(ndKOR at 7!{ze3azpww^h
znj3y_u%pOK#0d_TYctkIyaJu#oy_TeX?p;@NQ!f{x==`?rsMP8?sr;{uD+EEG*2|D
zK;2xt6lg0lD-^V=Z5Thgi#bf+>;58DNxZJel&(IfUMs7PDer=U8ezRtUg>e%2FV!D
zraSiceE*_s^>0y^f>$CifJt2tWRe at GF<3N&EL43#ca}<&UV7KzAoa<8*%Th<_!K(0
z$PyFGfZo#U?iFQ1Jd0k{J6=;=Aof!UP{6NuJX>90@~0A at z-J$|9IJz0i)PAb{zn=V
zqq{yz((EpF<v-G(*pc2zny~}Ai*5XmG$^+G<D`)8VvGJG4T`ySebi at TWtlObN`L}=
zd&hIs)O+*c6A4h at VefdZy1>OxB|w409~)8RZBRSCF&$smb>KBntCn%_LkOawJ%&5;
zgK~8TE;3Vd(MJYMk2`(1^w!?5Fs23&?mbVBODC5YNd@>O at iN7hXgF1gtmvbq>N#=f
zFdAQVSn(C6V!L{oFYZAKHK7c|Stjfibr4#vyi~vi1^ax6B=iX=mH9r3!etubGUjy?
zOv>|qFiRBiTt9kf9keMrj}Epz7$;q;nk3>Dd^5={(8(7lX38r;d$E>eb&9mbK4xq=
z>NsOTFVL9 at agZV2cs`&YvVv$EkTe1leD5ZoT%a>`8D%(i9*IIFR&FWrF>&-U5m{hP
zQGb$wGj*QGpkStkxP}c?L4{I*$(Fg&&Ja|fBtebz+ERrAU+ZtXNEYOKAk`&7G$>tQ
zLjtO9(mL at Y4#nk_Jr_T-kq at v!rl$M~UAIpi$SbSJ&=k}B!qi$Pkx9A}+R#2`Tqhqo
z%|C++N{5r6HEkw{e at DR+Q9p<l;R!B5OPXDVmXqk-(s7WRLySr%slZI()47K$a>ZB5
z#*{V)dWlabS}=lka$TH1c|*_`LLZ34<0P8Z{jL-H29%S|0+vF6l#&Tx^vUf~XV6c)
zha(yZ#zG+2pOm3vXnV%MG;ML#6IMna&?TlhirUj0GcZE2)Rx{0*261-nMMt37 at CxN
zs6~l=+7<Ht5X+`?aoI)-L<bWjB52h(Y!P~wfGZ_jlBXZ^7)bEC5wzylO^BQiXqj~^
zHAi83P`m2=pB=vGRhqw!TKFzdq!YXUDHwYiezfz4o;R}eFqA>!)BIkE%J+!q)>7tC
z)dRwg?s(s;B8^@ZHS|jK$HhLF at uU%({AMxOK<)TC;g!hDQShGXN3TBBh0C at coq0-m
z4ozC!eMKj6jlg2d%dKXqFZer}LKGV?zDCk+r_|HU<-n&L7-Xo4yMwAH*9SUg88015
z>vxyqeq2skBM(Kl&N360$O5_-96(<(B7QiM%~j=da2VUnE8*DT?V5hH at F8vn<dtYM
ze+EA!a>fHM*yH9YD2`JnRX?^9sy?H<LrXbi%7L=MH?ad~>SXu+=l#kH07I)BLGx~1
zm1Ruq-n*f)sen!QP}6n2gl#~u^f_AKqW<)VlPaI9<$m&_6KN6R7|PA)N9(E6xFk(3
zva59rHO?Ob+PkZx4>v=X{_6x}8799AGY6Dz at ta{8wbHA&VM5>Tu3NRXb>SS1*NxIQ
zcJ;4C2I9B6OSN(;LqNf=w8`(|>V}-`6v|C|h=EqMHcNh}T7%_PFaQjuK3 at 4cGo9X~
zy<l!Nt2AIKwF(nGP_RULdF7efuypImwN%#%0SYvJ>m^i0Hq0y12BKwYxIiMhYN04v
z=b#O$ucRa&)>73$-|tQVrOvK4*y#-rN#lfy5Q=?-NO*6rqmS{@KVfiu%<_4>jpZ&N
zL4Y8)O9(-3fW#A*cZoZPWmJIpN57lI=e_hb<fi()zT2;&TF1ID1B~(aXt%#^l!(kE
zJ_cm4O#A}q<P#_#JEe`%O7R<{S_M+A!Y1Dc*xv)};P-g_Ti#s?<eqWbMTq<YA55xs
zSacx4fVmsg8|VRaodc4tz_`FDzyF+ku8Txq=2V>q1X@&EX~I$y%S=zi11?&rw?Yfw
z at uMPzmtXm*yw-$|9szyAlmx<5BwUZ=svgO(T$$v($~HvZmo@^OeExhXNHB}M@@##q
zlzyv^aWLry0VDLssNilvVQK^Vsl31R>e!1St$6l4IerYTmbV2z;-=AknHyKRrBs`o
zV)uff99!Y39>8%uwQ^%r$g at nOP0ZG<JVo|&=`~WAOA3o?Q9B)5q1h>cTp}~TeT?*~
zwDMC~+F`upeZ&ey)@{(@@s<;DmtsYSSlGxCXIZdBT&X5l021h|0;cvWULI}`aq0rC
zggsAo246egb#r=|ts||H9l-bd at 3J}Zn(|gOMin4WOk0_ab2|Y^YcN0AX%BO<o`J3U
zjA|_K)5xu-u1kIH73fakrg5fRTDlLcUqDjSDnAWKPb39)sS0dm3T%}6w2%VaDVKO_
zM5t^sg<518_;!8LDDpxpo)w}H-HX>nEN)91C80O*7GpEWaSn}=Y!}8>d5N~l#6ov-
zu2T&N3PlFYit~W5MGXrL6?q>&`a at C|UM17RO6j#tk(Z0S5<o5nHo+z}NR#LjK?%fo
z#DKF})VKh*FUy|ZqkTJd`zt at ue%8O*mv(}Upnwsv4G2-zt!k7SfKfLIHr?ze5x~kn
zEt|ZkZ>1+?qt at 6szfgElZ7G>Yf5K9-k3&nzQW^vc10N!Kz4nP9%c$8WEvD|<FJHz&
zTS0jH<&A&cetCkWdao0IRJ{_!{Q9ZeFUbkX9=BiKUfP$Q)Lm!-6q3)z{b!!WPM1Zd
zxH)aE$~DehG$Ws`NaaF2M$c8<feCAuF0oed`b%^Ak0YuY|6gyyRP9324wVfghlINq
zsu!w-D&9DD6uKym{n4eMn?aE-Oyx^Nt-Ut?#i?7SqjxbcH>U>E`IOR!5KP~1!@C;Q
z)DKn!0T;FehtP}hZ2NhO-X4P%TKWfi3`DKLbP1)lM%Bp0&e3;e(UH9jweG}WzeA$O
ze<UjIK;r0+5)Fv;z|?B^=`>R5^R7>(kvi2I@$fR&cun{piyIeWH;{|S_k(f06L;fP
zsrKZ7QPJ5&>G&~kuzT#33$eQ!uMvQji-b6t=w~<Z4oI5pNRR|Q!Lsw?*(3*D4{6ei
z!!JRS_>BV89gzVn24maJ-}3TN3tP!`ddXW;3QuQnA5cI%%%~`G-8s3!6XY?B-vD~=
zA+=k4+acUfL$sb)+`NUYglpmgArW-uDOTvM<T$-d<4CLIY-u$JNxTb?K4zubDL~n8
z!Pb{)ue<?z<29+M9i1GIWiY7&@&nCOD6Fu>D};&jg?2oImmFw`^l6Jjs_i%8tDtOm
z$j>^xTe)NfG at G6f(BpM$y>gcZ*`MH!_b5QDU27NFn7s!GjxVNPH+pUXBVu@^B&Y*-
zLXM`-9#mCNUw}txyK?WgHsCs3)B)=UFZUHA5 at CpGtTeG#Q%%HuC&M4yfsS)ybBo%2
zXH2IYB#y9n-FdR3y?u5==l~{-c7We_T~uW3e<q4dJ~ICQ_S;pWe!X(Y3Ucd2dVg9+
zS=W;Ts1z}`gC7o{zyIUEJa<JO)Sf#-y5xWo1DMMn`|Au_RQ|dre{^;4=``5F_@=eV
z6fr>ZcB>fNVEV)(Y`GKFjCluoxGv>Bc<}_e0#dm#UD_#D5b2JTS2~Og{AkYuSOF9;
z|L^_jHF$YC&^;FE{@H^bZqwKM8G78?-_vcn;bXUHoibaoIvag-$N!7lG=QG|=)Xw&
zs;h at n^o#DABlrKOQ*=+WipXC*QWF{UQ?lou^uN%A!9|b3Me}Nbt0lWUgjbTu;gyv$
zM+vWYu6l<XwkSXNg$QZ}{Nnbk5%|kyQA6;T!xA~?cyV&1dWGJ$mIZxs9<9o`1iHO^
zWbfG3IhWXSIwzd7Qf}Ctk~1_XPXQ7^q(ioIhF0OoTd~SnEG=xh`-)v>g2`}af`|pP
zP0W<`{!P6&cx^{koflf=7kdRiOJLf8ZrSqg8pvv5-d(^<RX}Qp1#r7J8U1`5{h{|!
z5inp{oyfFm&9pj#*@yNSvpLO-zPL|a<%Mm`3r)QLRmnSs^qzg{cb0$j;1)yro9=`Q
z{|AHI2%v|we8eCOcMMhSd6)C(Y3d3;#T4uBshA=St76`VhXe;meT?;MDIesFEQ1rS
z#}<_E at jDtL^jZsasF8Z*)NpaNhPXy!%3o>PQ~t<cvmZ~Xfu|~Xs-Ds!(ih7#MAz+V
zr?gPIc>Z0H#(v!-t at vV5ShsB}Fj(3b^!RA8Ba6~?5m&IC1O{o(L#wVRtd_wnRamVc
zVGap%NtjQ<uSxhV2{(|ih=f~7xPyehkZ=zP_ml8236GQTBneANSWd$8B)mw%D<rHV
z;Y|`YlJFi0TS(YSLYjn6NZ3xo4ia{f at I47x6ENhEkV`@X5*m}xgoG5ynM%S$62_8n
zF$s-HXh1?P2{}y7Oe;2|MG|(9u$_cYNJx{gm4q!Myhp-D65b?X9SN_H at FEG%ldznG
zr6fE_!s8^gVW>);_mB{m*X|ib4Z*j8T22CERKF}i7e-~9=)$!34_(B}28#^O9M~!7
zuWtk2x%koRZgnx6<i`~lN$YZJslhpKhKV>HGvypGT|Ekna%)9TL5J7Q=SnN(x^roZ
za43LIf~t6a>>iw-t6+(=dnFOwlZfghpyadZ<VIo(FuP4-e*x7f7<awV8)gyl=~PV(
z5O?+$>EX at j!Stc;yYS-FJfdieT6nn!;Q>t37CMC}6S&Fz2b?%rEoZjc&44 at xcon(<
zeGzd7>oSBcyM>Obdxh>?l+Ad(I`1iIN(z=^BN&9a1z`4pWezJ8D4QYCB+;%Gx0qr|
z2)zR9Ds*=M73^jKYwAK#O#H$Sx`B-dI0|l3nE|BaU}ed>PE}Ma*%&Azmpf;1ow}$#
zpy-yel_=-p+lpX<Z~*<QGFGG`eMbtMbN_h;OEv+XrhZNhX6mjGDwtb-C<En}0%R?y
zgWN at vq90L*AlDB}F0cf0g6Zm;pr=pO29lp`Aa{+2g5iD7QL7GwXu4jFRum|q=<wKy
z5kKKy&^`KRyo|<7K~hQNSiwzaG+36J(rb3%mWyC|QWy?1jB2CYBVG^RPuFNx<DG?=
zpSFEQv|uEl$cLW0i_wI at 0643`bd>suo{F&!hSX+y0;y9a14k0CVGDf&Uv7x%=*x=`
zb7?i54PB`6$A2<%)1Rmj-%{bY;8JiAS*?GAawlWF27MVhSd#S~k!*3A#J6^1WkvjC
zJlKs@$T{rjKsifUuUrho)Fi)PdPFR?q4fTcJW|eKlFD;jW<lxs(TYSgI|Z#!A&q`^
z5BXl)t=K{`D<&Qeru|4ARUe;cx(H}g0Xnm9^*YXkst{O~c6VW}ZCudB+~qCe(<6RS
zuTaB_dfSk8<??7y3OXDYaYY018wm8wcx)2$c&i+oZUudKC6%!14CYXST?_i;)>D0X
zC3o-$3i>3W(M*M0KTjdo#J||mH?Fz$qRS3JJq*PfvMo;Sb0%80JEQBV^gMFWy=V|E
z-HGqE=_NZ={<xIQ#4#E4T43-7HSzmIy$iHu&L8zx?NNx{iF@{^>_i(wK5CD#XxJVN
zYRD^r0UH)+`<+MvEwb+KRByq*Zdbmj+u}l;@G9r|uN&v1`pNqE- at a>XRxH3$fM$TJ
z0Hpv00N(=yUt^PeGcK`NHkX*^F%UNhzzBd1 at Zu_)^$4I2z(JY+;AN->;0nM!02<&e
zfYB8;YY4yufEfUD0ipqx1FQx38Q?g;C4gptR{(u~XS4R*Vzaga?0`D5;Wrsz0l+MP
zi2%a at 3;^EVWV8MTxCw9`U?0G at 080U)00IG~0gM0`1i%I8yuoHY2DlAS2Cx>|SPeh{
zL;=hNm<nJ6PylTVfnQ?)7WNBhatGiFKncLF0N(<v07wMb1ofSUGHc<N0$2br2Y>6}
zZ-5+tuK|7mC<C|$@C4v3K;P?Z));`P0CNBq0;B?D1FQwu0Z;;P5ug>I6TqY%Xba#0
z5DbtAum<2efPDa!09ODS0saPf1;7D(`T|%0OaO4X!Hi*-axDFT{_X(w04HIL_W^7G
z$Ol*k5DTyXz#Cu+z$k!00D1tOQ08xd+W?mUP6PZ3 at Et$_KsG=!z{1~|w#GrfT>u8v
zvH!)Z9)&Kf8E0Hr<8HgK_AGW~jgNFyr|lRtgZ0b`j9AF?@jor=RX+HOHAVxpm$6yx
z``9eEG+{U;bdO6DMp7whnfy^!>7y~9Pk3r at oG`;T+9NJesElRuVg#h7#wEx6E1rpn
zOO8&22tjfbKTSx9(vs8pR#8x=GQL-&GR`YGj+)Rj!FK$F at wmZqAwZHaJv}@|7#5MT
zj1{HAG%S*|iuFcA%RT;N#R#dew3HMoEH*)ysr)-VRTvo;o){LLk{BgS3rh{BVp&X)
zu=LoJG%8X=vD^Z at +`Yp*eCGrPD4+f2`p%r|>Jz|H{_W=L<KsK0N3=3NAkcMgV2~f{
zqkP at b%6NA{!0bR at KX<RW0=Gclx${5D|L<gFx~rd`yKA6p at AiBIbAmq69*Jgo$3-km
zkE4Xvso{|cK)iGyq_PTDKxA56Duprd>^9fS5BlpVaCH~V4Pg0sy9RoD&0u&wXs!UC
zy^_<Z at I)A<xRhjmbU08uYCNVVr|{E7k+FP+rp(xjk`t0sGLrcOFC~AZV>_NRg;W4D
z2p%NA9}IyjD_WEsN$O2bq4?oTq4MyEL?M)k6(%OyO&A}Qn8 at -VP4cM}J~Lu`)rj#&
zTBVQVTl0l!X(?%Zn`KtZSOG#RBqc2Ym{ZNuqel14fVc=LugH{S at 03W=rB9{1rp1Vo
zgvnI;$BB^UE=(r`WQsEM821ql*tt(9!askJFfG$7nG&W&herxWdHD&`(&N%8oIt%=
zb4y`n7NLJ~r0`SKrKhK_0Ei<zmV(m=2pqTklX)={W)1N52n=zZD_H24NyVllD}UTl
z(u51GqQ+ZAEmRITc7pK1{6J6NIi9{g0%t26OWyziR>}$vPZSB6M^=O=E|H2$PAB;@
zy;G87!aUMal7ds>qWq{djDw6}9w})_;S`exNF3%Do|Y~Q6s6*bV_et_s3wZkOa6BA
zP_jqZ9AO6h?HdsfV;Tmm<VsO#0aO}{Gpjp3;Ny6&q*UOPFy_Z6B}zmZnk!09M(M at O
zgYo0X6WWOqqX-kGqzaSysVV8$8>E6YGunKsbUg+~kGNz)Vt9s{!UE!w0RQeb12WUY
z7!F#><nJC7)EmZ(;di%{m=YevXUNZo6qbrkeoz^OWs#NAQex7=ljejcVR>KR`jlvX
zk}wH4duVrGs8}ICHBD$8*K at 8aF=tr8P>=9Pc=E{J?M4H8^eCw+G|DP!G(#&YE=kB&
z4l~Qv#)j_`9wp?%^qQii$@tVv)&z(rD}Y-{YNj$lRYslWyHuE#kp at zU$<R#)<-DeZ
zI8foR453J8Wk-oX_ACX`Me!q}W1_;TaDGyFOk5;CS(Frk5+_|K<VQro+zHEwOU4cW
zDx+C}fN(m0Zc0*kGR{R&Dxa`zkM`1pF;EC<fMQW88T`n^@bq*h?|9)dAv4cKsUalQ
zjU>Xqz}UESen{N%@U$o>2&7Vx%qpD^gv?A4rST(El2S!b^LV~nVq9bbe~xe&MI=`W
z&@ovg<O8+ca55)itZ-QzMTU++lc}4?)_{~~DkB_b<R|86`bQH~Igr69M&K8)85Nx(
zg4H)JS=rOH%+dd|PFNdKkS|bnEBRt%I=>e$QJJZPE>v20a*U9bN-|kRfxti!{VyC)
zjwtyJ39hV)#hR0%;=5k8tMNr*sBj*y)LoPXmUj0qO}In^;vK|WMr<6cKpElbWL*De
zHL7}`d|Y=Gg#RfVS>;MO9tI;3q{&C!PvMKwg;Q8T$;xQugdYZ at F&8G|QlV8kvd%ER
zwTO?AR_WF%o=i-M!97B(j0hI%qwFl3i8lPX!Wh2$3_cNiQ}|zy!l72_&b{YIx)8=k
zn8{yCq@#OWdTL^LCXouNej&|~)omuI>zpmjBsGS9a=tO at 5#VH<nyDNyM at L7PIgo{v
zWaf7OFm|MJ&Z7M4r4PVk8t7eotNEW>C4G(vcuukML1{+hO*pClBWnCx-V#jar-=Ab
zDay_YlaS`I;Y(q;7ez<MMaIE$%ny%@1Z9w)78essrR(9i;K(I~N5;k_3$cJ|N|N|=
zCBs8|p0fq>!`y=A&K1lF3=0Yn%vHsC`?|S$hxxd=d3wzeu>Re at Xh0j3k^k%<@>Ta@
zp%%HyQsea)F at XH&LE`ukB8p-d>Z948p_=`OLmI3s$~u`Ur$E<0uE5gMy`;}$u&@L9
z3UXSxo^_A+!XApAwR#2uzKO!{bRkR{XddPd2<9~9Dw6uIp5W@}l^&EXOmj_kjY^73
zR>?;A?bgc(6Yyc$EJYn0mXj1ROrru&ixVspg07}g`;n5cvOtUBC{*L3kqqe+&Y5BS
zm=vgNt}qq26NnoHLK35q&QsK}FpmgNjgLT0qMMH(x3HV1{}s<n8_-XCFYBy-t;v8H
z|5K|dvp!p=k=ffV2b9Aqj2g-U-oSM$ogbczo#d-*l{g`a8!Sdd;{QuNJ#`)!>7MD4
zYCI!^Ju8L$Jz0P(co^49v_NckoN|IQ`To5;_lQ?5>B at F`F8`!I|9{L|^|*XAa}nPj
z;;6U&qnv-PX+m6lp*`h8MtCw=bQ${S^_1 at XXwXV~FV)j~%n4YgqvO(&Sggq2@(F|%
zQAt=tpBc{&Pm94t1k<fWSRTWWG*Ek0x(Of&nHZX-TSek;98p90sbIT8(@>pLkLU5q
zU;d~xv}#5(x}z_c8A+fydL)L&D0NFvei?NacpOXMyk%GgdJOtc3Q=giLBk_6nyd{f
z9rsiDBS~WSToxrSk4yb%b;j&0l^v+A01K-0&;QUpS#yQqQJFmiGnt#cG@}SurkMr1
zS9zcx%yGU~^hYDQG)|a-lOi$}^$?gsnV6Lf=tt95NP#SiNgoH=9kw?E7(k_!eL at 4v
z=+?bvfN~6reOeg9wPC2crKKdQL<lP-B{iL~f0K#b5-y at r@E0_RNR0SIS(XyDFqPCv
z5>nx)(2{x>)t&`H6kQccJxBd_ijoIZe=8Y<vALpPm55FueiVWO6-Oni^;Z<cXgdI5
z7%duwNjRv`jLabVtU3#FGgxPdiJ9s(Jt9-7Ag8k!rR87ic6b`h;H5&A`rjrSos4ne
zM$b<B>uwo%K1t`Bj`-9`yCP*fH%4unkbl?cmy`E0hsbWV<TurC9_wAAdv?W<Y#r;9
zf2|vQ?%OEi6N6vy5662hIrXyHwJbO5=AA+E*855R#Wy=@@@|NOixT^l?@5SS{wCtX
zlUiYc??MferbO+?NN3*Le+;>W7x~Ffi;UyETU{65N?Q{1^YvEEsWWeKW`D>ttWPM`
z+x2!&@ub9}qcd*Tp1JGtrgZ-wiH#FP3m*us8Q#7(-}(A)`)!&=Okp+q=lC~V>>plt
zuDIj)(BbEg1#j7S`WkQ7*^}E&vPW_AwZe`z8B|-!^pAYCBIWZw-m&w38ysHYY#m+l
zt?Rv|+Dq<gl=AC~#u(pfljI#)@>y|-_O8}*+wE?iq<^l}SvK(vi??=<?k2M$qlae<
z<5yZcCvi6?My=CW82PxvKOrF^Jkg at jMwmB;74hQfM(xBecWIbcbZ}RPoag;h-E>&!
zCp*#i?~`TH75S&$KNx&J!pr)O>B|*2z7~4ld^a!rsLxgZ;wcoXbmt?RGdEp#J($(7
zvC%o{{Pkbnb=<xYFN<?~-;_MjBR}Rq-O0sw(yck}e-75P3-i|7SG&US{?sK}e*0Y6
zBaMyq%hvD>YORW6LyqO8 at O5uSpW5CUe%0tr^P-~KrqRQS>JA^@(@-<O`PlqbhR4S{
zEj)YTK;r3gzWC(Rl4Iw-H+WQ{`F;Hn%5mnczYk^9|7bemE=Sz|UV2~s$UkzOqBcy6
zPcq!IAbz?2HKW!a6}sz39%Shq*`|}_zMj`!zmxk_><f({U6tB#p&=2kFUJUTme?l_
z{7X9_d8zr$u9mSkBny_`F}^bEeoV at PQ*Yk1m92FvJ2Bwa+QW<KowsjiufP7&`N~Fz
zxi230K94zbJtm~|*ZbPV(`VZs^}I9Iu+iIG at 6fARn)ZvAb6l(17C#7j5VNOkZL)1<
zS)9k$$HFfU5=WQrs86x7e-t}+V}`*M&6)aVPW5LG`+S5}P?^)|3#0VU9{p~?@v)rv
zV+(gH8Y*qC)fG#(HH{m5u=$I_l~F&8coF$z>&|$Q-ufi=UTxj2)9sDqc`-U^{X$q;
zt7o0tXtMm|ql06QeCc3bV(`P-`tJ<OZvA<p?cR!^5AN#UtiQ2l#-p3hJCEIuO%~tz
z?Dzg<tG*a<>ea)H!zmdvPnbPkz|BvM=P52ZX-6;A*XX0zCj2JuU_|E)MMAjXT4MiY
zkMwptt2b;26m#ZO9 at BIT9}%<rb^pb6J~QLI?q(!Un-zck;JpR6o1*m}xU at SpP7XL&
zy7$7iGtDcn9i1st6x&$5ID59B^7JK}^~VB!-Fe(n%f9aPdhLeaM~5^Ao{MQ3K7M)h
zv6HjH&$G>ALpO{~88f*||M*X94XVr^Xe}sgV_TE8*w%dD>InM at RRPvxITsS61RWV!
zYj!UPuG!@3%PnZS=yj&@dI8<`_Ht9l9|pd~`+c$x7O%AyZ at Xqu^p$_#%2~$4n*wg6
zb}akOwJkiT;ox|a$HkKyii<2Z<%+fD7n!d%+spdl?py1_-(R-h8ycGN*dj4e at nE{^
z&22^te*f7rcjF(X+rQ>}9NitBvA68khxGHm>R!^8;^r#h(F=F>9SjYXZ})H?btNGs
z?nCO*g9)~dZ41Wm$LZ?mCplR3eQEFU;HXY$^^(BUr#8Zbj at K{8oGGca{aLimLNalO
z&bRMMw+}d7m}`{Tyw}R1?dViR=F9XlPdYx!{DSM$G0pR|d^6kKvm<0*S^HL2TLj+K
zC@|gNa>l4oOb`FHvdQ6`;e{Oz-W_L#ezSX%-qlTo{d8GZ7JAw?2&55jlP?84%m at rU
zbJ{d<$Ijc+3-dP{ZCdA7)X>~#@0FVRw-2AJzx?)}g$)sDgCA!mG#3ZDY|r(bKd-M*
z|AE6zd3RDBEPrqv?z}tUgYfZ!$1ALKFNZ`q)Xmv>aGl1Z?FD8-uk5y4{GoKrp@)_S
zp4Cl1ZY}P+J at KgSn%^uvYyUP4s2lB({Vp~`_~=#U^v_RtTG~_Qx`QW;>C1Uh8Zi4<
zq37JxW?`mnTlV6vmyiECSNWl9#k#s%&O0t&d23%FKBKel`(=TpM;wK__slL5JL&B$
z8dm$ZSU3OjL1W+0wlJf_4v*ibHzj>-R7tt at UGS1U-1YB@)WnJ$*Nn!Q4fdP0A6u`z
zP|Vtun`>S=sK9l}7iSj47SS1QO-+dlhWJ{WhGp9uY_&EYdEbIHtuL$SRDi8`$F~s&
zrPl+Bzw3XY<9<j-+xZQ<E8A{uYI-Fr)j7DQ(Becwv+dR~ZDaDDW+q(P at 0ofd#XPig
z{1}gi5AB<ycj#PL85u|i4imog`Sayb_Aixt&12T(+Kkw-ee}tL7h2zJZ~idl%FEkd
zexR?FChX1mu;A#HX}a5wu5`%#?XacAxaX!ilO}kK8Iqo1t8 at Hes^>p-3I6tCkL4Lh
zLnG%jyuHkO{ILE?@s&4)xeYC|`ffU;KfJKyV(N|`C9Y?3Jwk_T>LfZ0IzQdiHqXdt
z)QlqE7|p$b+2wCDgH~OR at c!(A!>UCc!;600ZFKD3CewZ9tiV4P*!sTT5)skR7?62&
zfbT=E;Ow`48?76 at ylHVIqF+Iw_1rU?Ca$B;d{)=AL;K0g>_rDEg)@`ac_x0oBS1vk
z_nop=M|XI9pe1*#aC)EC%-x%Id6s??ZNBc8kz)$Zwv=9e at l#=)JfitS`S7;KO=lmL
zn!K;uZ8%+AFe3Zty6LAZ>ry*SFUL7~Jf5*U<HHxl3Br3F3$iav)(v>J)WP%hk%PJ?
z+qd`q$?nSZg0v5oc!4=<a(tym^37b$`DGsLdwX<s<dv7TkFF@><n{N}I_clf=o_c&
zyxV!34Ij1z8AQDqq#Lllk*jCDP0xAeLjBa8BP?dtwhkVW@$+Y+2QMD7U;lISAHtsw
zs(kR9*+0c`124Xq)K^jTy5FxOj`UgQoo;NhV5;eGn=X^(Yftv~X<a^`#ly#;Vca*4
zYrm^?I at PH^W$H8c>H4{Arp=vFK2_+)cAht2k$p<m*2(r&cP44<HJg}wF2wfOt&KK+
zC)}8DU!#xRw|^#B?*3-4RhMns$l5QgM|k^04F7WEj$y;LJm#Cev>ZC>__8sdHJ={q
zvH1PyC3 at 3FbyzI1u3CC*-1is%8GqpC$)A at OexLgKuX#%j&L5J##qM63h1L3uvA+IG
z)1D8Y1V7voExRYl_AQycvOm`_YiPu^6~9n9nd^tlSaxX#XZeRq)n6VSUz+%pdv;Ru
zTZa_cw{MdZ*Aypw at gyUjJ=ZpNlEce5?#e?E(@m2iqkkJ4?q4BWe6!(K;U8zCqE2fL
zi!O|7iQ!*v at Eq`ysn?v(0%m85*3Eh!+3b5+*J93hCl+|`x?ki|^!<5{L+#o#U(In5
zR9LQdcc1XPYx+E%%b3SrGX{Sxb at PjT9vH*63z}9c3emlNBKYg_&VV!frp$e0vcm6H
zc9}oz_-Mg{0R9(io<`3<^3^Z%Ca#l*YQ7u2aDgCYQPSrJ!g9<fJv_1Gb<4ABM;<lp
zO8;Zwv8j&}n!5g)5OeZREyLxl4zotI@%XLJg17zrB)nts)7D3y(>L;;$_ng%lb>A}
z_jmirejjS;ufN}xxVdYuc93G6 at u0Wn%NyU#IKS<U=-|RmPZ{gwN^#|j5ze{oeL_5*
zZ*bM^*g5v{KW{e{zW!a|`)YCMvZj#9ryGqV at 9#MNG3{>YKTDdW+mAh{ANtSzKW9(A
z*JzN?&=$S-c1dH~%~eOOZ*hK!sI$Ae<9dAR;~SxaEbEQC7F`&*Ve9$qF?XuHT+C{&
z1cy|<o4T>;=hZhVHqw2{_Z;%My#2yAFjBP_pZC$PrF7h{xFxOmeb9~aYu2aOS6wz8
zT9@%Y>D%!$#(p<&lx+RhX}@mzEih{Hi@%3$ypYqfp|hrR`?Ukv+cx!c*!olE+aE1c
zii`SbWo(&s#`cG->o32znItLH37h@(qKAfS<D}QVdGcdU!QIz0q^rF+lH%dj`T0 at b
zi_aO&TmAU(keusx?yU;EvOYKRSO2^zW&^%5OuMyaN8O{nn@{uiT;)XXdz1XjZ!4C`
z56<p8`cU8fDF>{o59~Kv^?di|a=Txb28n)goql51`O%#_Ub;>BY2SwxJAd3<_H$kO
z`QpC at Y9BA#?NTE7ef0^0yT2cGI>I{^!Sgy2B$OVG9oBFr%+vI=_N#!Cwp-VoI$qFR
zDsHhjduP#tb5AE0mErss#+06vUew+9>`-yvkj)X_OlWVOd at n4)>Xbvnk8PulUnub9
zW<|A}P0{#Dqv7Pa+q3RB#=o%3c+e7T964`$$UwihHoIt(?Z$7Hbnc&VvHZ&i2X@!Q
zxN*}&BT}yZp1ShDMpLss*6&XIGJRW}*;ga!YlCKdlm7F5e)ZwnnajD;4o%qc#l^K|
z#W7BLb*!(B#yR+XZV>il^P~3pd0%b*)A{;WYlO#JrrclP`^~lKqwF%)7`OiYN5;Il
zhK)~MV$b<^{?s|P{rvXLo?~o=E$|K5_UKiL*UI(We`>OJyWBD>f1fm`Zu_LMCx#bZ
zFx#|!$I3Ay2hRL(dIjH={oOYm#;<A5J<jt?ewa6X&+w9O2ix9w{gWjA+ENqVo=f{5
z>Z~lwU0kJIpSokwi2)Xm=bzl$G4+9|civx>*IRP3<BUGP{AGe?M%B+e!^<_XN76^v
zaKgQJoNW51D8>C-#f|sbe$mg&C*KM78F|WRl#5nLb=%=zcIF#c3_5&w)yjq#$92o<
z$98;{yk7J52&d?8zZd6E|9sukdFw|9E_Od|tJ7)lV2{s`)7PH=`sBfPU6PaIJz at s@
z5Xep)`Q(ge`;z9*y=!f9-rNoPOAxtr$Ml3ZHR2lsV(lx^cm<i4Cx^Bk^n19_MG-j1
zs)&A-o-aMvzio2=PM6i3A4g6rwfsyr)OA_VmO~9K(o2UI+BucXf4b=UpFxMS{bt at 8
z_(YL7)G0#O<EuM=$tGM}y>@Nt&23Ld9eLybZCG&Y>M6GKrigXF+5I@#?lW%18pEVt
zrxgG4(B*8!n)h0tkM<fcYtBE1UM?LrVN;)N1<T6D77cFN%%5G`v26T7&+>AO5B0mE
zUE?hlZF-&QIL3GLrtP6Go)7<1YhZ%U;_QZh)?SbJOJ33(Hg~OV<z!j$@+J>fZ0XR_
zy1#87<bM+!X%qhD_At)2`0vmDdRC{gLgSo$^6>)!x?I!m=cEl*jJ~?7&zdh!P!DT(
zzc(3wx2J6X7>_;!9fmL6l_QF-ZZy_dzPRh)wX`2<(=QEs{!7TrO=fL-9S?lCvZ#+h
z`<c(uNXhf7g(KYW(XO3Q{+XY at nK)#<>zyMb0?yt3UM{PCbL{J%1o{z1?E`h<ynib5
z|6%G~`;obmwtTnAuWS7HEvEuUyl<wr^<5JBbw>Y(6R(c9-}{?aK_9{6>6-ji;xkLv
zwfxcV)xs}6%$Io;O$&NHRC{%zd-$}Q`>sl>ukD?j?clodcIb$z<YSVhD{eo#bUx+w
z;Q4w-etOtC#N_3w%ssOk;x6|)YLxNY!k;QnIaX(D<aF)b`sWr?OMUwt_R0PhYj^jL
zUQ at Z`&a`pODdW6O-Pq8+ile*n at yR1!dKvB<GX99U=d^k^>-ov=s$Sid{kks3|FgY^
zuPnc6Ky3&=75!XWtC{#_b!;|0GYTKKMc4ndPSW{-sqr1($Rc-5+7`8Or_tT~37Pj!
z{?c+wHe_>sQ@(DA_t at +sE6)CP(pu-+bA#6nK4Bacf0+N`<*6l}xn-`+gYMkSO1j at F
z at 3>j)FTRmi(=V|oI4WUJ`G<%%%L|0HPfRox`bKIeHofIJM;3Ao|8Yv at U-XVMUUX}*
zYwOQ3OVXxlwqBpjxjD1mFz>@Iz2byP#e3e)I9il=_e|~W{iSbQCNw7gA$YJ*bnmv|
zwcoBg&mYlbv){j&HRWQ1f6lqO at cu)OcN7O7J3su|>5W at Xp54V8#Xh+$Oe>#TZP0Y|
zh`!A7^OO}|&5QN!QxQJ+w~}aU=cV^tzty<AM7yY-U)pxdc+8R`c at piC;?K69Yu!bk
zylJ;gr}k$a>&?VXx_j0>G%7M%8E<%oo8)Z0E-G>J<H&^?2?_ok7Kz~zc|x1U7ZI#E
ziP{^VnrrO(ay7T3;ve4m5aHpb>b at sre$uj&f4 at JKzarxP;0LC6ti8UzvEt>so8Cg7
zqv7+W6#HM at S<0erp0Rl}>%lHp=f;f<zg$0`bmMl%JGVGl{KVv at _XlF~J?<<%S?A8N
zPPfw>{O3MB at 38xZD{B3;mP{SVcHLK|Z){v^z+V#*TWrNo$vbu``ljyH at Yd~%n%@|W
zZmKOhTvs%#reV+V`Ny0Gj6ZI;>crWFPUWW)4?I07=6`?gSczuIBLnJ4{r7+0n(6ps
zea0cq-4Ukg_xg+fh}7 at 9A<8M&Fe!f8^7sXNT8*yhuh&)lsK+`uGD~OMk#^pC_pi7+
z>xXE(h>g>(?0Ov$5}G57xjZn at eo1nI_Fr8$&6i4UjBPQ#vwT6!{aIJuoO+P5wyf>V
zfD>hIix028b^G>C`lsvbvmF{M&-*@jG57kJnCHKihQv%S*1qp~)P8oO;n+Ke^vu2O
zHD|qY<t$(PU~ya3o|p$gw#jSTJmShSFNYudx-?om$SS3N$K2RQ_E!utHlER+sX2_@
z|5T9Hh|e#ab}Bo1R)5sk;|so9cr2b%*`U~6TzAcOT+=q`7tIF;{}5Gq_(|l85u*5=
zTiHqL^|tD2 at 0A<bPfyc{$<tzm^xJrD*6K$mmz#WfWb8qM5_5;|>ev48=dCis75Cas
z=-+)Xbj^+Wo6m1Pnh|^dSm$SV#L275`v3mw)QB%q4re?xJ25jOpS$3(f)}3}t?hKF
zkB0ujZ-m<voe>A)!V?rX`X^o!?9h9(tiiDU*&L2I&{6YP<?fgf;dP7qzxIlo=`$@k
z<L<%h at w1w4FSzIOKtFnNqf`6d(t`obXSQ9KdGy*!n_`9R?AaF<mrhp}1RPs$V|je%
zuczzmwSI5VULV*TGJ1GZ%(-LH%g3J&pLH at c)|@>iW$cFI`el==4A%a%K<k0IHM^}4
z=l?)+Th|Hp5v#{q2UJBRUf^V9bO?eM>|W#Rx~b-3QvvsS<r%NHZFIpO9Zi?_7yB9%
zAI$dICbnMtRguNDS(SbL1Db{#FY8FX5#Hwd-S~qIL6eIgn^+VTH)x4-H?1}=n*Rf9
zui0Viw|Dp2U;h4aMrf!aG120t>+}b|FEHA+G1v0vueY22vHPe8zie+t_;dQ<uk_2h
zzp9$WmUk{36^4c$+~@AGU7nI~Wz^Et4{?sR2?zOO7PRT>=#J}a;gIye!~SJ;sLs)+
zsewy65`;Eq#=Ly}vu$OG#A2Q3Tb&&f2W&5WXOvrb+G=le=G3EY4(Ts574fuZnd=4f
zta;62rnYDLYRMw9-79^qzq%V}QN6*mK%>y;jLWaXY4JISrb>q$7Yv7<>G0OuwELTW
zg`2J}yu#8IG}wA3zm1S)JPf#W`b=ox&K-%S`GwPOuiIp_xw)apujb0$K2ILLt^eok
z<@IS14GR-89}jj3EN-6fo4dWgQQvty)8PXx9a8T&4|n}R_#t8UipL8chg{aRnp5Wx
zrLpedPP2mTkL-3|89Ju)!{P&$4-XxmUiWN!U$ONX-J^-Mo|eDW1(^Q*F56 at DBVk7D
z=hHJ^*;{&^7_4hfar%y#G&`X5#az$AW0}I{)Wz9twtqc-+12%-^4zVubt|r1-r+1R
zuz&mgI-N5|N&}be*)4Q*5*N)LR<u`7xA<+X at xjaaVQrzl9vz8BNlnv#rz(xUez~Bp
z+uyFk*%gVY6^$9LIh*YpX0Ek<ti6j>e4*4lH+P9^!Jya$XTEUDpo<nHHZ_ at A`wlU%
z&kh at DZoPFH%i{j2B39oWV%q at e!H93aD-O7RzvDvx^KBg=ZI!z>ylUEX>!41l?1V+(
zo~^dc33+4M##~Cse0n3*bAM;3dCEhNG2^3~?H{hZptA$a|45&g!eQ*AFaI>(TltGk
z?z))K+jop;y>Rg4hvw~XZoj-T<r at 9r%bdLlrCW|J_;7T)?zG=>9afIBusl3T$MpG-
zF&-0iY%|h5Qy(7pPpJE6xrf+3GW2N1<+lxU>K{Jly}43+rKKUa at X)5dvq}nw>;JeT
z^<wTBSBd8EP>(?li8{8X)6b7GGRlkbEt-)XxK}eM^KH3z#N}1194>rTG`wTcF{9l-
z?lawV at 6SM%`Fmg61q~4qTdrmXG<rSs9pLviJNU~6>x~gtEN)sC7WA9A>CD{E&d}?$
zcQn;4%6|F(vG*QeO*CKM at X!PlkYGWu1x3LEA|N(Y5^88cKtM$#K!8Xfn1pJhND)!0
zfQ=$eiik>81nixrVn+}QcI*xHJG)6Jx$oQie?8ClzR&wz at 3-sm%x})jnRd?X>@wMX
zWlBGNh-sGO7hsn?XOV(l&s1s2A}Lk-b%bT~S!snKj}z+5^7E3$d!CG&srLR#UFXY|
z9XX9ZJKXL(eLHn at UDrw3!j``2agocGB^}-D-=bQ}xH9G|`Kig`)jxwm at 6&xM&uw1y
z at r|AI{4Zt;0&Aqpj^rq0^~No`s*|Gn6Z_K`5;?tYzS!0qexfGzD<!25-XC`5^h at y_
z8;?p*$41GGT3$1<b#a1hdQ`j2inm?T%HKSsZl~A{&(s(`!r64mgz35d6CYnPoqQl@
z(j?c3Gse#uQL6l!ws%~~!_!KP%1;XO-d`N`CF3{Y$n*kvj%Csq{Z*q!|I(T|wq|Fj
zV(4S51y&}V3lnDFT6`&a=b{l`YnK_l(O(+9b%cK7BHJaRHgr7~MW^}uHnHa2J)@^P
zu1I9AW5ZUhT{n+uU-x;TLlAkO>hmOVT2Vrw+S|FmrfaOeG}X<@a!R(^2IAA*Q&dzx
zjF}l+p+4()$K)A(t|sbBhp*RIKjGu-V}WNhKV952Xa0dh{(E*bu6KI&g)?bo8T-D@
z?x2)u69Si0XK at wZu>)@IHQv1Ke()BHD(WU#sj(ZI-Bd!txOu_kNhzV?*_St*zx<O~
zr&;d1*(ip!;CqMP_r&KumC?*~L9bSO&$Sh0d{{8g?eG>Uci%C~XtPQ at U7w#?PA|B1
z!^7ibx91eG<6fPN9cH(#5GiAF6fNu~Tbm~Zgit%&`>ZEOU$I<OootoyAm8Ndo($7r
zy@!nrtUnt?sGcHS(>5{~>BJ#Zp3XGf9zW6kowv;j9Z at gGfV!m))$P)DUmN3X7Zsnd
z**N;q^7_p;S3O$Tvzlo4aHZ$#Xs5iGBWqqJ={nE&A?Cs|UbXhn9N(^a<HI_?tgn7_
zr1?!ZC;!e<{bSD0e%<kTQsbrlI8;{R?R4`6ZypmzzB-WU at Y?kwt!K`o$IoBKUVmAl
z7x#kUeDde0n%=(FwhO<~nVG*=3 at iGsEI<3l?a=YxGS8B~I+q1}K+nzIpN`zpyLHL*
zcP5U6kJ6;nPgiE;e%Z0>`)BI!Yj=XzxZXZK-|=qWHo1FCyBBt>|5W$zSl0FjpH$lJ
z&$oDT%SYyRdy(hc8*gt{-PAZ5-r|-g-kRN{bN#9Rx;9niHRoJ@$)DYqs&@YF%*_|Z
z8Bk6;I$S-oOaI5I>k$VU2|c^6SRFoiIpJK^#Y-E`Um8JpchyLedo9}6u(|QNa+7GS
zM$+LlgGArHpyXL(&6MZrN@)d4_oaK-m+YGI;(cmo*tx8_3tuxgA8OvWU{u=v?;$xE
zl`PfWK at y|(&OKqi=R at nJ9oyz<#apbE+$r1TlF+=J5f`@q)pqiid)ve*5wYi|Rz~je
zh>dWPYY3ZE{xtml-PWxsSM8&g7r4hLj$0IclPz2Hs3rR#@pyW%r+8CIp5M2!m%$qk
z&rq;9#41%NJ#>Cr;k)p01v)S1<OQq<%&%TX%KkdzY|bLX54jtE79Xfj-(Pu_(^4@^
z=~<OQVSRPPwQWbQ-IF;s^2p*Nl#y=b+vzJ#+?wKje2m%J8oSTKYLoWOt?P)ZI60v+
zvSF3W-TDmO*O>p;)Opd1r7vz*s66~8!7bf!en+qNG at rHi_upDjd#*zL?ItN|9P4DK
z$1RZ<5%czjn)mB&Kj?fIq~qi+?_i_knAMZ7_5Hhi)@X9+*YyuKG+y+&P<SYSEoFGE
zi8X!Kp)LLzgmGh*<yHTP8P}4j+}xvffRjKjKTj-`3N^iyt$lduxSbbQ4`1w6c{B#K
z%&}R(NPo3fCTeBxqa{z$W9ZQ_tq&G;Rx~G2R|V;)FMIJ=KHAnPsN3N6ZP~BO8 at zjG
zea$gT&pNwmiq_0WnU2&g6xQbppQKW58We8w?Q0x2FRR6R$JFXsS!v_Wsm<Jyef+1X
zk|>F|QT}5>@<FqnFMCHjEtz_7nbX{fiB;QjzFZ$2*u1Xv^1+eyTO_-NopIgjlI`F2
zbb?~_$D*2*mSZ03x1N3$#n>Fyx#7wjxidj#K38N%9^f4DzCaVdFyl^5wxtm(<5S=D
z--&NLZ8kgHoj+c#R?VtP!azN*{O$P(GO at Yg_sW$QdfnPGt1UPw#c%S*#nZotMea%T
zOq#PSc1DWR>k1=Rdzr72b0=9Hd|2?V`S`Eohp$XDYqr_%RrGqL<}bRw*X+b4%Q+qQ
zzJ+PI8$Vm&vn+ex^~ej~PU(3ohQy6zKVCEcigTAunYI0IgU>w~)5^BTa>mYoJ61fx
z;A`Ddwf!p3C#&vW5lq_NdF!x_bNS`hE2|c-c+%=(YO}fg_ba8FZi`izcVkSXFKR!3
z=D%}ig!=2u8;Q%m9f^4Cuy&Et+(m^6(vg#O{GQ52pOUIvRN#Bkpes+JFZz at sWyYMt
zpRCQbrv!e8%Os>_%&HG2rr((u{PB`Sqgk0|+fR|kbtKRHFKI3ls52LatjS7Ce=_ym
zdn+F$iBGpSyFPPk-MO}->g8$aowlKs&*yt1lRGVSDs{0B=f2Q#cSxAh{*AV0U8cC?
z$%2y&BByR2s_ at erBPDG&k!`&vziGzr>J8C^kr%qS$?|uu%`B}yxIl?u5|$r0_4aws
z0M}3vd3JNzugjcEdmZ!MO?f*m&GhG?g+;~$m#cwRZ-zC!+va}XX!;J1ucV%Db3&Gr
zQYPuzO+Rw?<(~G2W8cm{A7Pvmuhc8&mSf3~)Ze?jeyf_^y|m=r^E5So*-W>u-JRLf
z(HFmFy at GDn*q|ak%_c$|r9^DmQ{xkn;l%FFq`=kApGQ%iul)IL#nKFB#4wc`OKC>u
zw>K4Uo?q15zJ;{F at 67Zy8w0l;JA3&}`^t&!tgf6R!#|9k^w{EHNcgBLj9Vo^az|@V
z=QxXOKEH5Z(XTMoF}t6@?f;0K6PEi$dyXw!dUyTl*{qJ)sn=^M(&FL0M{1t#%9W*T
z7=J`_l409YvmbsdHJ;!5d}g^<Qo+^oqRCvDrclpXT55;Huy=x8222K*&ZaTvFzJ3?
zTyLT~%Y%*tGHkOhzLy=3MSqRwvRFh<8k^`wbNAuzDR9L;NGoLnB#%Z*agc)KWC;5M
zX(1%th~y=QL)aCF2sj(zZ)lbZ12O>I3G!hOb^;m)I1!DKTnyo0pap<i5J8dvVQ(OH
zz~#U}fmAGz8Q@;XFAiaQpwVcIR5#?G1z|3bF32xJepv{60I32#2pmhl703v159G)6
zIRi}qoPkD5+Cg|DkUrqs&>lqyGl6CUt^qCs6c1zx_$%ZWgRm`-0+gQ%<xhn$EVrbz
zL4Fp>9|2)Epeca!fQte}0FePdhWyZhQmcTJ0jEOwh7b+~S_Jq8ls^i>>wsngt^khp
zXB?0@;E#}B0>TbJW03(gWt5~2gad)}Kz<d<9|>Vkpy_~1fn)t04P*lN737zOunW*6
z!26(lcL;9=S_=3+ls_KAen6Ul>wwDv?F6z0+{YjP<v;{ze<XkW*8|N3`Dy<6(|}X}
z9{?@_6b?iJ{D?pPD}j^%C-cWY1ZW}PHvafCfMx(b3LLBNHXsV%_x$l+0W=25ONol`
z#y<dP9>_2A#~-X&Y8v2T;8=e}0T}~+!5{xMKobG);gA0&pe2Cs^2gs7NCWV3;FvzR
zotCl!{GC7kSe{YP{xkgX=K#StNT27AKh~!ZFI at l}OCJdY<1GD at KmMzMpr57F_~X9;
z2>L;~oj?BIZBo!K=_=ruzU at F3fIsuc-w{Z0(D(-d%?EiCfBe0G)Bu+O$I6QVG6npG
zKmKchVBDlL`QyI at Xc^!R{`j+i<^Zk-j_FGPq5}T)FaCc@$p3TDQ2*}|^8X|u|8EuY
z|08Iq|G)be|Gy;U|3zr1|34S<|J_3Ve at DpwYtc~u|MoBbe@@8%^U+ZMe<I}nyM+Az
zrjY+vqM`o(>0kW+nvnk=LPP!kwUGbs7xMoHLjHde4fX$@|Kk5=g#14j4fX$SA^%Si
z^8f2X{(lS&_5Tn5;{R8K{J#VZ_5YVb{=Zkq|L+O;{|PkI|9||8|6dUD|3Wm>|DOr@
zf4Y$W-xBiwYBbdUzx<2;Hw*dyVKmhL-wOGEmXQBH6!QNDG}QlpBY6oCq$nXGGD?Dg
z#!HCE6C@;%l7xu(7zq-ZC?R4XFCm7;Nr;G!mQX<xBt(b`64FRnLPTn;L^v{ls>@4=
zLjG{buY~0vN05-j@(&v$LBsO9%1el2`Nc*{%*FC+DM-j-`DMmRoZ{t21cZH0NeW3K
zX*3KCM-pfR5=Syf49Ox<B!@)MNPI2h&SGO*wTXh2k2f7##0<paKVjm>{&nrc!S<{U
ziXXa;;z<QEZ23gg&>;FUI2>&ME#1#UgXO8=#$*lE?Z)V at 4IAG<KS+k_7_1!IKMKn)
zUu;t?KNG(FoWC^Vg!sC#n4JFn94-s{0S#WJK+lk}aRKj#L*8^6_8U=mwmVj3UmDll
zyZ^VMe3>Vc=G9-1fj$%D6!axeH~)uQ9Bf~#Ko7PtmQCm2KN9k#bG=!-?e>T$_~9}B
zqhfqJJH8Q}ICtT~c^cYUbFrVav3-an4<;0ZU{u9ngonXsOTl;#hq0E0 at g<;9ND+-k
zlhIT(3+bT6$Pn2fcf>)FC>NbU-AGh~SDw7kN#LIf{Bsol9L+z+ at K1R}LD<^~M8Kwa
zb-?UR7IG>f6*L!-5DkT+Q%FQ4Ttq}vL`+0nWSEGQh>VE5$T$(Ah?a<fi0k0;1!W4#
z!pay6ry`u=;8cQB8P4%=PJnYFoCa`Weedf}<1*ZsbYlN*WNg2&rzdm}o&U2wY)|vR
z4uAfReB8qMDL7m<o#s1`9@{i7Ec1gg@}tu+C%}K`Ndp~W>&b`<G<qHxc>{L>vIJTH
zqz)v{mxXzDn)F(<5+dKA>`Ss2DTy=f8wcY?`$GG{xRcsKe6ffjf8e$hnx&<+Kg at 1I
zOg0(t3m!J;UF#8UGhRMR3KgR{yR3=CS1Ne=2mJI0)TZFLgNKhN$Qn;O)I!KOD24RK
z6T}in^M0 at 2$TI_zBq5wEgj0lYsu0c=!Z|{?MF_VF;Wi<BT?lsx;YUKaTL?cE!cT<o
zQz6_Vgr5uH7ee@@5Pl_u-w5HiLbz85zZ1gmh42R<{80#h62hN_ at E0NcRS16*!rz7P
z4<XzqgntQPG)BlCCO2(YksdF9<TrXCB6HO&EVDZ{cwRH1i~;tkso<9V*|qe}$QHux
zE2xp$Zj^q&;j{E%l8jmGm$6r6$C`}EvwG~J?b~e<T_<TT`?{sG*JEvl{0&j-`YCrM
z-&daNYHj*HT)n52kQ7s?{qDKrn$vT1XHMVHLWnN{f6{2^38lB0stv;aao(Foorm)F
zV&$#qLS&}QwsU~@@bK7OI`XONZG^;yfOo!JO6)cz7QJsGl+k(h4WC@;?tKx`@8hM{
zbs6z)@q<Eg at uoS}=Pb(idM4*u6WCb>RZ~7MIXU*6PCVhFnQCn-A>$^buZp>w-Pu>C
z_^O4lLmuigQcWrBmx3=Lq?xb_mg$YF%SOm=={29*)<UQygIr9ZYkHa0YRMY#-!YK?
zjuQK#OwSh6(;#2OlV?}Ut$%IYLP$18#KRX#tvXvA5ob{UHljqS!MHPjvfN;df;NvD
zjGs(<NAKDoZ+3it+xm-!v%7WAp4QqXwZk%FP0^QeTIEHFM_+Dlv27t#e}wwn8um)H
z;O)-mt*ebvtGPd#G;@?^b<Ui)Lhq_c)gtwkv11lrrWI?9_E|p4v|`_n441DnGB$Rc
zq0G46LMY)t{xeI%jy#%m+rzPiP~?Z{lQ>|o`2COG?(y<lV_|+<>hLv82xrTlxa at eh
znXsD+?Y))mW?(*F|MBr=Lc=DIGfdu~vWDgY#Q}SwshvPU>sko;^DzA_Zsl4zK|fOg
z8}V>9NyIdIc^lzG6>?4AU}CA_yDKR$xs{Nt4EW*d8}35+J%sQ(y+*O<oEAcaIh4QJ
zFp^Z@;I+P^g%CNOhv`D;Q|`@U^r&35tgp at Lz7RSi)ONvwuh;up2?e#h^29gRy>yw|
zMyQ&@!v^(fmd;7g-s_;xyl1|_lce(Q$Yw&}C|>(fjCjE0w_qQ!kiMhz8+w`e(LkZK
zA9rfn*oJ|<Z7YHDPp4}<vR6CGH6D<YTu*ab{aXputH7QlJboqSGtVy5ZzI${Md+)<
zWyhbo{@KM$drIlD^aJd%-{Qn=M0>~+Kt3DNA6$|nN`0p~VFO&hU at 81noYrg;Q;?#(
ztCf(-;!OZr;{HEo55i%LkV)tEwGs|4gZf<BPpi>QP>eXxMu<L#`P+-#w<{mdP8fu<
zFI;VoIM7N+j6kkZ5-Ab3&mH~8pKK*;Q^MMFQ7``U`;_q$uM=|R0Ed*c7OZnuU$U!>
zP}z?8%eWS;chjohnkviZzY}$h&wN>$GqGm$JdwFpX?K_nm%NmB%Wc25S?|<d^HhTM
zNl(tzGh3<x*DTq4!l<fj+Fh!9oR^M;;@;l|ZG;1xF?*F-ud;oI_KcuDi(Qt9v$Xd+
zl<Nw~!|c`GM|?>lpG<wHm$H1(E6w at 24*Qzg2w8H_-{+%0KUOL&E88YzTw8r2I<)@L
z>v=-?6DKezikp??izZ<Hc&(^wguh(X{#HUx6J|eaMy;jS{H_geqSox&<5TE6>RFtc
zqse$u8zFKJue~Qe*l1N|G!srlfW4e-8gWbrR|sMG9bF>Zt=b4tYw-T{LX}+<J(KH%
z^e>>#xaHWIls&PN(iJRfWmF$t>Uz?1VC1`BF7t+2r-biSz4hg4>~ymWcDqY-tV;9d
zDt?+cKNjUO?)-iR{=Aqszo|Y7U%2wqb;8a?pwD~$&1ph-x)4?q!X?LEPLSWYhmxn5
ze0l8IE0O9#^6oqpllESYY1}@OXB!mF4024mZ`ys)rc{U-bHn6RGxEB&icKA}&oJ*|
zNs_$nr|98y%?-qz=G5{`divoDbIO$@KBwBKt5S+rwYqGL4qKRYvav?>wX<>L)0+!r
zs6A&D-xk%si*ThTZ>8?2c3%8EIHqNR<EKQE%!cFk{_Adk**Bu3=GEy?YSNCm6!cVm
zxIy2c??KfJi{kJgF_+$_J)IKmF@$r?gl*XMM}jm%rNLQlZ7a+VBE0#bTxk9a`>kta
z`F7xX(>Th`*Db!4aP%5BAH)-gjr(5LN`e1Q<y{Y6?No~|S=vg7FXxT_%fruFHDSJq
z55{rD$Kx(zm-~W!9OB763iP=zWg-7GUjB;BrwZsAZJ7V!a;}s8LbvrUCe at KMb7H7(
z!=q1HjFp|(X|-qZ9d?@O=^BOMS<aceS_rv$&>pGjdh!QTQWwDdQfC6~VLtjK?^$aw
zrLvW9tOBs#&u6K7)~#GB(n{E&%d>~aAD4E$hwEF$SYG)$q94K at R<{vy7xU)3o)cs4
zTJ5?{E&n*VvUY@`#dk|L*Py&3rg1wLnJZ<CQ)4twS{m<=X0?B%i4lqWsD1JDC)Dty
zQzqqk`(NL<x9P>%HzV2(I!jQ>7B at _rl)cw(V`Ss-uP0_2N6Ch??DX7N$PLc2lCc)2
zq-`)LZ<ASS at zT67qN2<h*0C+=Z*+a#HLUvr549^97r4(q=`buj>g#q-L+evVDe0HE
zL0fNatzJM<8F~FkqWOs;wJVM17VI(p at ylY9?l6P=`cj#4hxN&Zd-kXs)jJyGjduzS
zy!GsxiGf}9m8Ih>>#aSmSys1~&blMRO4n>Pj{RNU8eP-zpgMlaPeNI at d9>x&4 at tvo
zel5D%P%-<SCAoaYmgjq7&XZ0MH`T8Dm~MGo-bGK!P|7}N&6dJhnrDm(4wMv#NSH4_
zW4GGPtmKsS at yR)FNhW<t;f*$BZ7<^tqgTX9YwBi%GQ}ddHL6({BuL3?$lw3TZP|1E
zXTsFOCWk7RQD$O{3$!mmiif=8tYS`TRj>T6^T4j5<lL4n71A~o?Z!HNiL>J*H at UU>
z4C$E5k!33ioj&%YXct&}-ZRS%c^Hr>A^m0Ei~NXdcg~rn&FES)XT7zb^^Juhzt+8{
zL?<peeEI3`8YM?Uo at V<*O7X^L7Tdeay<~NZ&yIZWZg%+X*Uj&r9-kJmro`>k&ofp<
z4<uzLQr4tDn at _GSbu=|hT3#N{)NcK9Sk>(H<NF7V!yom9(53Wr??qKD{YL+6nZ2m{
zEuEdUBueeryW^~8>i!iQc5WHtpOlwF%nwuiOg%YnEXVNN;jum8s`Kh~mXnW1xk_Gs
z-MoKI;K*6e8`qN(cS;oyYN($V$KAiPwOZ4#Fnkq3t8k at zko76$XQFGYtBo{|lr7Jw
zE}v`L{_d!wSzgn at XXjsRQWO8U{e$7e_v91_uZ|JweNz*nm at ZS~Tut}<dZD9OwVtCD
z{zzw%b)ZS)s*Husi_e^RYp`nLkL*5+81u&WoweV0s#>LYoWHZwsv+s4 at p59VVo*w$
zZ|^z_qiv44LCZvma)meP?y at 7F7{`2;&G%VH-Bji7lGt#{nsRg>y;}Qvo3g~~cVB$7
z4wx2~&A6_3zSr|n*)3<KDPHC^Ync1G99*wBYMrcezC6XGLZi;%-tZ at 5{oh%$HS*q4
zv!++cZDk#&Zn9p`a^`rtX~O6$2WA{gu3UffwuO at Kb+h_(@)V+!oZ-a18RIH<uQuK~
zp=2ZX at q<1KasP{%AE%Rw&Q#8v{E^TT{o`eoBtxIH=L_|8N$<vUmET8eJEmulPtcN!
zI*N^cFB*qbqi8=U2X31$oas6%*R^EDlf`2ct+K at Pf9>uY^J=b4Yuvq=Y2<@n9{Ve3
zUt+t=M>8#_bWmzqjby*PU2?zW(eYCc<#i3~AA}wlF(q`re2HzQ?AM2s(i%gpPu{^R
z*lli-!_Spl<VG+yU1RSJyKpMGV at o81ntLMp>0F}u)MJdxW8P?;qLg;|xSU}huJk@{
zb9B?EF6#pQ8FJ5BizgdMB%TeK8eqBA!sF at puj_qM4`oJ0X&y2wRF-C3aVWT!*xbg@
z>8qyhk$G9(+gG7~An at VCnHSxy64yBxl^S!RN<G;RxyfE;J60 at ir**_=>~50CRr at rH
zvR!#|;P;I7$LsIVI_g|RskueWh;1&;;)#!}<}XvA8z*@zJe%xdvSF{K$C8 at KTGYM9
zpZ%w<4QUi#G;!03jxnTN&2whlok6^-(wk=+u%XB-%f}+-fP7toy;-osmGiSq!WpsM
zHl;NYntE#r`)sPIrLzy#7tb|HvG-fJ;any%tRJo#@v=;Ly56*gj)Pq*EvpWYjH6B0
zy`Ys*C2m{An1)qJixSUPqu<)jmiteX8&+0mu%B2L=PA!VcX>(Wee2{~KALf-Qgz44
zy~@ZS8d*gfd8Vg~IS_90So_W8xyQ}JsrfJ4e)_s}-mGmXI&W!k^k|uH)nSVF#*s}Q
zL?~Cyqs?yKun>Qnu*P0A_jiYdNl6dwqQ{Puy{+ at blrGn(kO~(1nre(qpIO|fH(S9e
z#-gFcvgP5Cy$d%Tk=@X?FU34v$K>iZQO%9ROB7VrUHnDO^_G3^XDXtZRhC$^I6KTb
zwQje<EgO>foa9LqLx+#%g)gl`N9_pb9=OL+*7)dTSeQ|5#a%i5oKKvsZFlVh^D0 at V
zc#Y#*HJ;}`c7FMIziCa at C>haM+KT)6OUK7lMw?c=Jvs4=c3IhouXoLwpITFEkR0Q-
zb@$eiT?;e!O&&$9Q8PPg!CcQ}O{=W?9P-ApdfI*6$D%(?GJ?Y#sqt<`C*0SIPYpXF
zU8zoWW_;ahz0>vG#M+I{7bYopY?-?~pORAJ(`EUcVz{TodaaH(jk<0B+-8&X{gmmq
zD4SIDC8)cLf1bW%YU1D|$2dlNzL;DUv%s(6w)VoS586|`%>zie+>=h`%SQxDdK9e<
z+N^I at n!=bU5hdHR_x#9fkJdjiNlRRPEz7a^m~_IOv#PXC>TYs`$5<(iBJ^|qv77tn
znH1c(tMgNSR%qJlIa|2D?~)GRo)Db>q3pnuwWdivPRFfx1hjH>Yp#8M<v*+A%ia|8
zlS@>W1&7~AzETnMw&{J8X|$7N!TF^N&L<pjTv4zlk{T<0`cfRB;Jc)bUdt8rVWh07
zGaR~~bUvGrb~qtS>9<MP)cs8*`<8aUnWmOu%E~mYFb$veeUoNFOZm2{>wzaMW4<`8
zk(254cO6FUkpG at wk(WAbJMrjL$q%XXWsEC}4RdFl;cA`RG4p)=hS^3JhnpvTZ~FXc
z-_IQJ&O7Zf*Jc^*cXS#4lFDL_U&w90V=HMLY3+3>TK>cSh@~oFKkKNLv5F_uTot^E
zW~pACwsFsLYFKCJ4E102<n99_Myxe(Ar-v2+&+yMY-bc_70H!uw~qFEFLryx0{Jsh
zb-t2o*p`JsTV4fA&K_2)`_>}5Fu>q=tjw(a+lmrChKJwUHubS-k*jOn>DMVEwpLzo
ztax5#nnOJMP-kApqwWvqUz4^<lMa1gPROqAFdcC_;&$<~*Och$r(Iu0U;7nt`fYZn
ztDH#+_eJb-{l2i?FIU80uI{p`OH7P3J{$JA*kkPp@!m at 7omSHWlst7U({-3%jvc;b
zoS(Id@?64j^Qn_!Q{E{@7{qI-FU%q>u$<yE_sW-PHRL#Hd)cXZ`g6RUxOdiG4m3}?
z_9<t^kMcmI*u#F+?P}7Xs=s)HN9-_-GhbAS-|RI!v3!0ltG&o@`?nIqnr#}UwM|d=
zM$G6{YIWD&cF|bTs$OZz;%DQ#>C}!ox+GPN8d<2^m-lefgYEa8R~*+}Xjyr6Y|hEq
zqzTKdoYMlgJ6eZTJ6LJvRl0EV^v92$Zb7OUrQCFR>5|*V&J873ovTexSjSw6InnCY
zHnuy#R&Kb-zDZ{9IXC=s at 7iT2GiIn5G^j1N?9()7i1BU<`=1vziwwo0Lh^}1c$^Sc
z62ip4V7Vb!MM#c>%9j(8iweo73t at So^fE$nX(2pPD1D<()_WD3CPMKTgcu?-mWc?Z
z*ILApnJ}}7aOerFuZ at D1$Oz?^6~ZHgv5>yu!dNK1n2=mT2rCGsA1Nfa5yI1i at N(h)
z7Vb|WJXWYYSD#Ne7q3*7uf(2TX*7hk%%!eW+R{Qel8Qf1Z>Y)=&DYg$CG6V`_Zzht
z#mM2vv at s$rga%pYznX__N>SNP7ggs`Dk7HMo~pBms=IEezCIz`!WfFP&q~RU3T!6q
zd54IH{n#Iu2-SC~5H=9PMnZVCaQk~N?{*<I6Jke0eJdHCvYl=fDVj7BcJ%@FmaRy%
z@|9cQ)l5i};^EL6AGAz8S_wP#vGy+TE&Dv8E;zQ85cwQ?UUL41?nR{?A%pM~q5d=x
zDnD6Bzm`z?xk6Z52<r&pX+n605S}T7!QLkfws(q9{d#I;UZ#b#5n?nE`YI*0a+Xm3
z=|b38D8H!?HWR{^7tOgBJqP+z9Jil6SA_6YA$&~;HwocpAuM%ae_Eh3+#g3{&(F#o
zI}$@u)vvY at vcI6PwNVL2P6^egQ3#(G!Z(HR4I$hlgjdKeV9(l-YZx_Zmfwfby3cim
z`s>UATPH1gE1 at bE>KCx#+ugD~HVYj9=kRcEqQb9}&CP^dEf}9uesryy#<CWHErguQ
zJUl!kV{FBv7DD+EXz%U&1(TXfHhv0jBc#ay&Q*?XJXoPTVqF{I5QT?ZI+tgT^aHsF
z4{N>Yi$A%rg;3LqvQ<koPSlK^tE^ejLMS)~{yprlaidFJ<V+Tnca~RPV~0)2#6g(2
zF at E#@jV*+vWjws>f=oeQXA2?ShL_*v>D0K>b6W`8Ch+ukEqfDr$FYS_tIflYgs^{a
zQ01e|1Nx8`8ha=PumKOhyK?N*y4V5yUI=#!>D#;^-p-{B>O<z$C#1K2<JMveqdI@@
z#|n`z>c&|#rCvYQN~o>C`tN3W=5BT)<$Eh3`!KJ6%A=CDBwsma7*>?57E0Y<k9Gt{
zNqR$n$@8AicW$`C9E_Xvj$R0R(?ZBt%X^;Md*_U at vtlb@S3Pn~Pk%vuNbPN6{{nx?
z$Dgk?_mzgopPX@>uv3=zyp23Ysl`4-ic&Z1sNRTr<Kxp4_pkGlvotA3<X4TGo^s?~
zzx7h<kus`C3I32V%iFn)dr4pPn4Z<4rNizlW2{*g`+ec7!(Y#lwyG?sZ%Z)Yluvth
z?b1~x<D|{nYuMi_nwE8bUgy#N(K>DVm(JIE0WMy7AC##o8RW#B!^)SASom#IMtoU%
z%ysK}_Ds_UDLcyZzxgPc9P70%p0ws#wU_r1 at 8*=JUUw8oG48t+XTEV+l{4+o#Z>J#
zq;UFrMT?dRjwjS!-Cn$mY;a__dGj6B8+M<T7c_3KXd_g<<~^T{RzJOO=lwRqkrv+H
zf085by_?HvA;j<I{r#wzs_tzz==oYy;~2(><=2c-534`SXMUSS+|Ird{iTVJd<e$7
z(6VKcZ-n8vXK%=LD{>yu&TRN~y*z7kR+6M)iRRvMu5)ElLbji(8+&|?QP|nIm1ks3
z7VmjV%de>zMM}!|IA3>JS4$_+&ELIS-8|n*wmNLs(_6P&Qg0US*kF9DqG`?X(h;#@
z<%iJoljn_h&S=R>vFnoRo_t$F|6q|-u9m6le%;kM^(hX&J7=3&Rh}~l-=uu4R{Oyr
zvwVG3Qb~7Z;k3C&CF!0ceqHXYrQ`(9a<15soPYPHcijESM9cV>Bu~T2f at y{C%Ec2?
z>x|O6$Z5F>wvT)ZmsUkhW*O(~GaHlnJ!<>1dd`-RANrJn3!A&FRh>vDZtk1#JR`}d
zVC3B5tLz&6b?cP1C%1pFNG}^*KO_2tUe>12fIUg$NV{*{J1TYYs;9Ks=RF=y(=7{$
zr at q8X`E_qIK9b8#I!M`;J1nPc*51PHLeICOzpU;EH3ht%hh;Z)My{1{Cp9R$9_30*
zGAOHfWPIib_}3iX-^U_n+;pa-!hC`~FAh1>%O?D$+<)O~lpHn2!>+(^LJQ}|sYS02
zSX3&+-%E<AYRw9}+Pr2)4>_xkY at u^D<|(J=?SpiNw{`vWg;hF->J at H@OuwHg(MQhS
zKl7(b)y*#)A$`sgk{t7+K4w|d#x7kMs$LXT6Y~D~@F<JYVGmw?GuTEtPDnqV;uK?A
z*hNxXzkJ1r)ChSclK5})uu<QKb4HAKadp&6m6whs)RI+CzHfLjllkse??kVo>Q>w3
z6&`7e=ATus`<)$O?`c at Cwlw_N&S9rF(lk#HrCSMmMqt<T_ET?;EZ$X-(n`q4<^8=;
z(_(e^U3AJKYt(`|!lxUGQB`@zqN*g!cHdd^qAf;Sk9bEzWbofh*<B-FE>ed1 at EG9X
ziKTth9tVB9B58Ph-3doEt^@6{Z)?b#5*33T`;!<)Y3+{W4?i7zf3^^I#ex4^%1+!x
z(QsXKWG}hEPifv`s-a at i59Jr?nb8)B&oi^)T;3kexUl4G>#i3TiCQOiKgw97e0NW)
zW&Sj6^JCSz8{Vw$_E}lLS<>=^Y<0MCxyo^}^N!Uc(_-h4H&};_;*jjZ&zwms&}_UK
zJ&Ce+DtDo|xY0q+Wj=DP8I5KKru^vOKKgO)L`G8atE(EO^{<ukK693ZiYDYwT6J?G
zsXQ~2UaI1{`ohWadT*YNvaWY>dZa27KC-gv`a_vh&n==p7cdwfML(ZQ%H4G%Q{8f_
zNJ-|f^_c|UvL|U>>n2zv%A7ZoD~?sy+&p2noW at Fn$Vrn}5jxJA%WJY^E<Jf^nCsu`
zwP93 at Wq3pRr^@*87O52FF_|(P{k0{bsm{YkSyr at Le2HXT`l`;AD(GI!u{tKTQ9R$E
zLHX;h8FyTo1I-&&zPO%wpmy^t%7xIKXW|TF?s;>9jeh$V-fnU<UpCt?#YXGBQRElu
zM^dZ)I{h|6T`^|=Gwzj(f3i&LXd!H02IEEOdEz+sUd1hc7qgv9Syxs$j}yIofBlp`
z?r5Wg>T^C4rH^jaml335M%Y_svhCwPQ$&1>WjkrV6I`v6t?Bct#wt9}d%r#YmGW9j
zMrzW{jr!g!HFjm&)FrztQW`0<ZrGo3xF#O!aO=vz^ZQ+s8%?9SW|Jz<QPm!%t$Hy<
z$+k#A%E&77%$Do%Y}S%dW7gU%^+`56z+U+^c8}Fkj*xu`|GlF3N{)x}BAQW>(|iVl
zvC!t8{Jiunn`Rkr3*a7fQonAmxBM%4^SynBQSTm0t{JuV;?!$(TRYa?vn<Oy>`}8M
zxFnXn@#di$-lp}U`_p!5-*HuL`}uU)*Z|7D_=2qQx&FFjPlDd4Tj>^iBe`3PTEulO
zP`R|qs3g;(a<wUeT6;$gA7N)rcp7AxTbekxWs3TEMo!@5)NiE*2^XbT_QaUVhaJCt
zXclTAB#h+!J@=yFL;3oN*9qHod4IpyYFXFDUS?}vAim+shm6 at LNDB8jQIo=rcTx{d
znm97vF$d*Z?%3N(*gl0ff6Wh^{ANKHtj9xmxbx)WK5vUKi=F$p)90?@#BM%ZxJYlW
z4EbR9mrW+zyjb?_N85{|O|7Z}wXf#M_>YS-x>gar&(kPbMAJ=vbxc{9>61Y2p>DH+
zU5ksd55JQQeX3u0B<`Kj4#T#-2A>HnmzO1O`qnOQ7O9=e6bX7{nmS>X{_;!JmM44{
zr+koUO5v^_u4>ml(Y)aLja2;~zn0wG^*)HDp=4cCrafmVTe;Ht?rVwM3`Ntpd*`0r
z-970@`pTc at eX?TBV#HE=<l;M)nUJRMrxxuZWo0csGQ0EA3dZiydI`fXQnn-WS4Tys
z{1_h`6IZx!vU%~b+`apB3-8?DQhvX3 at dV?<`ZQ0YU$@HZ+8WpUvacE!G-}R0bx&nw
zK*h at GHE*iT5+siWhmSOC&Q*vIRjYb#8tZV1OkZJ5y<K);quh)-$~NOu1`{r6F{46m
zrQANY)hKeD*X#$`qD}4e^WWZ|R<dl+iJWq4-kjwf3Ln<LHcTXK4SH_p6ESauQ{iHb
zH##@TCpN6roqL-Z97*the(dRcYLs`l-k4t(>dzn96+5|Nf at Qv&tOMC5l65%r;;(P>
zLX8ep6Q>#_87Q0dc=_&IU1PPc?m^cavi-Y_&XTn|Z!9w?+1-92RDNseD|!D;#kxkL
z^m3C6msV%q*Lp6kyKohZ_jlfYuT8BTq+{(g^6pKs=jALWI<-8G&z|<Z#He!Pg(GLC
zcGkLHxqH$vu*`I;aobYm=7_T9RgzJYr at k;qlW+6c;PiRH*XgkbS>s|T#T_qX-X=8k
zELTkPm?za}nDFanV6>f_ho6>#(Vkl^X0cE6rYEcI{ZaO#t$pmfc;k3oF^7zx18w0M
zBmEANXHwI@#(nIZen-RYwsLES=SQms=41zz-Rs^Z%YK#}=iP2{%&DE`|KPFbTFK@`
z_tt+m5AR)e_UHTjnuZQ-_sST5lf*_B#|o*u%z2x16waq+o7FvAw~uk79c58h>T6}?
zn5OT!)U#yC at L_2p_w?v#ttNX5ulr}d`u6(Au%7jAcJ!Gv#0Qxj%qbhyR<(`3V{N8I
zb?4M;ch+x;KkMUhD&u_;^?>+GjaL8t%6D29hZfB{M$Pm37+*T?QA?#}*O?ugz8Y0M
zkPA9y<@;EN^QO1&>0Z;UX$M_T>*ntK?pHw2T%c^6tUF0g;jLEGk>`arZwKvnK*Iak
zEc8Cq(whiH$9elLTxaj#?Z>;t+fOGVl-^r$vQCl21FIUpyWLjzcgNXnn3p=^a<D~Y
zS<f%7^eAfchlAxhh9wrUoC#MZ9Ln3C669K0s(QgF;!&jH^kQap0-<8@&j(soxn^0F
z?G4JmY-?_<X#M=2TpSRio^!O#<GlTJeKyC3dQ5&ryFvn`jj%Cd=QEvC7DvhPcXCc2
z6TjeJ9XeGm)GF?PQo|wBj2X>e74D>ojiJO^{~)i?PF*awO&)EF(I*|MGy7CYICfYf
z?&Xg+^<<+kYlHnv<1x>Tgs$If?28VZ&aNP*OJyHD{vhZg<(=BaQ!CW1Qd}G#Z!EjR
z`SI58>Sx1qCTU8`Z>~?<vPplej!%9d)1pDexMSZ<v7CeJt{+kk2r)k3+0L>Ry?SEm
zl_NxNMy+-AjRIfPvhhun`?vM&53ZYKpDG*HQ at -NI1Zf?=uWbgVl`fiuR at 2bg*)79A
zcRjgcT&di(I&1q3-TA6UPraG8)YJ#Ff3<nNtxbC{jkKs!jFjNtxpGt3;(cd0I<eat
zS_$>@q>$bbWwEXwm-Za!Y&WlX^GHEtX^~<l?IoKXEoPV$@c!}n?V1|{R<tZ~jI}XK
z4kFa7zPD3)->M1s<9a%*@^f6j&Loz7`S7TsQRO(tbjNWWmrEuuw`*PKwc7u%+dRpx
z*eBw7$g1HB(py7 at U$n~Bc^x}@PL4&_`VSQ6_<dG;7TXs at Y+0`FR=#d!Tg4c17WcXQ
z-r?bP7fL1lMYUTA#cgmue at abGfh<urZ=RM><m;Ov#hzhL#WbFjUVB2ci1__%JfXg9
zVq%C|`#Q^J!j2fQKi5wU7o-(dZU{U|&N^=N#$?R<3%>H+N|hg)jkd`VSXVNe-igYI
zj6QjymlWImI(NMaeQT74+b{=jSEC(W2bEMRCRn)EJ7kVL*G$+m8^7K*$tut8RjIcz
zj4kJQ^`*Vl at 0EEMRJp{HQc0{nN4 at USE@p5l+Q;gHbzz0XFwe!B-cwH3N59wV1b=dE
zop8%pUHo`ZN3uS_Dkq;jZ>C*m_e7OrceXs4ZdCkM>)^0M*VCU>E>$a!H8g8@`{?3C
z!{R5Wymd7S^{Na at Rj>EXx#Jo-{;FlN8$HT0+Oah#*>*}*NxVvO at vC`;;W}Yk+H_C9
zDWw_ot{l6}yvROiRsNR7$TIl_>AQEuT4Y-JJ&)gIdlz#$>=6d$h1j!WaUj|pe?;@0
z<L`^GcmJ}DgBjQdNw8NNBjk%X$Q`i|8`0s^L>`EVuopbv{!B(%U&zRQ6+(6aepW0$
z`vAHl-NW8Hz=X}P!}p+@)BH^6ZdNol$)9aS3o#GyGY?>r0=(?#{#19aH7n4Fj=wY8
z49-PRk}v$vLA>{kd+^WMh={ECC$T>!gnuGDehwZ#haZEG4Z=Tzg-CpE1T}XD@<nd&
zKfX;FSwouwh2p4?iVN|A7(3wp5HmOx2?Zc8AP&N}up at H_Gx_CWVLwFYm+cSf8F*h=
zAsU3;5%wJq6Og+B3c%w8`Dl=DAcj|8K^+D464Xaf2SM3_a(U&1^p`CtS5T&)983=l
z^aX&-gP#LSgVlBb+e2-!6r4eEj-bZ_Z{a|!J)|0pt)R|+gYwwnbsLOncw2bo3Ca=Z
z7U&b`5#$FOF<a#8yNLIV77sXP6RqGNVu27ikd at UO505z^cp)}0>?9yCFFN*~c6_{9
zf&F1HJ{A at PJLC!?!7KwfP%*GjTn88{K9FF#415f+w_s!Srn|8NXuQ|bgMH&c%#1-l
zrWezR>B972Iv`&NrUT25<;C(K at Qwhs2MyN&&Vq-)Z`d4u9JrAmoe#jP at DMl{9s$0_
z<KSVC7t4pG$I at YGFgdb7#>f_|#~4{69i$CjYXl)n-Z(QkCTuz#<92i|?<-6YHXRfu
zF_|pfFD(t%+Ec8IF>bxW%Gj1-h{st`t&QzTwkxr)q5Vo5V}4pgs--2#-WU&)EP2Ht
zW)AN=V{Kgq$Q8mKFUe?E90}R;!>TM2GUJCkqe)1gA3hyPLc08LX#@$0h>D3z43m_S
z9zH at wR&Jy`L1EPBF=G|SDJhSiFmcjkqRN!1s?(;csn3`>Yqo~w9Id(9I=b`p<}X;d
zXtDm1rOOORWJ4ok6H_yaxrL>bHPvRht)2Y}2S=xst5!R&aarq1b948gdwO{@*7-1f
z{aF6%*&J>_U{G*K=!T7(Hg7>|HD at F2#qn!_76UE8=1Pn&Mz}ZofmJhLo}k0*gv}Ie
ze9k1|ZI?yE`95U{zHA5Q;50m`9iqU9nf{Fgn-8eq4<tOr-^sDV7U>}^7;POqRs+(J
zphmp83!B4;_{>JcXD&KEr(z{qLI|7PJ at 7bBT(2*l)*D*Gfe;O!k$E#9HqT*mZ~*SR
zelQ0S;eQ(5@<3d}fG$kVz$G-u$3UU{beLBU$Gx7XpMlQ~49H2tYs)K>2&Dz!`Y|~+
z-?Q*iF_}M{%>EoajhY~#;H~6o^@Ugtj<J+JpqE#7tX){`*mz0U?1`meLCcA_J|>=?
z*D at MjvY?+d at U~%niOuQQTt!6caLsWC#6~ml-ovcGy}wR_`;+#!J>`ej5wjlNb%%}D
zg*_yv5nd;3CTHO76pXoGytVts+YfSZar^MYd&>*jN`w;N+KylSFs(f8OyIoM3Py at 2
z at g3Bo!sX2U7rXlFc+&^<w;|}U=Z_1!U&8BQ7T#;v+TwqOT?n^BtG^wBItlvi?^@s?
zlwTVy=+7U3kEk2J7yr}?SRY{Z`>Vfdqxt{E at e9IR_-8-+yYlq@3*})}>hWJJZ(e_S
z{`g2?dIKRn8()E7I{wac1im<+QJ_!vzfk|RxK=s}#%n%@Z&5sijhtW<|62dKXyG5n
zn+2uO`8DSGGm9_BX2C$*8vkDJP&>kE<BzZUxcs?AU^9Q7 at 8=G(pTF1R%b(>KxW}<^
ztsebzfX~0`|F77~(2_jx{-*J at 3-k{7A=alX+#b~NdDI)f<`D4}H+_gT{M8?|293{u
zUOy}a&jztE^TjcDNd2 at 1jn99s7h7#(_XYxuoWIzw)}Z;?6CVSf_wcSb{(u>HP9lDF
z^2cM?I2P1`m&apBUtkAzKNnU^#$St|4jlX3cuNr(PZ0|o+gGCnoPfn2B;&tzjs-pn
ziwBPF18OWJBW(YVKX7GCDe&>Y5(~&^0&oN1ldyQ;lYuSBC*v!emOL_20p59ljIfWN
z)&a-XuGzptfo}!g2Ye&&- at u)LTj9RJ#;?=Z^%rZK13vc)W(7ku3r-^R+|bpPC4{g$
zsDb;Z;rxEk#7~6u@%tYZ^eL9gmw)Z$<;HaR;Jq0H|1af_&Cn8z`#nMh*KIRI+akQp
z>i8WSW|h1h80vljOeO?}VgE$1-{*=AL&HSn#f^=PC9q?j7Q#OgtWI2D<0L7C=4)v=
z+DIZqBw|B`q+GpS;Xo+ZKNt=v>~#W?ND6;T1@@zKERnlA2d%I-(O3XsjL+4x#Mj;{
ztSN?6BV%M2!h!o4!RJ)9bo3B*FK7h)N`kT}f4LXH4ha}`!5*iH5Ekc$(*}iiKv;?&
z-Z?0oFescjD4aAXoIEI;GALXjIuNcL6vm!ONb~d|!QQO at n-Ah&PWArtud=_MW`Fsm
z`p|Rh-<(5JgbzAJ{=;){{)j=R=zn+$@)G~2yZ`@y<F8}t{lD7+L<Y|P^cZ3RA_J%B
ze|Qd9z<>ArxAtQv_U44aXt3-*ZZf~!L-Bvw-hp-t$MANrhJ{B&ZjFkLiQN{rJ$}c|
zgv6xel+;~m=^4BC?A^CNGb=miKyF at sLE*uo;*!!sWrxd;96eT1Syf$Ad;CP*$@+%I
zQ>V|IJ$L at X#Y>m3T)o!R+|t^1{l?AqTet7ry?6gX$HUI9N8OK~Jbl*l{Kd;xuiw1w
zefR#u$4{TXeEs(QN8it1zyI40VE*|5%YXC$=6|~V|I_9FFMj~`&+`8x`ai&r!KHg>
zaJV!s_L)k=$36@{FAtV4LfDs at 86Gqb;&dXH<wo<uelE>n1#rDJd{}HcjUT3YvKj6)
zB#;pY$%unwOjaPx2iCy>bT*fz0nu=u$JW5UV~WfDu{YK5!+xRIyG?>LLg_Rn&CdgQ
zv;4fENbEE55N6_WUf7qIiEeBLmxg~^m+t3<$GeBp at n^~cWr7qmUpiiu01igbR;UXn
zh=D)+<^<6_7#wd6Plg|^gX2%bK256;NcW?M2GE(99zk3HJHRV|7SfM-?IGgr>5rqc
z at o$^<V;Y-=XBracNAsl(U_YoFo@!7UUzP`*?KcS1gCUh)KZbts2w>x%1MZIl4X|FN
z4XHDoN#xL&fiw>mdmzp|U<if*XJB=}zI^T<;KpRQ59D`efr$`#BRLSqWcj)=XoJgk
z_r^c3*^k{=OhzCi5n${yoY>dgu}s((U7;uG9J+=Zn-<DoGHCd_a{O5AAi5U-4Zjcw
zb9{!xxv_kpZ9~#Q7)BV&t|1st1{-f7SOjpuUUataAh7^51A^(kZma;d*Pu9tyEm8a
z2Wx(?8GalsfCHWYC3&*xe(v4_diZ#V9)28jB+X+`9ydCZS6P0oG%!0H2oH+)83_0L
zU&w&}31q_lC5Xp-M-W~I7KVuhn8Bv^hr!wyZf<m%-=MshZ3)6qVeA!A{TMo7Ak6b6
ze7rmYxPzOA`yDo at TsE{He=!lWKMs5077YfTJ}4cB;p at +2crvgrs|w;Uf9JcqAP(a|
z-l)H0G2iBwiVqNtXF-Cx4I2LbIO5;LVd1*tWMpi;0v+V at R6dWzISGXUx3(lBE{+Y6
zKk!v%W{8P%3i1GMXl93O`0 at IDtj?E@#<4vT=j-XM<>`N1%hP`Y=a%SVEl+<1&dKN?
z&M7DZ=jJFL=c^DG=XS^m=k~}F=cdSjuUD7PRe_t>lF?|K8zO{rOVnF~aXZur+{l=O
zuHxJf)!^I`9mKgE%BbO$9}ApfZ-+Jlx2D=6Z$7ujxi!)UZeveI>R5U^J2VdGWF&=i
zOZ2fC<5bj%b3=3%=SHXk=O!o{=f)@==cXta=Vr(o=T^uG=hnyw=M<!ia}pxrd=-+%
zxh?9e!uSgG3g;`)ZJaxxi@@z1Oi*JLuU&Ojy#A`G;`LJnpO*q(0ebU*o04tOzA9|o
ztWhe)S3&*w at f-P^TZN6M5%LCZW?_n)F}%tWIq|tAKfeK=>jJm2rJ&h(eJs!f;HyX`
zNFKNa^e5uukCi;!3EbYEiq{t_ucea58!LJBtl`&JMn+jiQeID7MoL3mOk74 at UTUHg
z)zAi!fUNuHPV4^p)RZpRi{OaA4bF~>fB6}U$39rk`${&&&lCHsF(z>2<*}r3xFmNj
zBam*x^2a`84{<!qQ-iEPBh8CWW(7N<703?%i|OAz9~l-F79AEIhLF5ibXasm*k}m}
zV`Jl}s3-}9w6wx(!eWsWQde7G;~0h{v4=V~HnG at En|fGm8012(-mc!>-cnMM!T$b1
z{{BOr=NKX?vIbg#?2#&9dn+5bTludaVO?b8+Caviq1f6P+0mCrO3R)knru6ML3i&#
zqs`cjgyAA*tlv1!>);aZ&T{r=v#=iIIP)%~&hEUAi90hHZqC?C0Ry-UCdb*G<qKCA
z59c5T{t0)Dg_>HL{vK|F%Fh0Ykj-)t)F~qRw{`pV`#1LJ58dE%0e%=`@JBf{mM4GA
z$H7AK?CpQfUmE{s`Ha**%YW?pvpl0<sQjvsd|Jg&d83g0UiDCU>>&A<S_3rV_)vL;
zQ2xiKhRSaX$#<Opv;3TpT)2J1F8o>E-TLSDf4KSQ{6TmAT)&5R4f?}x28D&w<=h{T
z9lHO|>3(z$$RxWA{;^(_gJh=$g at xPK^M+S{?8qM!u7309c3<rKvs_DrG(>(;Nd8Hb
z)L+(I2>+9wXJVv3mZLImsJul;zCmfIT)6!b;|J=|s{GIOa2)^Va(WH^EPrqIXZcZ^
zq4L4w-r at -B7RP^<6P-v%)#=arAN-5larIESu%CZ+{_{ADr2TXKPPma!liQ!m5Ayx9
zej~p>%g3|+EdO!w&*j&?`LmtO=>4<)`gebp2YvXn{+_-+%PW8Wx&FJQ$$ykzQTnr-
zGV#yyvPplIpCJyF3)|15X at AbYb2?9s9qtgWxiD}YcDXEy)U`xW&!9N<Yof>r;wml;
z#GP#tMXK7O=<J|$md&C_7t$pTitB|q1aYN<^2)V{q6v_fczGbs2I3O6|9(AC3_84l
z0)aY!nt<wn;(+!5IW+U~kwKppU*}ASQwEX)5(Rn>^?d}?0<?gizU&I<0lErwAE*cD
zJCNK}Q8Woi8;A^K3*-qD3bYgG08j<cWuOkA&p-;$N5wZq(LSJT(6Je~AJ8fwb0A%y
zDL^tn-*1Sb7eF_F&H at z!B?1Kkc>vi1Ed`nmqzohl^!2(ZdJ5DIR1dTh%7_5s0(k)0
z0_g*30mVTXlYq+uA*@}{CwGCa0#yMO03`x#1Y!cEfxhFAXD4tj&?+EnjKi34fx>{|
zf%1Urf$jsn0{RZ5&?<^%0_g);133fv18oM{36u>~1#}VUG0<0_(QVMTKqf#AKun-$
zpk$z8pwmECfo=o60Qw9h4)sw0ngFB?WN at 7~hQIh at X#@Rl1f&O417lnalnN9J6b$4I
zv<k=)Xc3S)kTTG4ps$eU1yDQCWuW6g1whF_aX_1a{D7RV at yePF?KS{XZsFmr2yQ$4
z>1=L at oi`os9k6A)A@&@PJ|x}-?jb;CNVPJwx75+r^k6a(;)vVv?m&!r??K+k&uPTK
zUUto5hd_=eB5+4y!eG)#TrQj87Qm%*Al6aListXYpa)SsF&Wy%&xrw$_%r;xNZ8-2
z4Vf$s-3(UbkY*iL8kWGG;Y&x4kr9hy1X(a-&+3mC6*V1Fr`SQ7NvK_Xg`e+`lC30|
z94?zl$1WRQVpai6E`uBbT3L<^54xc at jg5>&`S)fd4-YoJS6pArl11~dWVo?ucpI-H
zBRZ2VD5Fu#mQM4)l_O6<oo!eQKQ6Wbw^z^~cG#mFHxX=;Dqj<d!BX3CJ@^eq9$3kP
zuo;x=PGjQxTGxn};J1SO`#Y#b1eV&K?(2_fx2E}Gaa#p(HZ-m`;4v7sVtE8G`MnBp
zxmcV7 at 6Fi8!6Y<F+?LJ>fKK&>j`Kih6ILr5HiN}xa6=54G^__2u~rxcu-SCK{w?%p
z2gM2U?#A-+fItJv8?Y}dAJkyfK&=MV9YH;OS%E{WX)$js7=gU}*h{!6eqgkuzsB2P
zPwFr$8vR%8aPw?oY-?@YZ^?3^1NX@!G#eiymOJ(gP+KgB;}4p+o+OkY3av3>dQrG^
zUwe8mlp6#wejWp3Ko_+IOQ3P+MutcQ(*nE<88JBi*h}IE()EejvuS=D>_zVUNGM6v
zhEDexNOK<<`+3;VplF0PW4d_T9<1olFn6e#93s=b7=HW|d%*@hdH4Ldts+DaTjB2k
z1 at IpPpogM%-mD-2^5u^L4`btQ0d at C+J7GE-A7s$bBZApE3 at L}jCZX}7R;>QV3TPiz
zBOb7Y;X(66ZCIQ^*64xBZD^P=AU57h{Eq8SqK5YmFB1F|>sww?Xoa1ztzcyI1ak_7
z%;19SBJ`B+ZM;V!2o+#CvEeXeF)@#?5yb#C0GrFUU^23g75055Y^<1&Ly%8jFf*_)
z3$o`UI~J4SL1qVFPb5u^DEw+LvA$UzKxc>GyT?h`vH)W6>B)i~f_#U{vF=3HSe&t6
zfG;G#B3v;{^{4ys at g@ul_NL=G7T`MZYVgx6!D4vLg%}bt9l-pGkc=EiHiBxRNg^;?
zGnvN0ba$9(NyyI3*ivBROk~Jf;m7b}a2Yh-b7Xml;T1>m<9!wZp`{Q<8I*>_r1SHK
zi1yncHq(+g{c~=!s2QE+k55Z*$;QIGt at YDH1WD{!0~rxg9Td--(FB at a31-JZPrAq<
zg86TU80I0E1AEvo{ORa}AhkXAS%x>@FPQPdB*Ormc65Aq5JC&ZEa|jB`d{LA;d3LD
z%9}``|IgzViJJsJrVVe6EuGh%al*4F%p*!7gMUVJ8T*X{7 at J_akH+Uj-a{ozh98W`
zbzCD1`=A!WN|ra%)7abqe at x(r#KkBazE&37gpU1^0%kTk2lJ;!aeF%3m*F=siNZAq
zu58|Tr96y--Rb_AUg#S9nv;*s!v8FWl8oqX0bX8owxEO;(3gYTL68t!4((a}*GQBh
z=)qMiKl+gNu<>@=U~%ZJC<W7jeLsWlLGg2E(|xfb(96N`&~1WvZ!9nNm=w*&^iz$k
zu<&rGr33c03`4A1*o1jb+`j)e92c-~|8F}kVyORDALlWI8|S&dT%jm%jk<=92+t1?
zYQm8b9To+w5HwA~5zGd^ZXidj7mfV_8ElpxR#OKWn?ZBKjKJX^BqVfH+>S}7`=f5r
z0iO~wM3SF}9jtc at Spm@aR{q>3Y^+2P6B?JsB>DSe)<!}stVEs- at -m`5JWKQAfWu<_
zRXPac(;pfqZp&q^@WVbff;6!Fg4D45;i+PySA)j{3<XREdV1O5^$ytlFno=LIWC=N
ztcZrMV+M5r at 9N8OM0c@z{G9+5is2Kc4V{e}4$MAyQ=k?pJiBuD;kWJ7UsoG2a2jHk
zhOk!TDFl5Co)2LNn-3snuPFcNIb0fPV6~Qp6eCzx46QwQxvU5_P4i|bo&dZ0$p|ct
z7lj-}Oqg(4z-)nxe>?=dPL*dL{GN0~H+bHS&zv4GlluC at 6|ldC34_+6j>wK at H6Hwh
zC^8qUGog8ymcPB7{MQ3+lYft!$NQ#;44;ehd7myB^#b+i^045*(%;bKrN{WcrMF{w
za)Y2@&Q=U}Hj4wunYR+)IP*t|znpYlfj>s4!PNtMA6p&h!S-O5>hkv8?$hP%!`-OM
z+qdhX%iEu82^{-OmOgMr;Hto}yOq&cJrMS(GBWzALq<*G3<R&?L!E%j6bEn%;KcC;
zNU*oF5%3|y0eLClr-N`dVAA*j{9kD!c33|(IB`U&!H77~5XTr7yqga{<k4RatZgEH
zjUFQZ`=<;4|MCAHe?Bm~`OSZJhJ?b{5$4acz20}ccpE$W|5kZ6M*qG129L=o3<#?e
zHfIQIUyRQ&f5zqr355OL5Z{N6 at 1w@%3v3^?6rW4;`Eb5$#30#NeqM}^<m;8^$6>!4
zP~a05ufmU?$Hyc-HsoU)ejZzXyd9rA^7XIem(AqIW4}Eo0%6lT_FDrszplgh>BIPS
z4(Ia-zC4mI-^$mM1cdF#&*bAAetq)z<rVVdtNHb7;>&OG<>MrIeIe+x|2>ENKOQ_e
z at gI->ZB_hVdi?X|PoDgrHz)qj*8Bg><NtOW;2-}VHwA;IFh`4uOXb1D>>3dgp~8<Z
zc*x^9`8*z;)!B!q|9{H6wwS1nFg(lB7OicTge9~uJt0aoso>fsRSU|lM!-}9*u-^d
zst5-`S+pD$F|`&iX>8JmCT&w6#3F=^52TV-328Lgq-pwKQj!uwh#@}MNKyh#+pH1k
zZohwK&YsKe0c=Tn8}iNNKQr^s<^Ru~fwLbcJ9&B;^}p^N?^PW7Jr$Sz%k<hJ>-%Lo
zi2C36-0OLs{n#_vQ{&wK$xA#}g%6Ud at i)g6wr~8<`1;iPKa5S>eaM*aq-aThhoXD`
zWOsnw1MUKMfH7bc7y-TmZURF<KhO=F2R;DK0cU|u-~`YCv;jwfW}p$M2lfMR0Ivh(
zKq;_6)?Wv#1{5F%SOGBLx6kmr4om at efm^^$U|FW|d^v>j0B{-T2F?Q?0_T7Zpb-cH
z+kka|0;~Wsfw_y&0Zak+fIGk_a0~bbxDH$e`hg3;Ip73vRMxKtf<QU&GO!Zx0CQdF
z7nlOZfC1n_mpE_C_gwr}0`V;@W!c42$2vA+)EW95d-x^x<0{q|ZAYdA$d3{-TpzH`
z+1}q`<xbZhx4zT$zcbJ}buM4Ho>SQ0A7GXJ#=dNMI<P31_0xAli5r9N#PmJTPl0Q|
zDDW$g?V|Tua25o at E~CvRCY}e6G5)<nc9qfJju`s|ApY_qU?<RQTJS=N5!ljY_tpjR
zt_-87-;c5r$TrC)zZwwF+N6V0<%y4;WB;MB(D#@!Y{4yq-kzSB<EArHIzRs>2Jw3j
zHy{6M94qL&REm_&PDjNt!&J}3xrffB$TJzeo7xRIonMBK()ncsDb=4$(~nCeDRK&V
zriIhx^x3r9LB7F3UhW_dI>;L#@9??#zk<Ife<9TQs+)DYjIvVVW|<jAdF2*23z^ED
zemBc8)&Dqv>!vc+n6KfBT&oavFJmczOzHmp`)p!jg5AD-o87o^gPlElmIVR<wsGS|
z=JWa3nl)=!US1wODT{ALPb64hooGM(=feM`-Ap1O6J$(rB1N9Cv_m;A5 at bwqs+^bg
zb~B=^tFQ#S+}tiPI85clU^F_MKw*$#%3I}8O3dvZRo75gv(^4U2=U(P5YN|;JU%_c
z^CY3f+%BdRP`f at HvAkFMJUJeU87ue}^7u5D7x0)BSlZ2&?m)9gRX)Gp7pj77QtbDK
zO!5$qJv*%WJYEbvrg)=$9xv48P^?DYi+Xa=E~fB2znW{)myMZG at 3W<4rQ7jS28llq
z<oafl`G=);eHglzdWUBDL*9b)3YJmka}(+G`F%mDue>@a^m!16W>FIP9kW#_^UG1|
zJ*zxoe!0;opI<#`^?m}m$Ro?r>EmlCwU*0#wojK+?6d1rnAka*CH4&aDf2lVT~2Y1
zZGMl)6oie0$VLE}-&?KA5eN3z)>D{XT(`+M*`>@6Ms-`I*rpE#KL<-sx*U~sP$DAQ
zNvpo3N60k69YR3&3qnjOu(cDGucva3rg<jIR)3$?dlG3(tf^^TMVaPqZ6_>0A<}7K
zspfqYW&QSI(#I`75$7q7W4g5p8!~J&oj%#Cp|4Dj4coNo^YT6FBM;DZNlm0Rw=Zd%
zHhtOLCgAKLU7z#<uCJ`h=b(=n_ZF#7_qv$82RP~DHov#ZSCd9xwl8U$Df6S*kjjEI
z^AmT2bowgh9?I3*k!C%!L$mYh<NHRrXw<TQ-Yc<r<|lo<+V9B at 1k>0{8hza3g&le+
z&sKR-?K8EV at OWYKA>>g=;}6p*?c|4z at O8>Zhpm1ePx^wTUGgK&{9$L$Pp7tf%<!*i
z=VHcLp_JV$7f*t3yT0HlF`Kq=#v}P#ch^qNlDM05#A!UIa at N5H>tkc(J8U_7z;f86
zo1P(0n;7KwNOrPT&O&vJ^Y#(1P?O}{tCi(dy!H_rpPbJ27vW4=t(;+StK^p>)~sEe
zYs=uj6Z~I-%PGQHgajwlRz8C|&OoTwHFJ*%emrCT)^QhFCYzZxfcd_F`JQ3F^ZA}K
zE at sf%daUwEtY0JRWv)!I9*IPY?MXWWee|M_EPfcEI^slN-Jh%_-Jcc7{n^b|LNJsO
z<JED#24eNCJ7e(5S-C4WSrl|;ovIwh3GEttmd)7LBst&r*((^gaJ<v3(xP=6X981`
z9E`_p8gN>4T|ysun8zU&=Q_?j_PUF4cJXok>^RPgEMOXEh2wfGJZ5ZBX~6XqTMvC1
zd`z8eyJS^VIG0!>-!Uc0nw4q;OX;IA*sX2@^Z606z8#e8j=Fa^*@a;JY)JYod3mkm
zPZPbhN)|p9S9Fi8lgyI`dEb;f&U6k?!~dOaQRC~Nv$koRkGjq at qX6fHJDhUISlpe!
z+55Q_VJ*9`md~=E+&VXR8~W4OJ`?Ae$~jx<+pNsQT_&VHTaPa3A2ICdl-wU at yR+*s
zS>3#TQ0ceZmU{_p>w$x9>1(=OvQ}!Gx$gkKr?*+|Ec4%yk2&qhB7I-nw^#G~_LRx@
zi)%Ga4IgMeu5^T(TeOn=NNdX`t*%iG*J^9S`ujC&>yCss)oS6wc3-{{u5D>*P&NG}
zo05EA;kx|I&n#Dz;<na^#^0V?WN$Btc4(=obrE_6U6vtfRo{w0i%M^&w>LGb2URV3
z(R^9FP>X at QrnaliN;AbJ`L$X_OZ$<-YHPj{Y4X?6i(4i64Ykdhn!mZY$f2>JyvSL5
gagk-L#YM?Uqg-61ujl4Uf2Duhwu)V4!Jy3i0g*_Gf&c&j

diff --git a/distutils2/compat.py b/distutils2/compat.py
--- a/distutils2/compat.py
+++ b/distutils2/compat.py
@@ -1,10 +1,10 @@
-""" distutils2.compat
+"""Compatibility helpers.
 
-Used to provide classes, variables and imports which can be used to
-support distutils2 across versions(2.x and 3.x)
+This module provides classes, variables and imports which are used to
+support distutils2 across Python 2.x and 3.x.
 """
 
-import logging
+from distutils2 import logger
 
 
 # XXX Having two classes with the same name is not a good thing.
@@ -20,7 +20,6 @@
     _CONVERT = False
     _KLASS = object
 
-# marking public APIs
 __all__ = ['Mixin2to3']
 
 
@@ -31,6 +30,7 @@
     yet does nothing in particular with it.
     """
     if _CONVERT:
+
         def _run_2to3(self, files, doctests=[], fixers=[]):
             """ Takes a list of files and doctests, and performs conversion
             on those.
@@ -38,22 +38,20 @@
               - Second, the doctests in `files` are converted.
               - Thirdly, the doctests in `doctests` are converted.
             """
-            # if additional fixers are present, use them
             if fixers:
                 self.fixer_names = fixers
 
-            # Convert the ".py" files.
-            logging.info("Converting Python code")
+            logger.info('converting Python code')
             _KLASS.run_2to3(self, files)
 
-            # Convert the doctests in the ".py" files.
-            logging.info("Converting doctests with '.py' files")
+            logger.info('converting doctests in Python files')
             _KLASS.run_2to3(self, files, doctests_only=True)
 
             if doctests != []:
-                logging.info("Converting text files which contain doctests")
+                logger.info('converting doctest in text files')
                 _KLASS.run_2to3(self, doctests, doctests_only=True)
     else:
         # If run on Python 2.x, there is nothing to do.
+
         def _run_2to3(self, files, doctests=[], fixers=[]):
             pass
diff --git a/distutils2/compiler/__init__.py b/distutils2/compiler/__init__.py
--- a/distutils2/compiler/__init__.py
+++ b/distutils2/compiler/__init__.py
@@ -1,11 +1,26 @@
+"""Compiler abstraction model used by distutils2.
+
+An abstract base class is defined in the ccompiler submodule, and
+concrete implementations suitable for various platforms are defined in
+the other submodules.  The extension module is also placed in this
+package.
+
+In general, code should not instantiate compiler classes directly but
+use the new_compiler and customize_compiler functions provided in this
+module.
+
+The compiler system has a registration API: get_default_compiler,
+set_compiler, show_compilers.
+"""
+
 import os
 import sys
 import re
+import sysconfig
 
-from distutils2._backport import sysconfig
 from distutils2.util import resolve_name
-from distutils2.errors import DistutilsPlatformError
-
+from distutils2.errors import PackagingPlatformError
+from distutils2 import logger
 
 def customize_compiler(compiler):
     """Do any platform-specific customization of a CCompiler instance.
@@ -14,10 +29,10 @@
     varies across Unices and is stored in Python's Makefile.
     """
     if compiler.name == "unix":
-        (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \
+        cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags = (
             sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS',
-                                       'CCSHARED', 'LDSHARED', 'SO', 'AR',
-                                       'ARFLAGS')
+                                      'CCSHARED', 'LDSHARED', 'SO', 'AR',
+                                      'ARFLAGS'))
 
         if 'CC' in os.environ:
             cc = os.environ['CC']
@@ -68,19 +83,16 @@
 # patterns. Order is important; platform mappings are preferred over
 # OS names.
 _default_compilers = (
-
     # Platform string mappings
 
     # on a cygwin built python we can use gcc like an ordinary UNIXish
     # compiler
     ('cygwin.*', 'unix'),
-    ('os2emx', 'emx'),
 
     # OS name mappings
     ('posix', 'unix'),
     ('nt', 'msvc'),
-
-    )
+)
 
 def get_default_compiler(osname=None, platform=None):
     """ Determine the default compiler to use for the given platform.
@@ -101,17 +113,19 @@
         if re.match(pattern, platform) is not None or \
            re.match(pattern, osname) is not None:
             return compiler
-    # Default to Unix compiler
+    # Defaults to Unix compiler
     return 'unix'
 
 
+# compiler mapping
+# XXX useful to expose them? (i.e. get_compiler_names)
 _COMPILERS = {
     'unix': 'distutils2.compiler.unixccompiler.UnixCCompiler',
     'msvc': 'distutils2.compiler.msvccompiler.MSVCCompiler',
     'cygwin': 'distutils2.compiler.cygwinccompiler.CygwinCCompiler',
     'mingw32': 'distutils2.compiler.cygwinccompiler.Mingw32CCompiler',
-    'bcpp': 'distutils2.compilers.bcppcompiler.BCPPCompiler'}
-
+    'bcpp': 'distutils2.compiler.bcppcompiler.BCPPCompiler',
+}
 
 def set_compiler(location):
     """Add or change a compiler"""
@@ -127,8 +141,8 @@
     from distutils2.fancy_getopt import FancyGetopt
     compilers = []
 
-    for name, cls in _COMPILERS.iteritems():
-        if isinstance(cls, str):
+    for name, cls in _COMPILERS.items():
+        if isinstance(cls, basestring):
             cls = resolve_name(cls)
             _COMPILERS[name] = cls
 
@@ -139,7 +153,8 @@
     pretty_printer.print_help("List of available compilers:")
 
 
-def new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0):
+def new_compiler(plat=None, compiler=None, verbose=0, dry_run=False,
+                 force=False):
     """Generate an instance of some CCompiler subclass for the supplied
     platform/compiler combination.  'plat' defaults to 'os.name'
     (eg. 'posix', 'nt'), and 'compiler' defaults to the default compiler
@@ -162,9 +177,9 @@
         msg = "don't know how to compile C/C++ code on platform '%s'" % plat
         if compiler is not None:
             msg = msg + " with '%s' compiler" % compiler
-        raise DistutilsPlatformError(msg)
+        raise PackagingPlatformError(msg)
 
-    if isinstance(cls, str):
+    if isinstance(cls, basestring):
         cls = resolve_name(cls)
         _COMPILERS[compiler] = cls
 
@@ -200,26 +215,24 @@
     pp_opts = []
     for macro in macros:
 
-        if not (isinstance(macro, tuple) and
-                1 <= len (macro) <= 2):
-            raise TypeError, \
-                  ("bad macro definition '%s': " +
-                   "each element of 'macros' list must be a 1- or 2-tuple") % \
-                  macro
+        if not isinstance(macro, tuple) and 1 <= len(macro) <= 2:
+            raise TypeError(
+                "bad macro definition '%s': each element of 'macros'"
+                "list must be a 1- or 2-tuple" % macro)
 
-        if len (macro) == 1:        # undefine this macro
-            pp_opts.append ("-U%s" % macro[0])
-        elif len (macro) == 2:
+        if len(macro) == 1:        # undefine this macro
+            pp_opts.append("-U%s" % macro[0])
+        elif len(macro) == 2:
             if macro[1] is None:    # define with no explicit value
-                pp_opts.append ("-D%s" % macro[0])
+                pp_opts.append("-D%s" % macro[0])
             else:
                 # XXX *don't* need to be clever about quoting the
                 # macro value here, because we're going to avoid the
                 # shell at all costs when we spawn the command!
-                pp_opts.append ("-D%s=%s" % macro)
+                pp_opts.append("-D%s=%s" % macro)
 
     for dir in include_dirs:
-        pp_opts.append ("-I%s" % dir)
+        pp_opts.append("-I%s" % dir)
 
     return pp_opts
 
@@ -258,7 +271,7 @@
             if lib_file is not None:
                 lib_opts.append(lib_file)
             else:
-                compiler.warn("no library file corresponding to "
+                logger.warning("no library file corresponding to "
                               "'%s' found (skipping)" % lib)
         else:
             lib_opts.append(compiler.library_option(lib))
diff --git a/distutils2/compiler/bcppcompiler.py b/distutils2/compiler/bcppcompiler.py
--- a/distutils2/compiler/bcppcompiler.py
+++ b/distutils2/compiler/bcppcompiler.py
@@ -1,8 +1,4 @@
-"""distutils.bcppcompiler
-
-Contains BorlandCCompiler, an implementation of the abstract CCompiler class
-for the Borland C++ compiler.
-"""
+"""CCompiler implementation for the Borland C++ compiler."""
 
 # This implementation by Lyle Johnson, based on the original msvccompiler.py
 # module and using the directions originally published by Gordon Williams.
@@ -10,10 +6,11 @@
 # XXX looks like there's a LOT of overlap between these two classes:
 # someone should sit down and factor out the common code as
 # WindowsCCompiler!  --GPW
-import os
 
-from distutils2.errors import (DistutilsExecError, CompileError, LibError,
-                               LinkError, UnknownFileError)
+import os, sys
+
+from distutils2.errors import (PackagingExecError, CompileError, LibError,
+                              LinkError, UnknownFileError)
 from distutils2.compiler.ccompiler import CCompiler
 from distutils2.compiler import gen_preprocess_options
 from distutils2.file_util import write_file
@@ -50,12 +47,8 @@
     exe_extension = '.exe'
 
 
-    def __init__ (self,
-                  verbose=0,
-                  dry_run=0,
-                  force=0):
-
-        CCompiler.__init__ (self, verbose, dry_run, force)
+    def __init__(self, verbose=0, dry_run=False, force=False):
+        CCompiler.__init__(self, verbose, dry_run, force)
 
         # These executables are assumed to all be in the path.
         # Borland doesn't seem to use any special registry settings to
@@ -79,18 +72,18 @@
     # -- Worker methods ------------------------------------------------
 
     def compile(self, sources,
-                output_dir=None, macros=None, include_dirs=None, debug=0,
+                output_dir=None, macros=None, include_dirs=None, debug=False,
                 extra_preargs=None, extra_postargs=None, depends=None):
 
         macros, objects, extra_postargs, pp_opts, build = \
                 self._setup_compile(output_dir, macros, include_dirs, sources,
                                     depends, extra_postargs)
         compile_opts = extra_preargs or []
-        compile_opts.append ('-c')
+        compile_opts.append('-c')
         if debug:
-            compile_opts.extend (self.compile_options_debug)
+            compile_opts.extend(self.compile_options_debug)
         else:
-            compile_opts.extend (self.compile_options)
+            compile_opts.extend(self.compile_options)
 
         for obj in objects:
             try:
@@ -110,9 +103,9 @@
             if ext == '.rc':
                 # This needs to be compiled to a .res file -- do it now.
                 try:
-                    self.spawn (["brcc32", "-fo", obj, src])
-                except DistutilsExecError, msg:
-                    raise CompileError, msg
+                    self.spawn(["brcc32", "-fo", obj, src])
+                except PackagingExecError:
+                    raise CompileError(sys.exc_info()[1])
                 continue # the 'for' loop
 
             # The next two are both for the real compiler.
@@ -132,72 +125,53 @@
             # Note that the source file names must appear at the end of
             # the command line.
             try:
-                self.spawn ([self.cc] + compile_opts + pp_opts +
-                            [input_opt, output_opt] +
-                            extra_postargs + [src])
-            except DistutilsExecError, msg:
-                raise CompileError, msg
+                self.spawn([self.cc] + compile_opts + pp_opts +
+                           [input_opt, output_opt] +
+                           extra_postargs + [src])
+            except PackagingExecError:
+                raise CompileError(sys.exc_info()[1])
 
         return objects
 
-    # compile ()
 
+    def create_static_lib(self, objects, output_libname, output_dir=None,
+                          debug=False, target_lang=None):
+        objects, output_dir = self._fix_object_args(objects, output_dir)
+        output_filename = \
+            self.library_filename(output_libname, output_dir=output_dir)
 
-    def create_static_lib (self,
-                           objects,
-                           output_libname,
-                           output_dir=None,
-                           debug=0,
-                           target_lang=None):
-
-        (objects, output_dir) = self._fix_object_args (objects, output_dir)
-        output_filename = \
-            self.library_filename (output_libname, output_dir=output_dir)
-
-        if self._need_link (objects, output_filename):
+        if self._need_link(objects, output_filename):
             lib_args = [output_filename, '/u'] + objects
             if debug:
                 pass                    # XXX what goes here?
             try:
-                self.spawn ([self.lib] + lib_args)
-            except DistutilsExecError, msg:
-                raise LibError, msg
+                self.spawn([self.lib] + lib_args)
+            except PackagingExecError:
+                raise LibError(sys.exc_info()[1])
         else:
             logger.debug("skipping %s (up-to-date)", output_filename)
 
-    # create_static_lib ()
 
-
-    def link (self,
-              target_desc,
-              objects,
-              output_filename,
-              output_dir=None,
-              libraries=None,
-              library_dirs=None,
-              runtime_library_dirs=None,
-              export_symbols=None,
-              debug=0,
-              extra_preargs=None,
-              extra_postargs=None,
-              build_temp=None,
-              target_lang=None):
+    def link(self, target_desc, objects, output_filename, output_dir=None,
+             libraries=None, library_dirs=None, runtime_library_dirs=None,
+             export_symbols=None, debug=False, extra_preargs=None,
+             extra_postargs=None, build_temp=None, target_lang=None):
 
         # XXX this ignores 'build_temp'!  should follow the lead of
         # msvccompiler.py
 
-        (objects, output_dir) = self._fix_object_args (objects, output_dir)
-        (libraries, library_dirs, runtime_library_dirs) = \
-            self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
+        objects, output_dir = self._fix_object_args(objects, output_dir)
+        libraries, library_dirs, runtime_library_dirs = \
+            self._fix_lib_args(libraries, library_dirs, runtime_library_dirs)
 
         if runtime_library_dirs:
             logger.warning("don't know what to do with "
                            "'runtime_library_dirs': %r", runtime_library_dirs)
 
         if output_dir is not None:
-            output_filename = os.path.join (output_dir, output_filename)
+            output_filename = os.path.join(output_dir, output_filename)
 
-        if self._need_link (objects, output_filename):
+        if self._need_link(objects, output_filename):
 
             # Figure out linker args based on type of target.
             if target_desc == CCompiler.EXECUTABLE:
@@ -218,10 +192,10 @@
             if export_symbols is None:
                 def_file = ''
             else:
-                head, tail = os.path.split (output_filename)
-                modname, ext = os.path.splitext (tail)
+                head, tail = os.path.split(output_filename)
+                modname, ext = os.path.splitext(tail)
                 temp_dir = os.path.dirname(objects[0]) # preserve tree structure
-                def_file = os.path.join (temp_dir, '%s.def' % modname)
+                def_file = os.path.join(temp_dir, '%s.def' % modname)
                 contents = ['EXPORTS']
                 for sym in (export_symbols or []):
                     contents.append('  %s=_%s' % (sym, sym))
@@ -229,13 +203,13 @@
                              "writing %s" % def_file)
 
             # Borland C++ has problems with '/' in paths
-            objects2 = map(os.path.normpath, objects)
+            objects2 = [os.path.normpath(o) for o in objects]
             # split objects in .obj and .res files
             # Borland C++ needs them at different positions in the command line
             objects = [startup_obj]
             resources = []
             for file in objects2:
-                (base, ext) = os.path.splitext(os.path.normcase(file))
+                base, ext = os.path.splitext(os.path.normcase(file))
                 if ext == '.res':
                     resources.append(file)
                 else:
@@ -260,7 +234,7 @@
             # them.  Arghghh!.  Apparently it works fine as coded...
 
             # name of dll/exe file
-            ld_args.extend([',',output_filename])
+            ld_args.extend((',',output_filename))
             # no map file and start libraries
             ld_args.append(',,')
 
@@ -276,11 +250,11 @@
                     ld_args.append(libfile)
 
             # some default libraries
-            ld_args.append ('import32')
-            ld_args.append ('cw32mt')
+            ld_args.append('import32')
+            ld_args.append('cw32mt')
 
             # def file for export symbols
-            ld_args.extend([',',def_file])
+            ld_args.extend((',',def_file))
             # add resource files
             ld_args.append(',')
             ld_args.extend(resources)
@@ -291,27 +265,25 @@
             if extra_postargs:
                 ld_args.extend(extra_postargs)
 
-            self.mkpath (os.path.dirname (output_filename))
+            self.mkpath(os.path.dirname(output_filename))
             try:
-                self.spawn ([self.linker] + ld_args)
-            except DistutilsExecError, msg:
-                raise LinkError, msg
+                self.spawn([self.linker] + ld_args)
+            except PackagingExecError:
+                raise LinkError(sys.exc_info()[1])
 
         else:
             logger.debug("skipping %s (up-to-date)", output_filename)
 
-    # link ()
-
     # -- Miscellaneous methods -----------------------------------------
 
 
-    def find_library_file (self, dirs, lib, debug=0):
+    def find_library_file(self, dirs, lib, debug=False):
         # List of effective library names to try, in order of preference:
         # xxx_bcpp.lib is better than xxx.lib
         # and xxx_d.lib is better than xxx.lib if debug is set
         #
         # The "_bcpp" suffix is to handle a Python installation for people
-        # with multiple compilers (primarily Distutils hackers, I suspect
+        # with multiple compilers (primarily Packaging hackers, I suspect
         # ;-).  The idea is they'd have one static library for each
         # compiler they care about, since (almost?) every Windows compiler
         # seems to have a different format for static libraries.
@@ -331,43 +303,35 @@
             return None
 
     # overwrite the one from CCompiler to support rc and res-files
-    def object_filenames (self,
-                          source_filenames,
-                          strip_dir=0,
-                          output_dir=''):
-        if output_dir is None: output_dir = ''
+    def object_filenames(self, source_filenames, strip_dir=False,
+                         output_dir=''):
+        if output_dir is None:
+            output_dir = ''
         obj_names = []
         for src_name in source_filenames:
             # use normcase to make sure '.rc' is really '.rc' and not '.RC'
-            (base, ext) = os.path.splitext (os.path.normcase(src_name))
+            base, ext = os.path.splitext(os.path.normcase(src_name))
             if ext not in (self.src_extensions + ['.rc','.res']):
-                raise UnknownFileError, \
-                      "unknown file type '%s' (from '%s')" % \
-                      (ext, src_name)
+                raise UnknownFileError("unknown file type '%s' (from '%s')" % \
+                      (ext, src_name))
             if strip_dir:
-                base = os.path.basename (base)
+                base = os.path.basename(base)
             if ext == '.res':
                 # these can go unchanged
-                obj_names.append (os.path.join (output_dir, base + ext))
+                obj_names.append(os.path.join(output_dir, base + ext))
             elif ext == '.rc':
                 # these need to be compiled to .res-files
-                obj_names.append (os.path.join (output_dir, base + '.res'))
+                obj_names.append(os.path.join(output_dir, base + '.res'))
             else:
-                obj_names.append (os.path.join (output_dir,
-                                            base + self.obj_extension))
+                obj_names.append(os.path.join(output_dir,
+                                              base + self.obj_extension))
         return obj_names
 
-    # object_filenames ()
 
-    def preprocess (self,
-                    source,
-                    output_file=None,
-                    macros=None,
-                    include_dirs=None,
-                    extra_preargs=None,
-                    extra_postargs=None):
-
-        (_, macros, include_dirs) = \
+    def preprocess(self, source, output_file=None, macros=None,
+                   include_dirs=None, extra_preargs=None,
+                   extra_postargs=None):
+        _, macros, include_dirs = \
             self._fix_compile_args(None, macros, include_dirs)
         pp_opts = gen_preprocess_options(macros, include_dirs)
         pp_args = ['cpp32.exe'] + pp_opts
@@ -387,8 +351,7 @@
                 self.mkpath(os.path.dirname(output_file))
             try:
                 self.spawn(pp_args)
-            except DistutilsExecError, msg:
-                print msg
-                raise CompileError, msg
-
-    # preprocess()
+            except PackagingExecError:
+                msg = sys.exc_info()[1]
+                print(msg)
+                raise CompileError(msg)
diff --git a/distutils2/compiler/ccompiler.py b/distutils2/compiler/ccompiler.py
--- a/distutils2/compiler/ccompiler.py
+++ b/distutils2/compiler/ccompiler.py
@@ -1,18 +1,15 @@
-"""distutils.ccompiler
+"""Abstract base class for compilers.
 
-Contains CCompiler, an abstract base class that defines the interface
-for the Distutils compiler abstraction model."""
+This modules contains CCompiler, an abstract base class that defines the
+interface for the compiler abstraction model used by distutils2.
+"""
 
-
+import os
 import sys
-import os
-import re
 from shutil import move
-
-from distutils2.errors import (CompileError, LinkError, UnknownFileError,
-                               DistutilsPlatformError, DistutilsModuleError)
+from distutils2 import logger
 from distutils2.util import split_quoted, execute, newer_group, spawn
-from distutils2 import logger
+from distutils2.errors import (CompileError, LinkError, UnknownFileError)
 from distutils2.compiler import gen_preprocess_options
 
 
@@ -75,15 +72,15 @@
     # what language to use when mixing source types. For example, if some
     # extension has two files with ".c" extension, and one with ".cpp", it
     # is still linked as c++.
-    language_map = {".c"   : "c",
-                    ".cc"  : "c++",
-                    ".cpp" : "c++",
-                    ".cxx" : "c++",
-                    ".m"   : "objc",
+    language_map = {".c": "c",
+                    ".cc": "c++",
+                    ".cpp": "c++",
+                    ".cxx": "c++",
+                    ".m": "objc",
                    }
     language_order = ["c++", "objc", "c"]
 
-    def __init__ (self, verbose=0, dry_run=0, force=0):
+    def __init__(self, verbose=0, dry_run=False, force=False):
         self.dry_run = dry_run
         self.force = force
         self.verbose = verbose
@@ -116,7 +113,7 @@
         # named library files) to include on any link
         self.objects = []
 
-        for key, value in self.executables.iteritems():
+        for key, value in self.executables.items():
             self.set_executable(key, value)
 
     def set_executables(self, **args):
@@ -145,15 +142,14 @@
         # discovered at run-time, since there are many different ways to do
         # basically the same things with Unix C compilers.
 
-        for key, value in args.iteritems():
+        for key, value in args.items():
             if key not in self.executables:
-                raise ValueError, \
-                      "unknown executable '%s' for class %s" % \
-                      (key, self.__class__.__name__)
+                raise ValueError("unknown executable '%s' for class %s" % \
+                      (key, self.__class__.__name__))
             self.set_executable(key, value)
 
     def set_executable(self, key, value):
-        if isinstance(value, str):
+        if isinstance(value, basestring):
             setattr(self, key, split_quoted(value))
         else:
             setattr(self, key, value)
@@ -173,14 +169,13 @@
         """
         for defn in definitions:
             if not (isinstance(defn, tuple) and
-                    (len (defn) == 1 or
-                     (len (defn) == 2 and
-                      (isinstance(defn[1], str) or defn[1] is None))) and
-                    isinstance(defn[0], str)):
-                raise TypeError, \
-                      ("invalid macro definition '%s': " % defn) + \
+                    (len(defn) == 1 or
+                     (len(defn) == 2 and
+                      (isinstance(defn[1], basestring) or defn[1] is None))) and
+                    isinstance(defn[0], basestring)):
+                raise TypeError(("invalid macro definition '%s': " % defn) + \
                       "must be tuple (string,), (string, string), or " + \
-                      "(string, None)"
+                      "(string, None)")
 
 
     # -- Bookkeeping methods -------------------------------------------
@@ -194,12 +189,12 @@
         """
         # Delete from the list of macro definitions/undefinitions if
         # already there (so that this one will take precedence).
-        i = self._find_macro (name)
+        i = self._find_macro(name)
         if i is not None:
             del self.macros[i]
 
         defn = (name, value)
-        self.macros.append (defn)
+        self.macros.append(defn)
 
     def undefine_macro(self, name):
         """Undefine a preprocessor macro for all compilations driven by
@@ -212,12 +207,12 @@
         """
         # Delete from the list of macro definitions/undefinitions if
         # already there (so that this one will take precedence).
-        i = self._find_macro (name)
+        i = self._find_macro(name)
         if i is not None:
             del self.macros[i]
 
         undefn = (name,)
-        self.macros.append (undefn)
+        self.macros.append(undefn)
 
     def add_include_dir(self, dir):
         """Add 'dir' to the list of directories that will be searched for
@@ -225,7 +220,7 @@
         the order in which they are supplied by successive calls to
         'add_include_dir()'.
         """
-        self.include_dirs.append (dir)
+        self.include_dirs.append(dir)
 
     def set_include_dirs(self, dirs):
         """Set the list of directories that will be searched to 'dirs' (a
@@ -251,7 +246,7 @@
         names; the linker will be instructed to link against libraries as
         many times as they are mentioned.
         """
-        self.libraries.append (libname)
+        self.libraries.append(libname)
 
     def set_libraries(self, libnames):
         """Set the list of libraries to be included in all links driven by
@@ -312,36 +307,35 @@
     # (here for the convenience of subclasses)
 
     # Helper method to prep compiler in subclass compile() methods
-
     def _setup_compile(self, outdir, macros, incdirs, sources, depends,
                        extra):
         """Process arguments and decide which source files to compile."""
         if outdir is None:
             outdir = self.output_dir
-        elif not isinstance(outdir, str):
-            raise TypeError, "'output_dir' must be a string or None"
+        elif not isinstance(outdir, basestring):
+            raise TypeError("'output_dir' must be a string or None")
 
         if macros is None:
             macros = self.macros
         elif isinstance(macros, list):
             macros = macros + (self.macros or [])
         else:
-            raise TypeError, "'macros' (if supplied) must be a list of tuples"
+            raise TypeError("'macros' (if supplied) must be a list of tuples")
 
         if incdirs is None:
             incdirs = self.include_dirs
         elif isinstance(incdirs, (list, tuple)):
             incdirs = list(incdirs) + (self.include_dirs or [])
         else:
-            raise TypeError, \
-                  "'include_dirs' (if supplied) must be a list of strings"
+            raise TypeError(
+                "'include_dirs' (if supplied) must be a list of strings")
 
         if extra is None:
             extra = []
 
         # Get the list of expected output (object) files
         objects = self.object_filenames(sources,
-                                        strip_dir=0,
+                                        strip_dir=False,
                                         output_dir=outdir)
         assert len(objects) == len(sources)
 
@@ -358,7 +352,7 @@
         return macros, objects, extra, pp_opts, build
 
     def _get_cc_args(self, pp_opts, debug, before):
-        # works for unixccompiler, emxccompiler, cygwinccompiler
+        # works for unixccompiler and cygwinccompiler
         cc_args = pp_opts + ['-c']
         if debug:
             cc_args[:0] = ['-g']
@@ -378,23 +372,23 @@
         """
         if output_dir is None:
             output_dir = self.output_dir
-        elif not isinstance(output_dir, str):
-            raise TypeError, "'output_dir' must be a string or None"
+        elif not isinstance(output_dir, basestring):
+            raise TypeError("'output_dir' must be a string or None")
 
         if macros is None:
             macros = self.macros
         elif isinstance(macros, list):
             macros = macros + (self.macros or [])
         else:
-            raise TypeError, "'macros' (if supplied) must be a list of tuples"
+            raise TypeError("'macros' (if supplied) must be a list of tuples")
 
         if include_dirs is None:
             include_dirs = self.include_dirs
         elif isinstance(include_dirs, (list, tuple)):
-            include_dirs = list (include_dirs) + (self.include_dirs or [])
+            include_dirs = list(include_dirs) + (self.include_dirs or [])
         else:
-            raise TypeError, \
-                  "'include_dirs' (if supplied) must be a list of strings"
+            raise TypeError(
+                "'include_dirs' (if supplied) must be a list of strings")
 
         return output_dir, macros, include_dirs
 
@@ -405,16 +399,15 @@
         'objects' and 'output_dir'.
         """
         if not isinstance(objects, (list, tuple)):
-            raise TypeError, \
-                  "'objects' must be a list or tuple of strings"
-        objects = list (objects)
+            raise TypeError("'objects' must be a list or tuple of strings")
+        objects = list(objects)
 
         if output_dir is None:
             output_dir = self.output_dir
-        elif not isinstance(output_dir, str):
-            raise TypeError, "'output_dir' must be a string or None"
+        elif not isinstance(output_dir, basestring):
+            raise TypeError("'output_dir' must be a string or None")
 
-        return (objects, output_dir)
+        return objects, output_dir
 
     def _fix_lib_args(self, libraries, library_dirs, runtime_library_dirs):
         """Typecheck and fix up some of the arguments supplied to the
@@ -426,37 +419,36 @@
         if libraries is None:
             libraries = self.libraries
         elif isinstance(libraries, (list, tuple)):
-            libraries = list (libraries) + (self.libraries or [])
+            libraries = list(libraries) + (self.libraries or [])
         else:
-            raise TypeError, \
-                  "'libraries' (if supplied) must be a list of strings"
+            raise TypeError(
+                "'libraries' (if supplied) must be a list of strings")
 
         if library_dirs is None:
             library_dirs = self.library_dirs
         elif isinstance(library_dirs, (list, tuple)):
-            library_dirs = list (library_dirs) + (self.library_dirs or [])
+            library_dirs = list(library_dirs) + (self.library_dirs or [])
         else:
-            raise TypeError, \
-                  "'library_dirs' (if supplied) must be a list of strings"
+            raise TypeError(
+                "'library_dirs' (if supplied) must be a list of strings")
 
         if runtime_library_dirs is None:
             runtime_library_dirs = self.runtime_library_dirs
         elif isinstance(runtime_library_dirs, (list, tuple)):
-            runtime_library_dirs = (list (runtime_library_dirs) +
+            runtime_library_dirs = (list(runtime_library_dirs) +
                                     (self.runtime_library_dirs or []))
         else:
-            raise TypeError, \
-                  "'runtime_library_dirs' (if supplied) " + \
-                  "must be a list of strings"
+            raise TypeError("'runtime_library_dirs' (if supplied) "
+                            "must be a list of strings")
 
-        return (libraries, library_dirs, runtime_library_dirs)
+        return libraries, library_dirs, runtime_library_dirs
 
     def _need_link(self, objects, output_file):
         """Return true if we need to relink the files listed in 'objects'
         to recreate 'output_file'.
         """
         if self.force:
-            return 1
+            return True
         else:
             if self.dry_run:
                 newer = newer_group(objects, output_file, missing='newer')
@@ -501,7 +493,7 @@
         pass
 
     def compile(self, sources, output_dir=None, macros=None,
-                include_dirs=None, debug=0, extra_preargs=None,
+                include_dirs=None, debug=False, extra_preargs=None,
                 extra_postargs=None, depends=None):
         """Compile one or more source files.
 
@@ -577,7 +569,7 @@
         pass
 
     def create_static_lib(self, objects, output_libname, output_dir=None,
-                          debug=0, target_lang=None):
+                          debug=False, target_lang=None):
         """Link a bunch of stuff together to create a static library file.
         The "bunch of stuff" consists of the list of object files supplied
         as 'objects', the extra object files supplied to
@@ -609,7 +601,7 @@
 
     def link(self, target_desc, objects, output_filename, output_dir=None,
              libraries=None, library_dirs=None, runtime_library_dirs=None,
-             export_symbols=None, debug=0, extra_preargs=None,
+             export_symbols=None, debug=False, extra_preargs=None,
              extra_postargs=None, build_temp=None, target_lang=None):
         """Link a bunch of stuff together to create an executable or
         shared library file.
@@ -662,7 +654,7 @@
     def link_shared_lib(self, objects, output_libname, output_dir=None,
                         libraries=None, library_dirs=None,
                         runtime_library_dirs=None, export_symbols=None,
-                        debug=0, extra_preargs=None, extra_postargs=None,
+                        debug=False, extra_preargs=None, extra_postargs=None,
                         build_temp=None, target_lang=None):
         self.link(CCompiler.SHARED_LIBRARY, objects,
                   self.library_filename(output_libname, lib_type='shared'),
@@ -671,11 +663,10 @@
                   export_symbols, debug,
                   extra_preargs, extra_postargs, build_temp, target_lang)
 
-
     def link_shared_object(self, objects, output_filename, output_dir=None,
                            libraries=None, library_dirs=None,
                            runtime_library_dirs=None, export_symbols=None,
-                           debug=0, extra_preargs=None, extra_postargs=None,
+                           debug=False, extra_preargs=None, extra_postargs=None,
                            build_temp=None, target_lang=None):
         self.link(CCompiler.SHARED_OBJECT, objects,
                   output_filename, output_dir,
@@ -685,8 +676,9 @@
 
     def link_executable(self, objects, output_progname, output_dir=None,
                         libraries=None, library_dirs=None,
-                        runtime_library_dirs=None, debug=0, extra_preargs=None,
-                        extra_postargs=None, target_lang=None):
+                        runtime_library_dirs=None, debug=False,
+                        extra_preargs=None, extra_postargs=None,
+                        target_lang=None):
         self.link(CCompiler.EXECUTABLE, objects,
                   self.executable_filename(output_progname), output_dir,
                   libraries, library_dirs, runtime_library_dirs, None,
@@ -736,8 +728,7 @@
         if library_dirs is None:
             library_dirs = []
         fd, fname = tempfile.mkstemp(".c", funcname, text=True)
-        f = os.fdopen(fd, "w")
-        try:
+        with os.fdopen(fd, "w") as f:
             for incl in includes:
                 f.write("""#include "%s"\n""" % incl)
             f.write("""\
@@ -745,8 +736,6 @@
     %s();
 }
 """ % funcname)
-        finally:
-            f.close()
         try:
             objects = self.compile([fname], include_dirs=include_dirs)
         except CompileError:
@@ -760,10 +749,10 @@
             return False
         return True
 
-    def find_library_file (self, dirs, lib, debug=0):
+    def find_library_file(self, dirs, lib, debug=False):
         """Search the specified list of directories for a static or shared
         library file 'lib' and return the full path to that file.  If
-        'debug' true, look for a debugging version (if that makes sense on
+        'debug' is true, look for a debugging version (if that makes sense on
         the current platform).  Return None if 'lib' wasn't found in any of
         the specified directories.
         """
@@ -803,44 +792,45 @@
     #   * exe_extension -
     #     extension for executable files, eg. '' or '.exe'
 
-    def object_filenames(self, source_filenames, strip_dir=0, output_dir=''):
+    def object_filenames(self, source_filenames, strip_dir=False, output_dir=''):
         if output_dir is None:
             output_dir = ''
         obj_names = []
         for src_name in source_filenames:
             base, ext = os.path.splitext(src_name)
-            base = os.path.splitdrive(base)[1] # Chop off the drive
+            base = os.path.splitdrive(base)[1]  # Chop off the drive
             base = base[os.path.isabs(base):]  # If abs, chop off leading /
             if ext not in self.src_extensions:
-                raise UnknownFileError, \
-                      "unknown file type '%s' (from '%s')" % (ext, src_name)
+                raise UnknownFileError("unknown file type '%s' (from '%s')" %
+                                       (ext, src_name))
             if strip_dir:
                 base = os.path.basename(base)
             obj_names.append(os.path.join(output_dir,
                                           base + self.obj_extension))
         return obj_names
 
-    def shared_object_filename(self, basename, strip_dir=0, output_dir=''):
+    def shared_object_filename(self, basename, strip_dir=False, output_dir=''):
         assert output_dir is not None
         if strip_dir:
-            basename = os.path.basename (basename)
+            basename = os.path.basename(basename)
         return os.path.join(output_dir, basename + self.shared_lib_extension)
 
-    def executable_filename(self, basename, strip_dir=0, output_dir=''):
+    def executable_filename(self, basename, strip_dir=False, output_dir=''):
         assert output_dir is not None
         if strip_dir:
-            basename = os.path.basename (basename)
+            basename = os.path.basename(basename)
         return os.path.join(output_dir, basename + (self.exe_extension or ''))
 
     def library_filename(self, libname, lib_type='static',     # or 'shared'
-                         strip_dir=0, output_dir=''):
+                         strip_dir=False, output_dir=''):
         assert output_dir is not None
         if lib_type not in ("static", "shared", "dylib"):
-            raise ValueError, "'lib_type' must be \"static\", \"shared\" or \"dylib\""
+            raise ValueError(
+                "'lib_type' must be 'static', 'shared' or 'dylib'")
         fmt = getattr(self, lib_type + "_lib_format")
         ext = getattr(self, lib_type + "_lib_extension")
 
-        dir, base = os.path.split (libname)
+        dir, base = os.path.split(libname)
         filename = fmt % (base, ext)
         if strip_dir:
             dir = ''
@@ -850,19 +840,6 @@
 
     # -- Utility methods -----------------------------------------------
 
-    # TODO use logging.info
-    def announce(self, msg, level=None):
-        logger.debug(msg)
-
-    def debug_print(self, msg):
-        from distutils2.debug import DEBUG
-        if DEBUG:
-            print msg
-
-    # TODO use logging.warn
-    def warn(self, msg):
-        sys.stderr.write("warning: %s\n" % msg)
-
     def execute(self, func, args, msg=None, level=1):
         execute(func, args, msg, self.dry_run)
 
@@ -870,11 +847,12 @@
         spawn(cmd, dry_run=self.dry_run)
 
     def move_file(self, src, dst):
+        logger.info("moving %r to %r", src, dst)
         if self.dry_run:
-            return # XXX log ?
+            return
         return move(src, dst)
 
-    def mkpath(self, name, mode=0777):
+    def mkpath(self, name, mode=0o777):
         name = os.path.normpath(name)
         if os.path.isdir(name) or name == '':
             return
diff --git a/distutils2/compiler/cygwinccompiler.py b/distutils2/compiler/cygwinccompiler.py
--- a/distutils2/compiler/cygwinccompiler.py
+++ b/distutils2/compiler/cygwinccompiler.py
@@ -1,9 +1,9 @@
-"""distutils.cygwinccompiler
+"""CCompiler implementations for Cygwin and mingw32 versions of GCC.
 
-Provides the CygwinCCompiler class, a subclass of UnixCCompiler that
-handles the Cygwin port of the GNU C compiler to Windows.  It also contains
-the Mingw32CCompiler class which handles the mingw32 port of GCC (same as
-cygwin in no-cygwin mode).
+This module contains the CygwinCCompiler class, a subclass of
+UnixCCompiler that handles the Cygwin port of the GNU C compiler to
+Windows, and the Mingw32CCompiler class which handles the mingw32 port
+of GCC (same as cygwin in no-cygwin mode).
 """
 
 # problems:
@@ -48,15 +48,13 @@
 
 import os
 import sys
-import copy
-import re
-from warnings import warn
 
+from distutils2 import logger
 from distutils2.compiler.unixccompiler import UnixCCompiler
 from distutils2.util import write_file
-from distutils2.errors import DistutilsExecError, CompileError, UnknownFileError
+from distutils2.errors import PackagingExecError, CompileError, UnknownFileError
 from distutils2.util import get_compiler_versions
-from distutils2._backport import sysconfig
+import sysconfig
 
 
 def get_msvcr():
@@ -94,13 +92,12 @@
     shared_lib_format = "%s%s"
     exe_extension = ".exe"
 
-    def __init__(self, verbose=0, dry_run=0, force=0):
+    def __init__(self, verbose=0, dry_run=False, force=False):
 
         UnixCCompiler.__init__(self, verbose, dry_run, force)
 
         status, details = check_config_h()
-        self.debug_print("Python's GCC status: %s (details: %s)" %
-                         (status, details))
+        logger.debug("Python's GCC status: %s (details: %s)", status, details)
         if status is not CONFIG_H_OK:
             self.warn(
                 "Python's pyconfig.h doesn't seem to support your compiler. "
@@ -110,10 +107,10 @@
 
         self.gcc_version, self.ld_version, self.dllwrap_version = \
             get_compiler_versions()
-        self.debug_print(self.name + ": gcc %s, ld %s, dllwrap %s\n" %
-                         (self.gcc_version,
-                          self.ld_version,
-                          self.dllwrap_version) )
+        logger.debug(self.name + ": gcc %s, ld %s, dllwrap %s\n",
+                     self.gcc_version,
+                     self.ld_version,
+                     self.dllwrap_version)
 
         # ld_version >= "2.10.90" and < "2.13" should also be able to use
         # gcc -mdll instead of dllwrap
@@ -154,29 +151,29 @@
             self.dll_libraries = get_msvcr()
 
     def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
-        """Compiles the source by spawing GCC and windres if needed."""
+        """Compile the source by spawning GCC and windres if needed."""
         if ext == '.rc' or ext == '.res':
             # gcc needs '.res' and '.rc' compiled to object files !!!
             try:
                 self.spawn(["windres", "-i", src, "-o", obj])
-            except DistutilsExecError, msg:
-                raise CompileError, msg
+            except PackagingExecError:
+                raise CompileError(sys.exc_info()[1])
         else: # for other files use the C-compiler
             try:
                 self.spawn(self.compiler_so + cc_args + [src, '-o', obj] +
                            extra_postargs)
-            except DistutilsExecError, msg:
-                raise CompileError, msg
+            except PackagingExecError:
+                raise CompileError(sys.exc_info()[1])
 
     def link(self, target_desc, objects, output_filename, output_dir=None,
              libraries=None, library_dirs=None, runtime_library_dirs=None,
-             export_symbols=None, debug=0, extra_preargs=None,
+             export_symbols=None, debug=False, extra_preargs=None,
              extra_postargs=None, build_temp=None, target_lang=None):
         """Link the objects."""
         # use separate copies, so we can modify the lists
-        extra_preargs = copy.copy(extra_preargs or [])
-        libraries = copy.copy(libraries or [])
-        objects = copy.copy(objects or [])
+        extra_preargs = list(extra_preargs or [])
+        libraries = list(libraries or [])
+        objects = list(objects or [])
 
         # Additional libraries
         libraries.extend(self.dll_libraries)
@@ -195,7 +192,7 @@
             # where are the object files
             temp_dir = os.path.dirname(objects[0])
             # name of dll to give the helper files the same base name
-            (dll_name, dll_extension) = os.path.splitext(
+            dll_name, dll_extension = os.path.splitext(
                 os.path.basename(output_filename))
 
             # generate the filenames for these files
@@ -215,13 +212,13 @@
 
             # dllwrap uses different options than gcc/ld
             if self.linker_dll == "dllwrap":
-                extra_preargs.extend(["--output-lib", lib_file])
+                extra_preargs.extend(("--output-lib", lib_file))
                 # for dllwrap we have to use a special option
-                extra_preargs.extend(["--def", def_file])
+                extra_preargs.extend(("--def", def_file))
             # we use gcc/ld here and can be sure ld is >= 2.9.10
             else:
                 # doesn't work: bfd_close build\...\libfoo.a: Invalid operation
-                #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file])
+                #extra_preargs.extend(("-Wl,--out-implib,%s" % lib_file))
                 # for gcc/ld the def-file is specified as any object files
                 objects.append(def_file)
 
@@ -246,7 +243,8 @@
 
     # -- Miscellaneous methods -----------------------------------------
 
-    def object_filenames(self, source_filenames, strip_dir=0, output_dir=''):
+    def object_filenames(self, source_filenames, strip_dir=False,
+                         output_dir=''):
         """Adds supports for rc and res files."""
         if output_dir is None:
             output_dir = ''
@@ -255,8 +253,7 @@
             # use normcase to make sure '.rc' is really '.rc' and not '.RC'
             base, ext = os.path.splitext(os.path.normcase(src_name))
             if ext not in (self.src_extensions + ['.rc','.res']):
-                raise UnknownFileError, \
-                      "unknown file type '%s' (from '%s')" % (ext, src_name)
+                raise UnknownFileError("unknown file type '%s' (from '%s')" % (ext, src_name))
             if strip_dir:
                 base = os.path.basename (base)
             if ext in ('.res', '.rc'):
@@ -275,7 +272,7 @@
     name = 'mingw32'
     description = 'MinGW32 compiler'
 
-    def __init__(self, verbose=0, dry_run=0, force=0):
+    def __init__(self, verbose=0, dry_run=False, force=False):
 
         CygwinCCompiler.__init__ (self, verbose, dry_run, force)
 
@@ -347,14 +344,12 @@
     # let's see if __GNUC__ is mentioned in python.h
     fn = sysconfig.get_config_h_filename()
     try:
-        config_h = open(fn)
-        try:
+        with open(fn) as config_h:
             if "__GNUC__" in config_h.read():
                 return CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn
             else:
                 return CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn
-        finally:
-            config_h.close()
-    except IOError, exc:
+    except IOError:
+        exc = sys.exc_info()[1]
         return (CONFIG_H_UNCERTAIN,
                 "couldn't read '%s': %s" % (fn, exc.strerror))
diff --git a/distutils2/compiler/extension.py b/distutils2/compiler/extension.py
--- a/distutils2/compiler/extension.py
+++ b/distutils2/compiler/extension.py
@@ -1,10 +1,6 @@
-"""distutils.extension
+"""Class representing C/C++ extension modules."""
 
-Provides the Extension class, used to describe C/C++ extension
-modules in setup scripts."""
-
-
-import warnings
+from distutils2 import logger
 
 # This class is really only used by the "build_ext" command, so it might
 # make sense to put it in distutils.command.build_ext.  However, that
@@ -82,33 +78,22 @@
         build process, but simply not install the failing extension.
     """
 
-    # When adding arguments to this constructor, be sure to update
-    # setup_keywords in core.py.
-    def __init__(self, name, sources,
-                  include_dirs=None,
-                  define_macros=None,
-                  undef_macros=None,
-                  library_dirs=None,
-                  libraries=None,
-                  runtime_library_dirs=None,
-                  extra_objects=None,
-                  extra_compile_args=None,
-                  extra_link_args=None,
-                  export_symbols=None,
-                  swig_opts=None,
-                  depends=None,
-                  language=None,
-                  optional=None,
-                  **kw # To catch unknown keywords
-                 ):
-        if not isinstance(name, str):
+    # **kwargs are allowed so that a warning is emitted instead of an
+    # exception
+    def __init__(self, name, sources, include_dirs=None, define_macros=None,
+                 undef_macros=None, library_dirs=None, libraries=None,
+                 runtime_library_dirs=None, extra_objects=None,
+                 extra_compile_args=None, extra_link_args=None,
+                 export_symbols=None, swig_opts=None, depends=None,
+                 language=None, optional=None, **kw):
+        if not isinstance(name, basestring):
             raise AssertionError("'name' must be a string")
 
         if not isinstance(sources, list):
             raise AssertionError("'sources' must be a list of strings")
 
         for v in sources:
-            if not isinstance(v, str):
+            if not isinstance(v, basestring):
                 raise AssertionError("'sources' must be a list of strings")
 
         self.name = name
@@ -132,5 +117,5 @@
         if len(kw) > 0:
             options = [repr(option) for option in kw]
             options = ', '.join(sorted(options))
-            msg = "Unknown Extension options: %s" % options
-            warnings.warn(msg)
+            logger.warning(
+                'unknown arguments given to Extension: %s', options)
diff --git a/distutils2/compiler/msvc9compiler.py b/distutils2/compiler/msvc9compiler.py
--- a/distutils2/compiler/msvc9compiler.py
+++ b/distutils2/compiler/msvc9compiler.py
@@ -1,10 +1,7 @@
-"""distutils.msvc9compiler
+"""CCompiler implementation for the Microsoft Visual Studio 2008 compiler.
 
-Contains MSVCCompiler, an implementation of the abstract CCompiler class
-for the Microsoft Visual Studio 2008.
-
-The module is compatible with VS 2005 and VS 2008. You can find legacy support
-for older versions of VS in distutils.msvccompiler.
+The MSVCCompiler class is compatible with VS 2005 and VS 2008.  Legacy
+support for older versions of VS are in the msvccompiler module.
 """
 
 # Written by Perry Stoll
@@ -16,24 +13,24 @@
 import sys
 import re
 
-from distutils2.errors import (DistutilsExecError, DistutilsPlatformError,
-                               CompileError, LibError, LinkError)
+from distutils2.errors import (PackagingExecError, PackagingPlatformError,
+                              CompileError, LibError, LinkError)
 from distutils2.compiler.ccompiler import CCompiler
 from distutils2.compiler import gen_lib_options
 from distutils2 import logger
 from distutils2.util import get_platform
 
-import _winreg
+import winreg
 
-RegOpenKeyEx = _winreg.OpenKeyEx
-RegEnumKey = _winreg.EnumKey
-RegEnumValue = _winreg.EnumValue
-RegError = _winreg.error
+RegOpenKeyEx = winreg.OpenKeyEx
+RegEnumKey = winreg.EnumKey
+RegEnumValue = winreg.EnumValue
+RegError = winreg.error
 
-HKEYS = (_winreg.HKEY_USERS,
-         _winreg.HKEY_CURRENT_USER,
-         _winreg.HKEY_LOCAL_MACHINE,
-         _winreg.HKEY_CLASSES_ROOT)
+HKEYS = (winreg.HKEY_USERS,
+         winreg.HKEY_CURRENT_USER,
+         winreg.HKEY_LOCAL_MACHINE,
+         winreg.HKEY_CLASSES_ROOT)
 
 VS_BASE = r"Software\Microsoft\VisualStudio\%0.1f"
 WINSDK_BASE = r"Software\Microsoft\Microsoft SDKs\Windows"
@@ -132,11 +129,11 @@
             else:
                 raise KeyError("sdkinstallrootv2.0")
         except KeyError:
-            raise DistutilsPlatformError(
-            """Python was built with Visual Studio 2008;
-extensions must be built with a compiler than can generate compatible binaries.
-Visual Studio 2008 was not found on this system. If you have Cygwin installed,
-you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""")
+            raise PackagingPlatformError(
+"""Python was built with Visual Studio 2008; extensions must be built with a
+compiler than can generate compatible binaries. Visual Studio 2008 was not
+found on this system. If you have Cygwin installed, you can try compiling
+with MingW32, by passing "-c mingw32" to pysetup.""")
 
         if version >= 9.0:
             self.set_macro("FrameworkVersion", self.vsbase, "clr version")
@@ -153,7 +150,7 @@
                 self.macros["$(FrameworkVersion)"] = d["version"]
 
     def sub(self, s):
-        for k, v in self.macros.iteritems():
+        for k, v in self.macros.items():
             s = s.replace(k, v)
         return s
 
@@ -247,7 +244,7 @@
     result = {}
 
     if vcvarsall is None:
-        raise DistutilsPlatformError("Unable to find vcvarsall.bat")
+        raise PackagingPlatformError("Unable to find vcvarsall.bat")
     logger.debug("calling 'vcvarsall.bat %s' (version=%s)", arch, version)
     popen = subprocess.Popen('"%s" %s & set' % (vcvarsall, arch),
                              stdout=subprocess.PIPE,
@@ -255,7 +252,7 @@
 
     stdout, stderr = popen.communicate()
     if popen.wait() != 0:
-        raise DistutilsPlatformError(stderr.decode("mbcs"))
+        raise PackagingPlatformError(stderr.decode("mbcs"))
 
     stdout = stdout.decode("mbcs")
     for line in stdout.split("\n"):
@@ -278,7 +275,7 @@
 # More globals
 VERSION = get_build_version()
 if VERSION < 8.0:
-    raise DistutilsPlatformError("VC %0.1f is not supported by this module" % VERSION)
+    raise PackagingPlatformError("VC %0.1f is not supported by this module" % VERSION)
 # MACROS = MacroExpander(VERSION)
 
 class MSVCCompiler(CCompiler) :
@@ -312,8 +309,8 @@
     static_lib_format = shared_lib_format = '%s%s'
     exe_extension = '.exe'
 
-    def __init__(self, verbose=0, dry_run=0, force=0):
-        CCompiler.__init__ (self, verbose, dry_run, force)
+    def __init__(self, verbose=0, dry_run=False, force=False):
+        CCompiler.__init__(self, verbose, dry_run, force)
         self.__version = VERSION
         self.__root = r"Software\Microsoft\VisualStudio"
         # self.__macros = MACROS
@@ -331,7 +328,7 @@
         # sanity check for platforms to prevent obscure errors later.
         ok_plats = 'win32', 'win-amd64', 'win-ia64'
         if plat_name not in ok_plats:
-            raise DistutilsPlatformError("--plat-name must be one of %s" %
+            raise PackagingPlatformError("--plat-name must be one of %s" %
                                          (ok_plats,))
 
         if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"):
@@ -359,12 +356,12 @@
             vc_env = query_vcvarsall(VERSION, plat_spec)
 
             # take care to only use strings in the environment.
-            self.__paths = vc_env['path'].encode('mbcs').split(os.pathsep)
-            os.environ['lib'] = vc_env['lib'].encode('mbcs')
-            os.environ['include'] = vc_env['include'].encode('mbcs')
+            self.__paths = vc_env['path'].split(os.pathsep)
+            os.environ['lib'] = vc_env['lib']
+            os.environ['include'] = vc_env['include']
 
             if len(self.__paths) == 0:
-                raise DistutilsPlatformError("Python was built with %s, "
+                raise PackagingPlatformError("Python was built with %s, "
                        "and extensions need to be built with the same "
                        "version of the compiler, but it isn't installed."
                        % self.__product)
@@ -412,37 +409,37 @@
 
     def object_filenames(self,
                          source_filenames,
-                         strip_dir=0,
+                         strip_dir=False,
                          output_dir=''):
         # Copied from ccompiler.py, extended to return .res as 'object'-file
         # for .rc input file
         if output_dir is None: output_dir = ''
         obj_names = []
         for src_name in source_filenames:
-            (base, ext) = os.path.splitext (src_name)
+            base, ext = os.path.splitext(src_name)
             base = os.path.splitdrive(base)[1] # Chop off the drive
             base = base[os.path.isabs(base):]  # If abs, chop off leading /
             if ext not in self.src_extensions:
                 # Better to raise an exception instead of silently continuing
                 # and later complain about sources and targets having
                 # different lengths
-                raise CompileError ("Don't know how to compile %s" % src_name)
+                raise CompileError("Don't know how to compile %s" % src_name)
             if strip_dir:
-                base = os.path.basename (base)
+                base = os.path.basename(base)
             if ext in self._rc_extensions:
-                obj_names.append (os.path.join (output_dir,
-                                                base + self.res_extension))
+                obj_names.append(os.path.join(output_dir,
+                                              base + self.res_extension))
             elif ext in self._mc_extensions:
-                obj_names.append (os.path.join (output_dir,
-                                                base + self.res_extension))
+                obj_names.append(os.path.join(output_dir,
+                                              base + self.res_extension))
             else:
-                obj_names.append (os.path.join (output_dir,
-                                                base + self.obj_extension))
+                obj_names.append(os.path.join(output_dir,
+                                              base + self.obj_extension))
         return obj_names
 
 
     def compile(self, sources,
-                output_dir=None, macros=None, include_dirs=None, debug=0,
+                output_dir=None, macros=None, include_dirs=None, debug=False,
                 extra_preargs=None, extra_postargs=None, depends=None):
 
         if not self.initialized:
@@ -452,7 +449,7 @@
         macros, objects, extra_postargs, pp_opts, build = compile_info
 
         compile_opts = extra_preargs or []
-        compile_opts.append ('/c')
+        compile_opts.append('/c')
         if debug:
             compile_opts.extend(self.compile_options_debug)
         else:
@@ -480,8 +477,8 @@
                 try:
                     self.spawn([self.rc] + pp_opts +
                                [output_opt] + [input_opt])
-                except DistutilsExecError, msg:
-                    raise CompileError(msg)
+                except PackagingExecError:
+                    raise CompileError(sys.exc_info()[1])
                 continue
             elif ext in self._mc_extensions:
                 # Compile .MC to .RC file to .RES file.
@@ -501,14 +498,14 @@
                     # first compile .MC to .RC and .H file
                     self.spawn([self.mc] +
                                ['-h', h_dir, '-r', rc_dir] + [src])
-                    base, _ = os.path.splitext (os.path.basename (src))
-                    rc_file = os.path.join (rc_dir, base + '.rc')
+                    base, _ = os.path.splitext(os.path.basename(src))
+                    rc_file = os.path.join(rc_dir, base + '.rc')
                     # then compile .RC to .RES file
                     self.spawn([self.rc] +
                                ["/fo" + obj] + [rc_file])
 
-                except DistutilsExecError, msg:
-                    raise CompileError(msg)
+                except PackagingExecError:
+                    raise CompileError(sys.exc_info()[1])
                 continue
             else:
                 # how to handle this file?
@@ -520,8 +517,8 @@
                 self.spawn([self.cc] + compile_opts + pp_opts +
                            [input_opt, output_opt] +
                            extra_postargs)
-            except DistutilsExecError, msg:
-                raise CompileError(msg)
+            except PackagingExecError:
+                raise CompileError(sys.exc_info()[1])
 
         return objects
 
@@ -530,12 +527,12 @@
                           objects,
                           output_libname,
                           output_dir=None,
-                          debug=0,
+                          debug=False,
                           target_lang=None):
 
         if not self.initialized:
             self.initialize()
-        (objects, output_dir) = self._fix_object_args(objects, output_dir)
+        objects, output_dir = self._fix_object_args(objects, output_dir)
         output_filename = self.library_filename(output_libname,
                                                 output_dir=output_dir)
 
@@ -545,37 +542,26 @@
                 pass # XXX what goes here?
             try:
                 self.spawn([self.lib] + lib_args)
-            except DistutilsExecError, msg:
-                raise LibError(msg)
+            except PackagingExecError:
+                raise LibError(sys.exc_info()[1])
         else:
             logger.debug("skipping %s (up-to-date)", output_filename)
 
 
-    def link(self,
-             target_desc,
-             objects,
-             output_filename,
-             output_dir=None,
-             libraries=None,
-             library_dirs=None,
-             runtime_library_dirs=None,
-             export_symbols=None,
-             debug=0,
-             extra_preargs=None,
-             extra_postargs=None,
-             build_temp=None,
-             target_lang=None):
-
+    def link(self, target_desc, objects, output_filename, output_dir=None,
+             libraries=None, library_dirs=None, runtime_library_dirs=None,
+             export_symbols=None, debug=False, extra_preargs=None,
+             extra_postargs=None, build_temp=None, target_lang=None):
         if not self.initialized:
             self.initialize()
-        (objects, output_dir) = self._fix_object_args(objects, output_dir)
+        objects, output_dir = self._fix_object_args(objects, output_dir)
         fixed_args = self._fix_lib_args(libraries, library_dirs,
                                         runtime_library_dirs)
-        (libraries, library_dirs, runtime_library_dirs) = fixed_args
+        libraries, library_dirs, runtime_library_dirs = fixed_args
 
         if runtime_library_dirs:
-            self.warn ("I don't know what to do with 'runtime_library_dirs': "
-                       + str (runtime_library_dirs))
+            self.warn("don't know what to do with 'runtime_library_dirs': "
+                      + str(runtime_library_dirs))
 
         lib_opts = gen_lib_options(self,
                                    library_dirs, runtime_library_dirs,
@@ -609,12 +595,12 @@
             # builds, they can go into the same directory.
             build_temp = os.path.dirname(objects[0])
             if export_symbols is not None:
-                (dll_name, dll_ext) = os.path.splitext(
+                dll_name, dll_ext = os.path.splitext(
                     os.path.basename(output_filename))
                 implib_file = os.path.join(
                     build_temp,
                     self.library_filename(dll_name))
-                ld_args.append ('/IMPLIB:' + implib_file)
+                ld_args.append('/IMPLIB:' + implib_file)
 
             # Embedded manifests are recommended - see MSDN article titled
             # "How to: Embed a Manifest Inside a C/C++ Application"
@@ -634,8 +620,8 @@
             self.mkpath(os.path.dirname(output_filename))
             try:
                 self.spawn([self.linker] + ld_args)
-            except DistutilsExecError, msg:
-                raise LinkError(msg)
+            except PackagingExecError:
+                raise LinkError(sys.exc_info()[1])
 
             # embed the manifest
             # XXX - this is somewhat fragile - if mt.exe fails, distutils
@@ -651,8 +637,8 @@
             try:
                 self.spawn(['mt.exe', '-nologo', '-manifest',
                             temp_manifest, out_arg])
-            except DistutilsExecError, msg:
-                raise LinkError(msg)
+            except PackagingExecError:
+                raise LinkError(sys.exc_info()[1])
         else:
             logger.debug("skipping %s (up-to-date)", output_filename)
 
@@ -664,11 +650,8 @@
             # runtimes are not in WinSxS folder, but in Python's own
             # folder), the runtimes do not need to be in every folder
             # with .pyd's.
-            manifest_f = open(manifest_file)
-            try:
+            with open(manifest_file) as manifest_f:
                 manifest_buf = manifest_f.read()
-            finally:
-                manifest_f.close()
             pattern = re.compile(
                 r"""<assemblyIdentity.*?name=("|')Microsoft\."""\
                 r"""VC\d{2}\.CRT("|').*?(/>|</assemblyIdentity>)""",
@@ -676,11 +659,8 @@
             manifest_buf = re.sub(pattern, "", manifest_buf)
             pattern = "<dependentAssembly>\s*</dependentAssembly>"
             manifest_buf = re.sub(pattern, "", manifest_buf)
-            manifest_f = open(manifest_file, 'w')
-            try:
+            with open(manifest_file, 'w') as manifest_f:
                 manifest_f.write(manifest_buf)
-            finally:
-                manifest_f.close()
         except IOError:
             pass
 
@@ -692,14 +672,14 @@
         return "/LIBPATH:" + dir
 
     def runtime_library_dir_option(self, dir):
-        raise DistutilsPlatformError(
+        raise PackagingPlatformError(
               "don't know how to set runtime library search path for MSVC++")
 
     def library_option(self, lib):
         return self.library_filename(lib)
 
 
-    def find_library_file(self, dirs, lib, debug=0):
+    def find_library_file(self, dirs, lib, debug=False):
         # Prefer a debugging library if found (and requested), but deal
         # with it if we don't have one.
         if debug:
@@ -708,7 +688,7 @@
             try_names = [lib]
         for dir in dirs:
             for name in try_names:
-                libfile = os.path.join(dir, self.library_filename (name))
+                libfile = os.path.join(dir, self.library_filename(name))
                 if os.path.exists(libfile):
                     return libfile
         else:
diff --git a/distutils2/compiler/msvccompiler.py b/distutils2/compiler/msvccompiler.py
--- a/distutils2/compiler/msvccompiler.py
+++ b/distutils2/compiler/msvccompiler.py
@@ -1,7 +1,6 @@
-"""distutils.msvccompiler
+"""CCompiler implementation for old Microsoft Visual Studio compilers.
 
-Contains MSVCCompiler, an implementation of the abstract CCompiler class
-for the Microsoft Visual Studio.
+For a compiler compatible with VS 2005 and 2008, use msvc9compiler.
 """
 
 # Written by Perry Stoll
@@ -11,31 +10,30 @@
 
 import sys
 import os
-import string
 
-from distutils2.errors import (DistutilsExecError, DistutilsPlatformError,
-                               CompileError, LibError, LinkError)
+from distutils2.errors import (PackagingExecError, PackagingPlatformError,
+                              CompileError, LibError, LinkError)
 from distutils2.compiler.ccompiler import CCompiler
 from distutils2.compiler import gen_lib_options
 from distutils2 import logger
 
-_can_read_reg = 0
+_can_read_reg = False
 try:
-    import _winreg
+    import winreg
 
-    _can_read_reg = 1
-    hkey_mod = _winreg
+    _can_read_reg = True
+    hkey_mod = winreg
 
-    RegOpenKeyEx = _winreg.OpenKeyEx
-    RegEnumKey = _winreg.EnumKey
-    RegEnumValue = _winreg.EnumValue
-    RegError = _winreg.error
+    RegOpenKeyEx = winreg.OpenKeyEx
+    RegEnumKey = winreg.EnumKey
+    RegEnumValue = winreg.EnumValue
+    RegError = winreg.error
 
 except ImportError:
     try:
         import win32api
         import win32con
-        _can_read_reg = 1
+        _can_read_reg = True
         hkey_mod = win32con
 
         RegOpenKeyEx = win32api.RegOpenKeyEx
@@ -55,6 +53,7 @@
              hkey_mod.HKEY_LOCAL_MACHINE,
              hkey_mod.HKEY_CLASSES_ROOT)
 
+
 def read_keys(base, key):
     """Return list of registry keys."""
 
@@ -64,7 +63,7 @@
         return None
     L = []
     i = 0
-    while 1:
+    while True:
         try:
             k = RegEnumKey(handle, i)
         except RegError:
@@ -73,6 +72,7 @@
         i = i + 1
     return L
 
+
 def read_values(base, key):
     """Return dict of registry keys and values.
 
@@ -84,7 +84,7 @@
         return None
     d = {}
     i = 0
-    while 1:
+    while True:
         try:
             name, value, type = RegEnumValue(handle, i)
         except RegError:
@@ -94,6 +94,7 @@
         i = i + 1
     return d
 
+
 def convert_mbcs(s):
     enc = getattr(s, "encode", None)
     if enc is not None:
@@ -103,6 +104,7 @@
             pass
     return s
 
+
 class MacroExpander(object):
 
     def __init__(self, version):
@@ -128,11 +130,11 @@
             else:
                 self.set_macro("FrameworkSDKDir", net, "sdkinstallroot")
         except KeyError:
-            raise DistutilsPlatformError, \
-                  ("""Python was built with Visual Studio 2003;
-extensions must be built with a compiler than can generate compatible binaries.
-Visual Studio 2003 was not found on this system. If you have Cygwin installed,
-you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""")
+            raise PackagingPlatformError(
+"""Python was built with Visual Studio 2003; extensions must be built with
+a compiler than can generate compatible binaries. Visual Studio 2003 was
+not found on this system. If you have Cygwin installed, you can try
+compiling with MingW32, by passing "-c mingw32" to pysetup.""")
 
         p = r"Software\Microsoft\NET Framework Setup\Product"
         for base in HKEYS:
@@ -145,10 +147,11 @@
             self.macros["$(FrameworkVersion)"] = d["version"]
 
     def sub(self, s):
-        for k, v in self.macros.iteritems():
-            s = string.replace(s, k, v)
+        for k, v in self.macros.items():
+            s = s.replace(k, v)
         return s
 
+
 def get_build_version():
     """Return the version of MSVC that was used to build Python.
 
@@ -157,7 +160,7 @@
     """
 
     prefix = "MSC v."
-    i = string.find(sys.version, prefix)
+    i = sys.version.find(prefix)
     if i == -1:
         return 6
     i = i + len(prefix)
@@ -172,6 +175,7 @@
     # else we don't know what version of the compiler this is
     return None
 
+
 def get_build_architecture():
     """Return the processor architecture.
 
@@ -179,12 +183,13 @@
     """
 
     prefix = " bit ("
-    i = string.find(sys.version, prefix)
+    i = sys.version.find(prefix)
     if i == -1:
         return "Intel"
-    j = string.find(sys.version, ")", i)
+    j = sys.version.find(")", i)
     return sys.version[i+len(prefix):j]
 
+
 def normalize_and_reduce_paths(paths):
     """Return a list of normalized paths with duplicates removed.
 
@@ -200,7 +205,7 @@
     return reduced_paths
 
 
-class MSVCCompiler (CCompiler) :
+class MSVCCompiler(CCompiler):
     """Concrete class that implements an interface to Microsoft Visual C++,
        as defined by the CCompiler abstract class."""
 
@@ -231,8 +236,8 @@
     static_lib_format = shared_lib_format = '%s%s'
     exe_extension = '.exe'
 
-    def __init__ (self, verbose=0, dry_run=0, force=0):
-        CCompiler.__init__ (self, verbose, dry_run, force)
+    def __init__(self, verbose=0, dry_run=False, force=False):
+        CCompiler.__init__(self, verbose, dry_run, force)
         self.__version = get_build_version()
         self.__arch = get_build_architecture()
         if self.__arch == "Intel":
@@ -251,7 +256,8 @@
 
     def initialize(self):
         self.__paths = []
-        if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"):
+        if ("DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and
+            self.find_exe("cl.exe")):
             # Assume that the SDK set up everything alright; don't try to be
             # smarter
             self.cc = "cl.exe"
@@ -262,11 +268,11 @@
         else:
             self.__paths = self.get_msvc_paths("path")
 
-            if len (self.__paths) == 0:
-                raise DistutilsPlatformError, \
-                      ("Python was built with %s, "
-                       "and extensions need to be built with the same "
-                       "version of the compiler, but it isn't installed." % self.__product)
+            if len(self.__paths) == 0:
+                raise PackagingPlatformError("Python was built with %s "
+                    "and extensions need to be built with the same "
+                    "version of the compiler, but it isn't installed." %
+                    self.__product)
 
             self.cc = self.find_exe("cl.exe")
             self.linker = self.find_exe("link.exe")
@@ -278,23 +284,23 @@
 
         # extend the MSVC path with the current path
         try:
-            for p in string.split(os.environ['path'], ';'):
+            for p in os.environ['path'].split(';'):
                 self.__paths.append(p)
         except KeyError:
             pass
         self.__paths = normalize_and_reduce_paths(self.__paths)
-        os.environ['path'] = string.join(self.__paths, ';')
+        os.environ['path'] = ';'.join(self.__paths)
 
         self.preprocess_options = None
         if self.__arch == "Intel":
-            self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
-                                     '/DNDEBUG']
+            self.compile_options = ['/nologo', '/Ox', '/MD', '/W3', '/GX',
+                                    '/DNDEBUG']
             self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
                                           '/Z7', '/D_DEBUG']
         else:
             # Win64
-            self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GS-' ,
-                                     '/DNDEBUG']
+            self.compile_options = ['/nologo', '/Ox', '/MD', '/W3', '/GS-',
+                                    '/DNDEBUG']
             self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-',
                                           '/Z7', '/D_DEBUG']
 
@@ -313,50 +319,46 @@
 
     # -- Worker methods ------------------------------------------------
 
-    def object_filenames (self,
-                          source_filenames,
-                          strip_dir=0,
-                          output_dir=''):
+    def object_filenames(self, source_filenames, strip_dir=False, output_dir=''):
         # Copied from ccompiler.py, extended to return .res as 'object'-file
         # for .rc input file
-        if output_dir is None: output_dir = ''
+        if output_dir is None:
+            output_dir = ''
         obj_names = []
         for src_name in source_filenames:
-            (base, ext) = os.path.splitext (src_name)
-            base = os.path.splitdrive(base)[1] # Chop off the drive
+            base, ext = os.path.splitext(src_name)
+            base = os.path.splitdrive(base)[1]  # Chop off the drive
             base = base[os.path.isabs(base):]  # If abs, chop off leading /
             if ext not in self.src_extensions:
                 # Better to raise an exception instead of silently continuing
                 # and later complain about sources and targets having
                 # different lengths
-                raise CompileError ("Don't know how to compile %s" % src_name)
+                raise CompileError("Don't know how to compile %s" % src_name)
             if strip_dir:
-                base = os.path.basename (base)
+                base = os.path.basename(base)
             if ext in self._rc_extensions:
-                obj_names.append (os.path.join (output_dir,
-                                                base + self.res_extension))
+                obj_names.append(os.path.join(output_dir,
+                                              base + self.res_extension))
             elif ext in self._mc_extensions:
-                obj_names.append (os.path.join (output_dir,
-                                                base + self.res_extension))
+                obj_names.append(os.path.join(output_dir,
+                                              base + self.res_extension))
             else:
-                obj_names.append (os.path.join (output_dir,
-                                                base + self.obj_extension))
+                obj_names.append(os.path.join(output_dir,
+                                              base + self.obj_extension))
         return obj_names
 
-    # object_filenames ()
-
-
     def compile(self, sources,
-                output_dir=None, macros=None, include_dirs=None, debug=0,
+                output_dir=None, macros=None, include_dirs=None, debug=False,
                 extra_preargs=None, extra_postargs=None, depends=None):
 
-        if not self.initialized: self.initialize()
+        if not self.initialized:
+            self.initialize()
         macros, objects, extra_postargs, pp_opts, build = \
                 self._setup_compile(output_dir, macros, include_dirs, sources,
                                     depends, extra_postargs)
 
         compile_opts = extra_preargs or []
-        compile_opts.append ('/c')
+        compile_opts.append('/c')
         if debug:
             compile_opts.extend(self.compile_options_debug)
         else:
@@ -382,10 +384,10 @@
                 input_opt = src
                 output_opt = "/fo" + obj
                 try:
-                    self.spawn ([self.rc] + pp_opts +
-                                [output_opt] + [input_opt])
-                except DistutilsExecError, msg:
-                    raise CompileError, msg
+                    self.spawn([self.rc] + pp_opts +
+                               [output_opt] + [input_opt])
+                except PackagingExecError:
+                    raise CompileError(sys.exc_info()[1])
                 continue
             elif ext in self._mc_extensions:
 
@@ -401,97 +403,78 @@
                 # the build directory for the RC file and message
                 # resources. This works at least for win32all.
 
-                h_dir = os.path.dirname (src)
-                rc_dir = os.path.dirname (obj)
+                h_dir = os.path.dirname(src)
+                rc_dir = os.path.dirname(obj)
                 try:
                     # first compile .MC to .RC and .H file
-                    self.spawn ([self.mc] +
-                                ['-h', h_dir, '-r', rc_dir] + [src])
-                    base, _ = os.path.splitext (os.path.basename (src))
-                    rc_file = os.path.join (rc_dir, base + '.rc')
+                    self.spawn([self.mc] +
+                               ['-h', h_dir, '-r', rc_dir] + [src])
+                    base, _ = os.path.splitext(os.path.basename(src))
+                    rc_file = os.path.join(rc_dir, base + '.rc')
                     # then compile .RC to .RES file
-                    self.spawn ([self.rc] +
+                    self.spawn([self.rc] +
                                 ["/fo" + obj] + [rc_file])
 
-                except DistutilsExecError, msg:
-                    raise CompileError, msg
+                except PackagingExecError:
+                    raise CompileError(sys.exc_info()[1])
                 continue
             else:
                 # how to handle this file?
-                raise CompileError (
-                    "Don't know how to compile %s to %s" % \
+                raise CompileError(
+                    "Don't know how to compile %s to %s" %
                     (src, obj))
 
             output_opt = "/Fo" + obj
             try:
-                self.spawn ([self.cc] + compile_opts + pp_opts +
-                            [input_opt, output_opt] +
-                            extra_postargs)
-            except DistutilsExecError, msg:
-                raise CompileError, msg
+                self.spawn([self.cc] + compile_opts + pp_opts +
+                           [input_opt, output_opt] +
+                           extra_postargs)
+            except PackagingExecError:
+                raise CompileError(sys.exc_info()[1])
 
         return objects
 
-    # compile ()
+    def create_static_lib(self, objects, output_libname, output_dir=None,
+                          debug=False, target_lang=None):
+        if not self.initialized:
+            self.initialize()
+        objects, output_dir = self._fix_object_args(objects, output_dir)
+        output_filename = \
+            self.library_filename(output_libname, output_dir=output_dir)
 
-
-    def create_static_lib (self,
-                           objects,
-                           output_libname,
-                           output_dir=None,
-                           debug=0,
-                           target_lang=None):
-
-        if not self.initialized: self.initialize()
-        (objects, output_dir) = self._fix_object_args (objects, output_dir)
-        output_filename = \
-            self.library_filename (output_libname, output_dir=output_dir)
-
-        if self._need_link (objects, output_filename):
+        if self._need_link(objects, output_filename):
             lib_args = objects + ['/OUT:' + output_filename]
             if debug:
                 pass                    # XXX what goes here?
             try:
-                self.spawn ([self.lib] + lib_args)
-            except DistutilsExecError, msg:
-                raise LibError, msg
+                self.spawn([self.lib] + lib_args)
+            except PackagingExecError:
+                raise LibError(sys.exc_info()[1])
 
         else:
             logger.debug("skipping %s (up-to-date)", output_filename)
 
-    # create_static_lib ()
+    def link(self, target_desc, objects, output_filename, output_dir=None,
+             libraries=None, library_dirs=None, runtime_library_dirs=None,
+             export_symbols=None, debug=False, extra_preargs=None,
+             extra_postargs=None, build_temp=None, target_lang=None):
 
-    def link (self,
-              target_desc,
-              objects,
-              output_filename,
-              output_dir=None,
-              libraries=None,
-              library_dirs=None,
-              runtime_library_dirs=None,
-              export_symbols=None,
-              debug=0,
-              extra_preargs=None,
-              extra_postargs=None,
-              build_temp=None,
-              target_lang=None):
-
-        if not self.initialized: self.initialize()
-        (objects, output_dir) = self._fix_object_args (objects, output_dir)
-        (libraries, library_dirs, runtime_library_dirs) = \
-            self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
+        if not self.initialized:
+            self.initialize()
+        objects, output_dir = self._fix_object_args(objects, output_dir)
+        libraries, library_dirs, runtime_library_dirs = \
+            self._fix_lib_args(libraries, library_dirs, runtime_library_dirs)
 
         if runtime_library_dirs:
-            self.warn ("I don't know what to do with 'runtime_library_dirs': "
-                       + str (runtime_library_dirs))
+            self.warn("don't know what to do with 'runtime_library_dirs': %s"
+                      % (runtime_library_dirs,))
 
-        lib_opts = gen_lib_options (self,
-                                    library_dirs, runtime_library_dirs,
-                                    libraries)
+        lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
+                                   libraries)
         if output_dir is not None:
-            output_filename = os.path.join (output_dir, output_filename)
+            output_filename = os.path.join(output_dir, output_filename)
 
-        if self._need_link (objects, output_filename):
+        if self._need_link(objects, output_filename):
 
             if target_desc == CCompiler.EXECUTABLE:
                 if debug:
@@ -517,46 +500,41 @@
             # directory. Since they have different names for debug and release
             # builds, they can go into the same directory.
             if export_symbols is not None:
-                (dll_name, dll_ext) = os.path.splitext(
+                dll_name, dll_ext = os.path.splitext(
                     os.path.basename(output_filename))
                 implib_file = os.path.join(
                     os.path.dirname(objects[0]),
                     self.library_filename(dll_name))
-                ld_args.append ('/IMPLIB:' + implib_file)
+                ld_args.append('/IMPLIB:' + implib_file)
 
             if extra_preargs:
                 ld_args[:0] = extra_preargs
             if extra_postargs:
                 ld_args.extend(extra_postargs)
 
-            self.mkpath (os.path.dirname (output_filename))
+            self.mkpath(os.path.dirname(output_filename))
             try:
-                self.spawn ([self.linker] + ld_args)
-            except DistutilsExecError, msg:
-                raise LinkError, msg
+                self.spawn([self.linker] + ld_args)
+            except PackagingExecError:
+                raise LinkError(sys.exc_info()[1])
 
         else:
             logger.debug("skipping %s (up-to-date)", output_filename)
 
-    # link ()
-
-
     # -- Miscellaneous methods -----------------------------------------
     # These are all used by the 'gen_lib_options() function, in
     # ccompiler.py.
 
-    def library_dir_option (self, dir):
+    def library_dir_option(self, dir):
         return "/LIBPATH:" + dir
 
-    def runtime_library_dir_option (self, dir):
-        raise DistutilsPlatformError, \
-              "don't know how to set runtime library search path for MSVC++"
+    def runtime_library_dir_option(self, dir):
+        raise PackagingPlatformError("don't know how to set runtime library search path for MSVC++")
 
-    def library_option (self, lib):
-        return self.library_filename (lib)
+    def library_option(self, lib):
+        return self.library_filename(lib)
 
-
-    def find_library_file (self, dirs, lib, debug=0):
+    def find_library_file(self, dirs, lib, debug=False):
         # Prefer a debugging library if found (and requested), but deal
         # with it if we don't have one.
         if debug:
@@ -565,15 +543,13 @@
             try_names = [lib]
         for dir in dirs:
             for name in try_names:
-                libfile = os.path.join(dir, self.library_filename (name))
+                libfile = os.path.join(dir, self.library_filename(name))
                 if os.path.exists(libfile):
                     return libfile
         else:
             # Oops, didn't find it in *any* of 'dirs'
             return None
 
-    # find_library_file ()
-
     # Helper methods for using the MSVC registry settings
 
     def find_exe(self, exe):
@@ -592,8 +568,8 @@
                 return fn
 
         # didn't find it; try existing path
-        for p in string.split(os.environ['Path'],';'):
-            fn = os.path.join(os.path.abspath(p),exe)
+        for p in os.environ['Path'].split(';'):
+            fn = os.path.join(os.path.abspath(p), exe)
             if os.path.isfile(fn):
                 return fn
 
@@ -621,9 +597,9 @@
             d = read_values(base, key)
             if d:
                 if self.__version >= 7:
-                    return string.split(self.__macros.sub(d[path]), ";")
+                    return self.__macros.sub(d[path]).split(";")
                 else:
-                    return string.split(d[path], ";")
+                    return d[path].split(";")
         # MSVC 6 seems to create the registry entries we need only when
         # the GUI is run.
         if self.__version == 6:
@@ -648,7 +624,7 @@
         else:
             p = self.get_msvc_paths(name)
         if p:
-            os.environ[name] = string.join(p, ';')
+            os.environ[name] = ';'.join(p)
 
 
 if get_build_version() >= 8.0:
diff --git a/distutils2/compiler/unixccompiler.py b/distutils2/compiler/unixccompiler.py
--- a/distutils2/compiler/unixccompiler.py
+++ b/distutils2/compiler/unixccompiler.py
@@ -1,7 +1,7 @@
-"""distutils.unixccompiler
+"""CCompiler implementation for Unix compilers.
 
-Contains the UnixCCompiler class, a subclass of CCompiler that handles
-the "typical" Unix-style command-line C compiler:
+This module contains the UnixCCompiler class, a subclass of CCompiler
+that handles the "typical" Unix-style command-line C compiler:
   * macros defined with -Dname[=value]
   * macros undefined with -Uname
   * include search directories specified with -Idir
@@ -13,16 +13,15 @@
   * link shared library handled by 'cc -shared'
 """
 
-
 import os, sys
 
 from distutils2.util import newer
 from distutils2.compiler.ccompiler import CCompiler
 from distutils2.compiler import gen_preprocess_options, gen_lib_options
-from distutils2.errors import (DistutilsExecError, CompileError,
+from distutils2.errors import (PackagingExecError, CompileError,
                                LibError, LinkError)
 from distutils2 import logger
-from distutils2._backport import sysconfig
+import sysconfig
 
 
 # XXX Things not currently handled:
@@ -34,7 +33,7 @@
 #     we need some way for outsiders to feed preprocessor/compiler/linker
 #     flags in to us -- eg. a sysadmin might want to mandate certain flags
 #     via a site config file, or a user might want to set something for
-#     compiling this module distribution only via the setup.py command
+#     compiling this module distribution only via the pysetup command
 #     line, whatever.  As long as these options come from something on the
 #     current system, they can be as system-dependent as they like, and we
 #     should just happily stuff them into the preprocessor/compiler/linker
@@ -49,7 +48,7 @@
     build, without a way to remove an architecture. Furthermore GCC will
     barf if multiple '-isysroot' arguments are present.
     """
-    stripArch = stripSysroot = 0
+    stripArch = stripSysroot = False
 
     compiler_so = list(compiler_so)
     kernel_version = os.uname()[2] # 8.4.3
@@ -64,7 +63,7 @@
         stripSysroot = '-isysroot' in cc_args
 
     if stripArch or 'ARCHFLAGS' in os.environ:
-        while 1:
+        while True:
             try:
                 index = compiler_so.index('-arch')
                 # Strip this argument and the next one:
@@ -150,7 +149,7 @@
         pp_opts = gen_preprocess_options(macros, include_dirs)
         pp_args = self.preprocessor + pp_opts
         if output_file:
-            pp_args.extend(['-o', output_file])
+            pp_args.extend(('-o', output_file))
         if extra_preargs:
             pp_args[:0] = extra_preargs
         if extra_postargs:
@@ -166,8 +165,8 @@
                 self.mkpath(os.path.dirname(output_file))
             try:
                 self.spawn(pp_args)
-            except DistutilsExecError, msg:
-                raise CompileError, msg
+            except PackagingExecError:
+                raise CompileError(sys.exc_info()[1])
 
     def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
         compiler_so = self.compiler_so
@@ -176,11 +175,11 @@
         try:
             self.spawn(compiler_so + cc_args + [src, '-o', obj] +
                        extra_postargs)
-        except DistutilsExecError, msg:
-            raise CompileError, msg
+        except PackagingExecError:
+            raise CompileError(sys.exc_info()[1])
 
     def create_static_lib(self, objects, output_libname,
-                          output_dir=None, debug=0, target_lang=None):
+                          output_dir=None, debug=False, target_lang=None):
         objects, output_dir = self._fix_object_args(objects, output_dir)
 
         output_filename = \
@@ -200,15 +199,15 @@
             if self.ranlib:
                 try:
                     self.spawn(self.ranlib + [output_filename])
-                except DistutilsExecError, msg:
-                    raise LibError, msg
+                except PackagingExecError:
+                    raise LibError(sys.exc_info()[1])
         else:
             logger.debug("skipping %s (up-to-date)", output_filename)
 
     def link(self, target_desc, objects,
              output_filename, output_dir=None, libraries=None,
              library_dirs=None, runtime_library_dirs=None,
-             export_symbols=None, debug=0, extra_preargs=None,
+             export_symbols=None, debug=False, extra_preargs=None,
              extra_postargs=None, build_temp=None, target_lang=None):
         objects, output_dir = self._fix_object_args(objects, output_dir)
         libraries, library_dirs, runtime_library_dirs = \
@@ -216,8 +215,8 @@
 
         lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
                                    libraries)
-        if not isinstance(output_dir, (str, type(None))):
-            raise TypeError, "'output_dir' must be a string or None"
+        if type(output_dir) not in (str, type(None)):
+            raise TypeError("'output_dir' must be a string or None")
         if output_dir is not None:
             output_filename = os.path.join(output_dir, output_filename)
 
@@ -254,8 +253,8 @@
                     linker = _darwin_compiler_fixup(linker, ld_args)
 
                 self.spawn(linker + ld_args)
-            except DistutilsExecError, msg:
-                raise LinkError, msg
+            except PackagingExecError:
+                raise LinkError(sys.exc_info()[1])
         else:
             logger.debug("skipping %s (up-to-date)", output_filename)
 
@@ -316,7 +315,7 @@
     def library_option(self, lib):
         return "-l" + lib
 
-    def find_library_file(self, dirs, lib, debug=0):
+    def find_library_file(self, dirs, lib, debug=False):
         shared_f = self.library_filename(lib, lib_type='shared')
         dylib_f = self.library_filename(lib, lib_type='dylib')
         static_f = self.library_filename(lib, lib_type='static')
diff --git a/distutils2/config.py b/distutils2/config.py
--- a/distutils2/config.py
+++ b/distutils2/config.py
@@ -1,21 +1,19 @@
-""" distutil2.config
+"""Utilities to find and read config files used by distutils2."""
 
-    Know how to read all config files Distutils2 uses.
-"""
-import os.path
+import codecs
 import os
 import sys
 import logging
+
+from shlex import split
 from ConfigParser import RawConfigParser
-from shlex import split
-
 from distutils2 import logger
-from distutils2.errors import DistutilsOptionError
+from distutils2.errors import PackagingOptionError
 from distutils2.compiler.extension import Extension
-from distutils2.util import check_environ, resolve_name, strtobool
+from distutils2.util import (check_environ, iglob, resolve_name, strtobool,
+                            split_multiline)
 from distutils2.compiler import set_compiler
 from distutils2.command import set_command
-from distutils2.resources import resources_dests
 from distutils2.markers import interpret
 
 
@@ -25,29 +23,54 @@
     if not vals_str:
         return
     fields = []
-    for field in vals_str.split(os.linesep):
+    # the line separator is \n for setup.cfg files
+    for field in vals_str.split('\n'):
         tmp_vals = field.split('--')
-        if (len(tmp_vals) == 2) and (not interpret(tmp_vals[1])):
+        if len(tmp_vals) == 2 and not interpret(tmp_vals[1]):
             continue
         fields.append(tmp_vals[0])
-    # Get bash options like `gcc -print-file-name=libgcc.a`
+    # Get bash options like `gcc -print-file-name=libgcc.a` XXX bash options?
     vals = split(' '.join(fields))
     if vals:
         return vals
 
 
+def _rel_path(base, path):
+    # normalizes and returns a lstripped-/-separated path
+    base = base.replace(os.path.sep, '/')
+    path = path.replace(os.path.sep, '/')
+    assert path.startswith(base)
+    return path[len(base):].lstrip('/')
+
+
+def get_resources_dests(resources_root, rules):
+    """Find destinations for resources files"""
+    destinations = {}
+    for base, suffix, dest in rules:
+        prefix = os.path.join(resources_root, base)
+        for abs_base in iglob(prefix):
+            abs_glob = os.path.join(abs_base, suffix)
+            for abs_path in iglob(abs_glob):
+                resource_file = _rel_path(resources_root, abs_path)
+                if dest is None:  # remove the entry if it was here
+                    destinations.pop(resource_file, None)
+                else:
+                    rel_path = _rel_path(abs_base, abs_path)
+                    rel_dest = dest.replace(os.path.sep, '/').rstrip('/')
+                    destinations[resource_file] = rel_dest + '/' + rel_path
+    return destinations
+
+
 class Config(object):
-    """Reads configuration files and work with the Distribution instance
-    """
+    """Class used to work with configuration files"""
     def __init__(self, dist):
         self.dist = dist
-        self.setup_hook = None
+        self.setup_hooks = []
 
-    def run_hook(self, config):
-        if self.setup_hook is None:
-            return
-        # the hook gets only the config
-        self.setup_hook(config)
+    def run_hooks(self, config):
+        """Run setup hooks in the order defined in the spec."""
+        for hook in self.setup_hooks:
+            hook(config)
 
     def find_config_files(self):
         """Find as many configuration files as should be processed for this
@@ -55,9 +78,9 @@
         should be parsed.  The filenames returned are guaranteed to exist
         (modulo nasty race conditions).
 
-        There are three possible config files: distutils.cfg in the
-        Distutils installation directory (ie. where the top-level
-        Distutils __inst__.py file lives), a file in the user's home
+        There are three possible config files: distutils2.cfg in the
+        Packaging installation directory (ie. where the top-level
+        Packaging __inst__.py file lives), a file in the user's home
         directory named .pydistutils.cfg on Unix and pydistutils.cfg
         on Windows/Mac; and setup.cfg in the current directory.
 
@@ -67,11 +90,11 @@
         files = []
         check_environ()
 
-        # Where to look for the system-wide Distutils config file
+        # Where to look for the system-wide Packaging config file
         sys_dir = os.path.dirname(sys.modules['distutils2'].__file__)
 
         # Look for the system config file
-        sys_file = os.path.join(sys_dir, "distutils.cfg")
+        sys_file = os.path.join(sys_dir, "distutils2.cfg")
         if os.path.isfile(sys_file):
             files.append(sys_file)
 
@@ -101,33 +124,41 @@
         # XXX
         return value
 
-    def _multiline(self, value):
-        value = [v for v in
-                [v.strip() for v in value.split('\n')]
-                if v != '']
-        return value
-
     def _read_setup_cfg(self, parser, cfg_filename):
         cfg_directory = os.path.dirname(os.path.abspath(cfg_filename))
         content = {}
         for section in parser.sections():
             content[section] = dict(parser.items(section))
 
-        # global:setup_hook is called *first*
+        # global setup hooks are called first
         if 'global' in content:
-            if 'setup_hook' in content['global']:
-                setup_hook = content['global']['setup_hook']
-                self.setup_hook = resolve_name(setup_hook)
-                self.run_hook(content)
+            if 'setup_hooks' in content['global']:
+                setup_hooks = split_multiline(content['global']['setup_hooks'])
+
+                # add project directory to sys.path, to allow hooks to be
+                # distributed with the project
+                sys.path.insert(0, cfg_directory)
+                try:
+                    for line in setup_hooks:
+                        try:
+                            hook = resolve_name(line)
+                        except ImportError:
+                            logger.warning('cannot find setup hook: %s',
+                                           sys.exc_info()[1].args[0])
+                        else:
+                            self.setup_hooks.append(hook)
+                    self.run_hooks(content)
+                finally:
+                    sys.path.pop(0)
 
         metadata = self.dist.metadata
 
         # setting the metadata values
         if 'metadata' in content:
-            for key, value in content['metadata'].iteritems():
+            for key, value in content['metadata'].items():
                 key = key.replace('_', '-')
                 if metadata.is_multi_field(key):
-                    value = self._multiline(value)
+                    value = split_multiline(value)
 
                 if key == 'project-url':
                     value = [(label.strip(), url.strip())
@@ -138,71 +169,74 @@
                     if 'description' in content['metadata']:
                         msg = ("description and description-file' are "
                                "mutually exclusive")
-                        raise DistutilsOptionError(msg)
+                        raise PackagingOptionError(msg)
 
-                    if isinstance(value, list):
-                        filenames = value
-                    else:
-                        filenames = value.split()
+                    filenames = value.split()
 
-                    # concatenate each files
-                    value = ''
+                    # concatenate all files
+                    value = []
                     for filename in filenames:
                         # will raise if file not found
-                        description_file = open(filename)
-                        try:
-                            value += description_file.read().strip() + '\n'
-                        finally:
-                            description_file.close()
+                        with open(filename) as description_file:
+                            value.append(description_file.read().strip())
                         # add filename as a required file
                         if filename not in metadata.requires_files:
                             metadata.requires_files.append(filename)
-                    value = value.strip()
+                    value = '\n'.join(value).strip()
                     key = 'description'
 
                 if metadata.is_metadata_field(key):
                     metadata[key] = self._convert_metadata(key, value)
 
+        if 'files' in content:
+            files = content['files']
+            self.dist.package_dir = files.pop('packages_root', None)
 
-        if 'files' in content:
-            def _convert(key, value):
-                if key not in ('packages_root',):
-                    value = self._multiline(value)
-                return value
+            files = dict((key, split_multiline(value)) for key, value in
+                         files.items())
 
-            files = dict([(key, _convert(key, value))
-                          for key, value in content['files'].iteritems()])
             self.dist.packages = []
-            self.dist.package_dir = files.get('packages_root')
 
             packages = files.get('packages', [])
-            if isinstance(packages, str):
+            if isinstance(packages, basestring):
                 packages = [packages]
 
             for package in packages:
+                if ':' in package:
+                    dir_, package = package.split(':')
+                    self.dist.package_dir[package] = dir_
                 self.dist.packages.append(package)
 
             self.dist.py_modules = files.get('modules', [])
-            if isinstance(self.dist.py_modules, str):
+            if isinstance(self.dist.py_modules, basestring):
                 self.dist.py_modules = [self.dist.py_modules]
             self.dist.scripts = files.get('scripts', [])
-            if isinstance(self.dist.scripts, str):
+            if isinstance(self.dist.scripts, basestring):
                 self.dist.scripts = [self.dist.scripts]
 
             self.dist.package_data = {}
             for data in files.get('package_data', []):
                 data = data.split('=')
                 if len(data) != 2:
-                    continue # XXX error should never pass silently
+                    continue  # XXX error should never pass silently
                 key, value = data
                 self.dist.package_data[key.strip()] = value.strip()
 
+            self.dist.data_files = []
+            for data in files.get('data_files', []):
+                data = data.split('=')
+                if len(data) != 2:
+                    continue
+                key, value = data
+                values = [v.strip() for v in value.split(',')]
+                self.dist.data_files.append((key, values))
+
             # manifest template
             self.dist.extra_files = files.get('extra_files', [])
 
             resources = []
             for rule in files.get('resources', []):
-                glob , destination  = rule.split('=', 1)
+                glob, destination = rule.split('=', 1)
                 rich_glob = glob.strip().split(' ', 1)
                 if len(rich_glob) == 2:
                     prefix, suffix = rich_glob
@@ -212,13 +246,15 @@
                     suffix = glob
                 if destination == '<exclude>':
                     destination = None
-                resources.append((prefix.strip(), suffix.strip(), destination.strip()))
-                self.dist.data_files = resources_dests(cfg_directory, resources)
+                resources.append(
+                    (prefix.strip(), suffix.strip(), destination.strip()))
+                self.dist.data_files = get_resources_dests(
+                    cfg_directory, resources)
 
         ext_modules = self.dist.ext_modules
         for section_key in content:
             labels = section_key.split('=')
-            if (len(labels) == 2) and (labels[0] == 'extension'):
+            if len(labels) == 2 and labels[0] == 'extension':
                 # labels[1] not used from now but should be implemented
                 # for extension build dependency
                 values_dct = content[section_key]
@@ -239,8 +275,7 @@
                     _pop_values(values_dct, 'depends'),
                     values_dct.pop('language', None),
                     values_dct.pop('optional', None),
-                    **values_dct
-                ))
+                    **values_dct))
 
     def parse_config_files(self, filenames=None):
         if filenames is None:
@@ -252,7 +287,8 @@
 
         for filename in filenames:
             logger.debug("  reading %s", filename)
-            parser.read(filename)
+            with codecs.open(filename, 'r', encoding='utf-8') as f:
+                parser.readfp(f)
 
             if os.path.split(filename)[-1] == 'setup.cfg':
                 self._read_setup_cfg(parser, filename)
@@ -275,8 +311,8 @@
                     opt = opt.replace('-', '_')
 
                     if opt == 'sub_commands':
-                        val = self._multiline(val)
-                        if isinstance(val, str):
+                        val = split_multiline(val)
+                        if isinstance(val, basestring):
                             val = [val]
 
                     # Hooks use a suffix system to prevent being overriden
@@ -287,8 +323,8 @@
                     if (opt.startswith("pre_hook.") or
                         opt.startswith("post_hook.")):
                         hook_type, alias = opt.split(".")
-                        hook_dict = opt_dict.setdefault(hook_type,
-                                                        (filename, {}))[1]
+                        hook_dict = opt_dict.setdefault(
+                            hook_type, (filename, {}))[1]
                         hook_dict[alias] = val
                     else:
                         opt_dict[opt] = filename, val
@@ -300,28 +336,28 @@
         # If there was a "global" section in the config file, use it
         # to set Distribution options.
         if 'global' in self.dist.command_options:
-            for (opt, (src, val)) in self.dist.command_options['global'].iteritems():
+            for opt, (src, val) in self.dist.command_options['global'].items():
                 alias = self.dist.negative_opt.get(opt)
                 try:
                     if alias:
                         setattr(self.dist, alias, not strtobool(val))
-                    elif opt in ('verbose', 'dry_run'):  # ugh!
+                    elif opt == 'dry_run':  # FIXME ugh!
                         setattr(self.dist, opt, strtobool(val))
                     else:
                         setattr(self.dist, opt, val)
-                except ValueError, msg:
-                    raise DistutilsOptionError(msg)
+                except ValueError:
+                    raise PackagingOptionError(sys.exc_info()[1])
 
     def _load_compilers(self, compilers):
-        compilers = self._multiline(compilers)
-        if isinstance(compilers, str):
+        compilers = split_multiline(compilers)
+        if isinstance(compilers, basestring):
             compilers = [compilers]
         for compiler in compilers:
             set_compiler(compiler.strip())
 
     def _load_commands(self, commands):
-        commands = self._multiline(commands)
-        if isinstance(commands, str):
+        commands = split_multiline(commands)
+        if isinstance(commands, basestring):
             commands = [commands]
         for command in commands:
             set_command(command.strip())
diff --git a/distutils2/create.py b/distutils2/create.py
--- a/distutils2/create.py
+++ b/distutils2/create.py
@@ -1,17 +1,12 @@
-#!/usr/bin/env python
-#
-#  Helper for automating the creation of a package by looking at you
-#  current directory and asking the user questions.
-#
-#  Available as either a stand-alone file or callable from the distutils2
-#  package:
-#
-#     python -m distutils2.mkcfg
-#  or:
-#     python mkcfg.py
-#
-#  Written by Sean Reifschneider <jafo at tummy.com>
-#
+"""Interactive helper used to create a setup.cfg file.
+
+This script will generate a distutils2 configuration file by looking at
+the current directory and asking the user questions.  It is intended to
+be called as *pysetup create*.
+"""
+
+#  Original code by Sean Reifschneider <jafo at tummy.com>
+
 #  Original TODO list:
 #  Look for a license file and automatically add the category.
 #  When a .c file is found during the walk, can we add it as an extension?
@@ -23,23 +18,26 @@
 #  Ask for a description
 #  Detect scripts (not sure how.  #! outside of package?)
 
+import codecs
 import os
+import re
+import imp
 import sys
 import glob
-import re
 import shutil
+import sysconfig
+import tokenize
+from hashlib import md5
+from textwrap import dedent
+from distutils2.util import cmp_to_key, detect_encoding
 from ConfigParser import RawConfigParser
-from textwrap import dedent
-try:
-    from hashlib import md5
-except ImportError:
-    from distutils2._backport.hashlib  import md5
 # importing this with an underscore as it should be replaced by the
 # dict form or another structures for all purposes
 from distutils2._trove import all_classifiers as _CLASSIFIERS_LIST
-from distutils2._backport import sysconfig
+from distutils2.version import is_valid_version
 
 _FILENAME = 'setup.cfg'
+_DEFAULT_CFG = '.pypkgcreate'
 
 _helptext = {
     'name': '''
@@ -64,7 +62,7 @@
     'do_classifier': '''
 Trove classifiers are optional identifiers that allow you to specify the
 intended audience by saying things like "Beta software with a text UI
-for Linux under the PSF license.  However, this can be a somewhat involved
+for Linux under the PSF license".  However, this can be a somewhat involved
 process.
 ''',
     'packages': '''
@@ -91,14 +89,34 @@
 ''',
     'setup.py found': '''
 The setup.py script will be executed to retrieve the metadata.
-A wizard will be run if you answer "n",
+An interactive helper will be run if you answer "n",
 ''',
 }
 
+PROJECT_MATURITY = ['Development Status :: 1 - Planning',
+                    'Development Status :: 2 - Pre-Alpha',
+                    'Development Status :: 3 - Alpha',
+                    'Development Status :: 4 - Beta',
+                    'Development Status :: 5 - Production/Stable',
+                    'Development Status :: 6 - Mature',
+                    'Development Status :: 7 - Inactive']
+
 # XXX everything needs docstrings and tests (both low-level tests of various
 # methods and functional tests of running the script)
 
 
+def load_setup():
+    """run the setup script (i.e the setup.py file)
+
+    This function load the setup file in all cases (even if it have already
+    been loaded before, because we are monkey patching its setup function with
+    a particular one"""
+    with open("setup.py", "rb") as f:
+        encoding, lines = detect_encoding(f.readline)
+    with open("setup.py") as f:
+        imp.load_module("setup", f, "setup.py", (".py", "r", imp.PY_SOURCE))
+
+
 def ask_yn(question, default=None, helptext=None):
     question += ' (y/n)'
     while True:
@@ -106,16 +124,16 @@
         if answer and answer[0].lower() in 'yn':
             return answer[0].lower()
 
-        print '\nERROR: You must select "Y" or "N".\n'
+        print('\nERROR: You must select "Y" or "N".\n')
 
 
 def ask(question, default=None, helptext=None, required=True,
         lengthy=False, multiline=False):
-    prompt = '%s: ' % (question,)
+    prompt = u'%s: ' % (question,)
     if default:
-        prompt = '%s [%s]: ' % (question, default)
+        prompt = u'%s [%s]: ' % (question, default)
         if default and len(question) + len(default) > 70:
-            prompt = '%s\n    [%s]: ' % (question, default)
+            prompt = u'%s\n    [%s]: ' % (question, default)
     if lengthy or multiline:
         prompt += '\n   > '
 
@@ -130,31 +148,39 @@
 
         line = sys.stdin.readline().strip()
         if line == '?':
-            print '=' * 70
-            print helptext
-            print '=' * 70
+            print('=' * 70)
+            print(helptext)
+            print('=' * 70)
             continue
         if default and not line:
             return default
         if not line and required:
-            print '*' * 70
-            print 'This value cannot be empty.'
-            print '==========================='
+            print('*' * 70)
+            print('This value cannot be empty.')
+            print('===========================')
             if helptext:
-                print helptext
-            print '*' * 70
+                print(helptext)
+            print('*' * 70)
             continue
         return line
 
 
+def convert_yn_to_bool(yn, yes=True, no=False):
+    """Convert a y/yes or n/no to a boolean value."""
+    if yn.lower().startswith('y'):
+        return yes
+    else:
+        return no
+
+
 def _build_classifiers_dict(classifiers):
     d = {}
     for key in classifiers:
-        subDict = d
+        subdict = d
         for subkey in key.split(' :: '):
-            if not subkey in subDict:
-                subDict[subkey] = {}
-            subDict = subDict[subkey]
+            if subkey not in subdict:
+                subdict[subkey] = {}
+            subdict = subdict[subkey]
     return d
 
 CLASSIFIERS = _build_classifiers_dict(_CLASSIFIERS_LIST)
@@ -172,78 +198,144 @@
 
 
 class MainProgram(object):
+    """Make a project setup configuration file (setup.cfg)."""
+
     def __init__(self):
         self.configparser = None
-        self.classifiers = set([])
-        self.data = {}
-        self.data['classifier'] = self.classifiers
-        self.data['packages'] = []
-        self.data['modules'] = []
-        self.data['platform'] = []
-        self.data['resources'] = []
-        self.data['extra_files'] = []
-        self.data['scripts'] = []
-        self.load_config_file()
+        self.classifiers = set()
+        self.data = {'name': '',
+                     'version': '1.0.0',
+                     'classifier': self.classifiers,
+                     'packages': [],
+                     'modules': [],
+                     'platform': [],
+                     'resources': [],
+                     'extra_files': [],
+                     'scripts': [],
+                     }
+        self._load_defaults()
 
-    def lookup_option(self, key):
+    def __call__(self):
+        setupcfg_defined = False
+        if self.has_setup_py() and self._prompt_user_for_conversion():
+            setupcfg_defined = self.convert_py_to_cfg()
+        if not setupcfg_defined:
+            self.define_cfg_values()
+        self._write_cfg()
+
+    def has_setup_py(self):
+        """Test for the existence of a setup.py file."""
+        return os.path.exists('setup.py')
+
+    def define_cfg_values(self):
+        self.inspect()
+        self.query_user()
+
+    def _lookup_option(self, key):
         if not self.configparser.has_option('DEFAULT', key):
             return None
         return self.configparser.get('DEFAULT', key)
 
-    def load_config_file(self):
+    def _load_defaults(self):
+        # Load default values from a user configuration file
         self.configparser = RawConfigParser()
         # TODO replace with section in distutils config file
-        #XXX freedesktop
-        self.configparser.read(os.path.expanduser('~/.mkcfg'))
-        self.data['author'] = self.lookup_option('author')
-        self.data['author_email'] = self.lookup_option('author_email')
+        default_cfg = os.path.expanduser(os.path.join('~', _DEFAULT_CFG))
+        self.configparser.read(default_cfg)
+        self.data['author'] = self._lookup_option('author')
+        self.data['author_email'] = self._lookup_option('author_email')
 
-    def update_config_file(self):
-        valuesDifferent = False
-        # FIXME looking only for those two fields seems wrong
-        for compareKey in ('author', 'author_email'):
-            if self.lookup_option(compareKey) != self.data[compareKey]:
-                valuesDifferent = True
-                self.configparser.set('DEFAULT', compareKey,
-                                      self.data[compareKey])
+    def _prompt_user_for_conversion(self):
+        # Prompt the user about whether they would like to use the setup.py
+        # conversion utility to generate a setup.cfg or generate the setup.cfg
+        # from scratch
+        answer = ask_yn(('A legacy setup.py has been found.\n'
+                         'Would you like to convert it to a setup.cfg?'),
+                        default="y",
+                        helptext=_helptext['setup.py found'])
+        return convert_yn_to_bool(answer)
 
-        if not valuesDifferent:
-            return
+    def _dotted_packages(self, data):
+        packages = sorted(data)
+        modified_pkgs = []
+        for pkg in packages:
+            pkg = pkg.lstrip('./')
+            pkg = pkg.replace('/', '.')
+            modified_pkgs.append(pkg)
+        return modified_pkgs
 
-        #XXX freedesktop
-        fp = open(os.path.expanduser('~/.mkcfgpy'), 'w')
-        try:
-            self.configparser.write(fp)
-        finally:
-            fp.close()
+    def _write_cfg(self):
+        if os.path.exists(_FILENAME):
+            if os.path.exists('%s.old' % _FILENAME):
+                print("ERROR: %(name)s.old backup exists, please check that "
+                      "current %(name)s is correct and remove %(name)s.old" %
+                      {'name': _FILENAME})
+                return
+            shutil.move(_FILENAME, '%s.old' % _FILENAME)
 
-    def load_existing_setup_script(self):
-        """ Generate a setup.cfg from an existing setup.py.
+        with codecs.open(_FILENAME, 'w', encoding='utf-8') as fp:
+            fp.write('[metadata]\n')
+            # TODO use metadata module instead of hard-coding field-specific
+            # behavior here
+
+            # simple string entries
+            for name in ('name', 'version', 'summary', 'download_url'):
+                fp.write('%s = %s\n' % (name, self.data.get(name, 'UNKNOWN')))
+
+            # optional string entries
+            if 'keywords' in self.data and self.data['keywords']:
+                fp.write('keywords = %s\n' % ' '.join(self.data['keywords']))
+            for name in ('home_page', 'author', 'author_email',
+                         'maintainer', 'maintainer_email', 'description-file'):
+                if name in self.data and self.data[name]:
+                    fp.write('%s = %s\n' % (name, self.data[name]))
+            if 'description' in self.data:
+                fp.write(
+                    'description = %s\n'
+                    % '\n       |'.join(self.data['description'].split('\n')))
+
+            # multiple use string entries
+            for name in ('platform', 'supported-platform', 'classifier',
+                         'requires-dist', 'provides-dist', 'obsoletes-dist',
+                         'requires-external'):
+                if not(name in self.data and self.data[name]):
+                    continue
+                fp.write('%s = ' % name)
+                fp.write(''.join('    %s\n' % val
+                                 for val in self.data[name]).lstrip())
+            fp.write('\n[files]\n')
+            for name in ('packages', 'modules', 'scripts',
+                         'package_data', 'extra_files'):
+                if not(name in self.data and self.data[name]):
+                    continue
+                fp.write('%s = %s\n'
+                         % (name, '\n    '.join(self.data[name]).strip()))
+            fp.write('\nresources =\n')
+            for src, dest in self.data['resources']:
+                fp.write('    %s = %s\n' % (src, dest))
+            fp.write('\n')
+
+        os.chmod(_FILENAME, 0o644)
+        print('Wrote "%s".' % _FILENAME)
+
+    def convert_py_to_cfg(self):
+        """Generate a setup.cfg from an existing setup.py.
 
         It only exports the distutils metadata (setuptools specific metadata
-        is not actually supported).
+        is not currently supported).
         """
-        setuppath = 'setup.py'
-        if not os.path.exists(setuppath):
-            return
-        else:
-            ans = ask_yn(('A legacy setup.py has been found.\n'
-                          'Would you like to convert it to a setup.cfg ?'),
-                         'y',
-                         _helptext['setup.py found'])
-            if ans != 'y':
-                return
-
         data = self.data
 
-        def setup(**attrs):
-            """Mock the setup(**attrs) in order to retrive metadata."""
-            # use the distutils v1 processings to correctly parse metadata.
-            #XXX we could also use the setuptools distibution ???
+        def setup_mock(**attrs):
+            """Mock the setup(**attrs) in order to retrieve metadata."""
+
+            # TODO use config and metadata instead of Distribution
             from distutils.dist import Distribution
             dist = Distribution(attrs)
             dist.parse_config_files()
-            # 1. retrieves metadata that are quite similar PEP314<->PEP345
+
+            # 1. retrieve metadata fields that are quite similar in
+            # PEP 314 and PEP 345
             labels = (('name',) * 2,
                       ('version',) * 2,
                       ('author',) * 2,
@@ -253,83 +345,99 @@
                       ('description', 'summary'),
                       ('long_description', 'description'),
                       ('url', 'home_page'),
-                      ('platforms', 'platform'))
+                      ('platforms', 'platform'),
+                      # backport only for 2.5+
+                      ('provides', 'provides-dist'),
+                      ('obsoletes', 'obsoletes-dist'),
+                      ('requires', 'requires-dist'))
 
-            if sys.version[:3] >= '2.5':
-                labels += (('provides', 'provides-dist'),
-                           ('obsoletes', 'obsoletes-dist'),
-                           ('requires', 'requires-dist'),)
             get = lambda lab: getattr(dist.metadata, lab.replace('-', '_'))
-            data.update((new, get(old)) for (old, new) in labels if get(old))
-            # 2. retrieves data that requires special processings.
+            data.update((new, get(old)) for old, new in labels if get(old))
+
+            # 2. retrieve data that requires special processing
             data['classifier'].update(dist.get_classifiers() or [])
             data['scripts'].extend(dist.scripts or [])
             data['packages'].extend(dist.packages or [])
             data['modules'].extend(dist.py_modules or [])
-            # 2.1 data_files -> resources.
+            # 2.1 data_files -> resources
             if dist.data_files:
-                if len(dist.data_files) < 2 or \
-                   isinstance(dist.data_files[1], str):
+                if (len(dist.data_files) < 2 or
+                    isinstance(dist.data_files[1], basestring)):
                     dist.data_files = [('', dist.data_files)]
                 # add tokens in the destination paths
                 vars = {'distribution.name': data['name']}
-                path_tokens = sysconfig.get_paths(vars=vars).items()
+                path_tokens = list(sysconfig.get_paths(vars=vars).items())
+
+                # TODO replace this with a key function
+                def length_comparison(x, y):
+                    len_x = len(x[1])
+                    len_y = len(y[1])
+                    if len_x == len_y:
+                        return 0
+                    elif len_x < len_y:
+                        return -1
+                    else:
+                        return 1
+
                 # sort tokens to use the longest one first
-                # TODO chain two sorted with key arguments, remove cmp
-                path_tokens.sort(cmp=lambda x, y: cmp(len(y), len(x)),
-                                 key=lambda x: x[1])
+                path_tokens.sort(key=cmp_to_key(length_comparison))
                 for dest, srcs in (dist.data_files or []):
                     dest = os.path.join(sys.prefix, dest)
+                    dest = dest.replace(os.path.sep, '/')
                     for tok, path in path_tokens:
-                        if dest.startswith(path):
-                            dest = ('{%s}' % tok) + dest[len(path):]
-                            files = [('/ '.join(src.rsplit('/', 1)), dest)
-                                     for src in srcs]
-                            data['resources'].extend(files)
+                        path = path.replace(os.path.sep, '/')
+                        if not dest.startswith(path):
                             continue
+
+                        dest = ('{%s}' % tok) + dest[len(path):]
+                        files = [('/ '.join(src.rsplit('/', 1)), dest)
+                                 for src in srcs]
+                        data['resources'].extend(files)
+
             # 2.2 package_data -> extra_files
             package_dirs = dist.package_dir or {}
-            for package, extras in dist.package_data.iteritems() or []:
+            for package, extras in dist.package_data.items() or []:
                 package_dir = package_dirs.get(package, package)
-                files = [os.path.join(package_dir, f) for f in extras]
-                data['extra_files'].extend(files)
+                for file_ in extras:
+                    if package_dir:
+                        file_ = package_dir + '/' + file_
+                    data['extra_files'].append(file_)
 
             # Use README file if its content is the desciption
             if "description" in data:
-                ref = md5(re.sub('\s', '', self.data['description']).lower())
+                ref = md5(re.sub('\s', '',
+                                 self.data['description']).lower().encode())
                 ref = ref.digest()
                 for readme in glob.glob('README*'):
-                    fp = open(readme)
-                    try:
+                    with codecs.open(readme, encoding='utf-8') as fp:
                         contents = fp.read()
-                    finally:
-                        fp.close()
-                    val = md5(re.sub('\s', '', contents.lower())).digest()
+                    contents = re.sub('\s', '', contents.lower()).encode()
+                    val = md5(contents).digest()
                     if val == ref:
                         del data['description']
                         data['description-file'] = readme
                         break
 
         # apply monkey patch to distutils (v1) and setuptools (if needed)
-        # (abord the feature if distutils v1 has been killed)
+        # (abort the feature if distutils v1 has been killed)
         try:
-            import distutils.core as DC
-            DC.setup  # ensure distutils v1
+            from distutils import core
+            core.setup  # make sure it's not d2 maskerading as d1
         except (ImportError, AttributeError):
             return
-        saved_setups = [(DC, DC.setup)]
-        DC.setup = setup
+        saved_setups = [(core, core.setup)]
+        core.setup = setup_mock
         try:
             import setuptools
+        except ImportError:
+            pass
+        else:
             saved_setups.append((setuptools, setuptools.setup))
-            setuptools.setup = setup
-        except (ImportError, AttributeError):
-            pass
+            setuptools.setup = setup_mock
         # get metadata by executing the setup.py with the patched setup(...)
         success = False  # for python < 2.4
         try:
-            pyenv = globals().copy()
-            execfile(setuppath, pyenv)
+            load_setup()
             success = True
         finally:  # revert monkey patches
             for patched_module, original_setup in saved_setups:
@@ -338,33 +446,27 @@
             raise ValueError('Unable to load metadata from setup.py')
         return success
 
-    def inspect_file(self, path):
-        fp = open(path, 'r')
-        try:
-            for _ in xrange(10):
-                line = fp.readline()
-                m = re.match(r'^#!.*python((?P<major>\d)(\.\d+)?)?$', line)
-                if m:
-                    if m.group('major') == '3':
-                        self.classifiers.add(
-                            'Programming Language :: Python :: 3')
-                    else:
-                        self.classifiers.add(
-                        'Programming Language :: Python :: 2')
-        finally:
-            fp.close()
+    def inspect(self):
+        """Inspect the current working diretory for a name and version.
 
-    def inspect_directory(self):
-        dirName = os.path.basename(os.getcwd())
-        self.data['name'] = dirName
-        m = re.match(r'(.*)-(\d.+)', dirName)
-        if m:
-            self.data['name'] = m.group(1)
-            self.data['version'] = m.group(2)
+        This information is harvested in where the directory is named
+        like [name]-[version].
+        """
+        dir_name = os.path.basename(os.getcwd())
+        self.data['name'] = dir_name
+        match = re.match(r'(.*)-(\d.+)', dir_name)
+        if match:
+            self.data['name'] = match.group(1)
+            self.data['version'] = match.group(2)
+            # TODO needs testing!
+            if not is_valid_version(self.data['version']):
+                msg = "Invalid version discovered: %s" % self.data['version']
+                raise ValueError(msg)
 
     def query_user(self):
         self.data['name'] = ask('Project name', self.data['name'],
               _helptext['name'])
+
         self.data['version'] = ask('Current version number',
               self.data.get('version'), _helptext['version'])
         self.data['summary'] = ask('Package summary',
@@ -374,25 +476,25 @@
               self.data.get('author'), _helptext['author'])
         self.data['author_email'] = ask('Author e-mail address',
               self.data.get('author_email'), _helptext['author_email'])
-        self.data['home_page'] = ask('Project Home Page',
+        self.data['home_page'] = ask('Project home page',
               self.data.get('home_page'), _helptext['home_page'],
               required=False)
 
         if ask_yn('Do you want me to automatically build the file list '
-              'with everything I can find in the current directory ? '
+              'with everything I can find in the current directory? '
               'If you say no, you will have to define them manually.') == 'y':
             self._find_files()
         else:
-            while ask_yn('Do you want to add a single module ?'
+            while ask_yn('Do you want to add a single module?'
                         ' (you will be able to add full packages next)',
                     helptext=_helptext['modules']) == 'y':
                 self._set_multi('Module name', 'modules')
 
-            while ask_yn('Do you want to add a package ?',
+            while ask_yn('Do you want to add a package?',
                     helptext=_helptext['packages']) == 'y':
                 self._set_multi('Package name', 'packages')
 
-            while ask_yn('Do you want to add an extra file ?',
+            while ask_yn('Do you want to add an extra file?',
                         helptext=_helptext['extra_files']) == 'y':
                 self._set_multi('Extra file/dir name', 'extra_files')
 
@@ -437,7 +539,7 @@
                 res = res[:-len('.py')]
             return res
 
-        # first pass : packages
+        # first pass: packages
         for root, dirs, files in os.walk(curdir):
             if to_skip(root):
                 continue
@@ -455,14 +557,14 @@
             if to_skip(root):
                 continue
 
-            if True in [root.startswith(path) for path in scanned]:
+            if any(root.startswith(path) for path in scanned):
                 continue
 
             for file in sorted(files):
                 fullpath = os.path.join(root, file)
                 if to_skip(fullpath):
                     continue
-                # single module ?
+                # single module?
                 if os.path.splitext(file)[-1] == '.py':
                     modules.append(dotted(fullpath))
                 else:
@@ -475,12 +577,12 @@
             existing_values.append(value)
 
     def set_classifier(self):
-        self.set_devel_status(self.classifiers)
+        self.set_maturity_status(self.classifiers)
         self.set_license(self.classifiers)
         self.set_other_classifier(self.classifiers)
 
     def set_other_classifier(self, classifiers):
-        if ask_yn('Do you want to set other trove identifiers', 'n',
+        if ask_yn('Do you want to set other trove identifiers?', 'n',
                   _helptext['trove_generic']) != 'y':
             return
         self.walk_classifiers(classifiers, [CLASSIFIERS], '')
@@ -497,7 +599,7 @@
                     classifiers.add(desc[4:] + ' :: ' + key)
                 continue
 
-            if ask_yn('Do you want to set items under\n   "%s" (%d sub-items)'
+            if ask_yn('Do you want to set items under\n   "%s" (%d sub-items)?'
                       % (key, len(trove[key])), 'n',
                       _helptext['trove_generic']) == 'y':
                 self.walk_classifiers(classifiers, trovepath + [trove[key]],
@@ -505,7 +607,7 @@
 
     def set_license(self, classifiers):
         while True:
-            license = ask('What license do you use',
+            license = ask('What license do you use?',
                           helptext=_helptext['trove_license'], required=False)
             if not license:
                 return
@@ -520,7 +622,7 @@
                         break
 
             if len(found_list) == 0:
-                print('ERROR: Could not find a matching license for "%s"' % \
+                print('ERROR: Could not find a matching license for "%s"' %
                       license)
                 continue
 
@@ -542,115 +644,45 @@
             try:
                 index = found_list[int(choice) - 1]
             except ValueError:
-                print ("ERROR: Invalid selection, type a number from the list "
-                       "above.")
+                print("ERROR: Invalid selection, type a number from the list "
+                      "above.")
 
             classifiers.add(_CLASSIFIERS_LIST[index])
-            return
 
-    def set_devel_status(self, classifiers):
+    def set_maturity_status(self, classifiers):
+        maturity_name = lambda mat: mat.split('- ')[-1]
+        maturity_question = '''\
+            Please select the project status:
+
+            %s
+
+            Status''' % '\n'.join('%s - %s' % (i, maturity_name(n))
+                                  for i, n in enumerate(PROJECT_MATURITY))
         while True:
-            choice = ask(dedent('''\
-                Please select the project status:
+            choice = ask(dedent(maturity_question), required=False)
 
-                1 - Planning
-                2 - Pre-Alpha
-                3 - Alpha
-                4 - Beta
-                5 - Production/Stable
-                6 - Mature
-                7 - Inactive
-
-                Status'''), required=False)
             if choice:
                 try:
                     choice = int(choice) - 1
-                    key = ['Development Status :: 1 - Planning',
-                           'Development Status :: 2 - Pre-Alpha',
-                           'Development Status :: 3 - Alpha',
-                           'Development Status :: 4 - Beta',
-                           'Development Status :: 5 - Production/Stable',
-                           'Development Status :: 6 - Mature',
-                           'Development Status :: 7 - Inactive'][choice]
+                    key = PROJECT_MATURITY[choice]
                     classifiers.add(key)
                     return
                 except (IndexError, ValueError):
-                    print ("ERROR: Invalid selection, type a single digit "
-                           "number.")
-
-    def _dotted_packages(self, data):
-        packages = sorted(data)
-        modified_pkgs = []
-        for pkg in packages:
-            pkg = pkg.lstrip('./')
-            pkg = pkg.replace('/', '.')
-            modified_pkgs.append(pkg)
-        return modified_pkgs
-
-    def write_setup_script(self):
-        if os.path.exists(_FILENAME):
-            if os.path.exists('%s.old' % _FILENAME):
-                print("ERROR: %(name)s.old backup exists, please check that "
-                    "current %(name)s is correct and remove %(name)s.old" % \
-                    {'name': _FILENAME})
-                return
-            shutil.move(_FILENAME, '%s.old' % _FILENAME)
-
-        fp = open(_FILENAME, 'w')
-        try:
-            fp.write('[metadata]\n')
-            # simple string entries
-            for name in ('name', 'version', 'summary', 'download_url'):
-                fp.write('%s = %s\n' % (name, self.data.get(name, 'UNKNOWN')))
-            # optional string entries
-            if 'keywords' in self.data and self.data['keywords']:
-                fp.write('keywords = %s\n' % ' '.join(self.data['keywords']))
-            for name in ('home_page', 'author', 'author_email',
-                         'maintainer', 'maintainer_email', 'description-file'):
-                if name in self.data and self.data[name]:
-                    fp.write('%s = %s\n' % (name, self.data[name]))
-            if 'description' in self.data:
-                fp.write(
-                    'description = %s\n'
-                    % '\n       |'.join(self.data['description'].split('\n')))
-            # multiple use string entries
-            for name in ('platform', 'supported-platform', 'classifier',
-                         'requires-dist', 'provides-dist', 'obsoletes-dist',
-                         'requires-external'):
-                if not(name in self.data and self.data[name]):
-                    continue
-                fp.write('%s = ' % name)
-                fp.write(''.join('    %s\n' % val
-                                 for val in self.data[name]).lstrip())
-            fp.write('\n[files]\n')
-            for name in ('packages', 'modules', 'scripts',
-                         'package_data', 'extra_files'):
-                if not(name in self.data and self.data[name]):
-                    continue
-                fp.write('%s = %s\n'
-                         % (name, '\n    '.join(self.data[name]).strip()))
-            fp.write('\nresources =\n')
-            for src, dest in self.data['resources']:
-                fp.write('    %s = %s\n' % (src, dest))
-            fp.write('\n')
-
-        finally:
-            fp.close()
-
-        os.chmod(_FILENAME, 0644)
-        print 'Wrote "%s".' % _FILENAME
+                    print("ERROR: Invalid selection, type a single digit "
+                          "number.")
 
 
 def main():
     """Main entry point."""
     program = MainProgram()
-    # uncomment when implemented
-    if not program.load_existing_setup_script():
-        program.inspect_directory()
-        program.query_user()
-        program.update_config_file()
-    program.write_setup_script()
+    # # uncomment when implemented
+    # if not program.load_existing_setup_script():
+    #     program.inspect_directory()
+    #     program.query_user()
+    #     program.update_config_file()
+    # program.write_setup_script()
     # distutils2.util.cfg_to_args()
+    program()
 
 
 if __name__ == '__main__':
diff --git a/distutils2/database.py b/distutils2/database.py
new file mode 100644
--- /dev/null
+++ b/distutils2/database.py
@@ -0,0 +1,647 @@
+"""PEP 376 implementation."""
+
+from StringIO import StringIO
+import os
+import re
+import csv
+import sys
+import zipimport
+from hashlib import md5
+from distutils2 import logger
+from distutils2.errors import PackagingError
+from distutils2.version import suggest_normalized_version, VersionPredicate
+from distutils2.metadata import Metadata
+
+
+__all__ = [
+    'Distribution', 'EggInfoDistribution', 'distinfo_dirname',
+    'get_distributions', 'get_distribution', 'get_file_users',
+    'provides_distribution', 'obsoletes_distribution',
+    'enable_cache', 'disable_cache', 'clear_cache',
+    'get_file_path', 'get_file']
+
+
+# TODO update docs
+
+DIST_FILES = ('INSTALLER', 'METADATA', 'RECORD', 'REQUESTED', 'RESOURCES')
+
+# Cache
+_cache_name = {}  # maps names to Distribution instances
+_cache_name_egg = {}  # maps names to EggInfoDistribution instances
+_cache_path = {}  # maps paths to Distribution instances
+_cache_path_egg = {}  # maps paths to EggInfoDistribution instances
+_cache_generated = False  # indicates if .dist-info distributions are cached
+_cache_generated_egg = False  # indicates if .dist-info and .egg are cached
+_cache_enabled = True
+
+
+def enable_cache():
+    """
+    Enables the internal cache.
+
+    Note that this function will not clear the cache in any case, for that
+    functionality see :func:`clear_cache`.
+    """
+    global _cache_enabled
+
+    _cache_enabled = True
+
+
+def disable_cache():
+    """
+    Disables the internal cache.
+
+    Note that this function will not clear the cache in any case, for that
+    functionality see :func:`clear_cache`.
+    """
+    global _cache_enabled
+
+    _cache_enabled = False
+
+
+def clear_cache():
+    """ Clears the internal cache. """
+    global _cache_generated, _cache_generated_egg
+
+    _cache_name.clear()
+    _cache_name_egg.clear()
+    _cache_path.clear()
+    _cache_path_egg.clear()
+    _cache_generated = False
+    _cache_generated_egg = False
+
+
+def _yield_distributions(include_dist, include_egg, paths):
+    """
+    Yield .dist-info and .egg(-info) distributions, based on the arguments
+
+    :parameter include_dist: yield .dist-info distributions
+    :parameter include_egg: yield .egg(-info) distributions
+    """
+    for path in paths:
+        realpath = os.path.realpath(path)
+        if not os.path.isdir(realpath):
+            continue
+        for dir in os.listdir(realpath):
+            dist_path = os.path.join(realpath, dir)
+            if include_dist and dir.endswith('.dist-info'):
+                yield Distribution(dist_path)
+            elif include_egg and (dir.endswith('.egg-info') or
+                                  dir.endswith('.egg')):
+                yield EggInfoDistribution(dist_path)
+
+
+def _generate_cache(use_egg_info, paths):
+    global _cache_generated, _cache_generated_egg
+
+    if _cache_generated_egg or (_cache_generated and not use_egg_info):
+        return
+    else:
+        gen_dist = not _cache_generated
+        gen_egg = use_egg_info
+
+        for dist in _yield_distributions(gen_dist, gen_egg, paths):
+            if isinstance(dist, Distribution):
+                _cache_path[dist.path] = dist
+                if dist.name not in _cache_name:
+                    _cache_name[dist.name] = []
+                _cache_name[dist.name].append(dist)
+            else:
+                _cache_path_egg[dist.path] = dist
+                if dist.name not in _cache_name_egg:
+                    _cache_name_egg[dist.name] = []
+                _cache_name_egg[dist.name].append(dist)
+
+        if gen_dist:
+            _cache_generated = True
+        if gen_egg:
+            _cache_generated_egg = True
+
+
+class Distribution(object):
+    """Created with the *path* of the ``.dist-info`` directory provided to the
+    constructor. It reads the metadata contained in ``METADATA`` when it is
+    instantiated."""
+
+    name = ''
+    """The name of the distribution."""
+
+    version = ''
+    """The version of the distribution."""
+
+    metadata = None
+    """A :class:`distutils2.metadata.Metadata` instance loaded with
+    the distribution's ``METADATA`` file."""
+
+    requested = False
+    """A boolean that indicates whether the ``REQUESTED`` metadata file is
+    present (in other words, whether the package was installed by user
+    request or it was installed as a dependency)."""
+
+    def __init__(self, path):
+        if _cache_enabled and path in _cache_path:
+            self.metadata = _cache_path[path].metadata
+        else:
+            metadata_path = os.path.join(path, 'METADATA')
+            self.metadata = Metadata(path=metadata_path)
+
+        self.name = self.metadata['Name']
+        self.version = self.metadata['Version']
+        self.path = path
+
+        if _cache_enabled and path not in _cache_path:
+            _cache_path[path] = self
+
+    def __repr__(self):
+        return '<Distribution %r %s at %r>' % (
+            self.name, self.version, self.path)
+
+    def _get_records(self, local=False):
+        results = []
+        with self.get_distinfo_file('RECORD') as record:
+            record_reader = csv.reader(record, delimiter=',',
+                                       lineterminator='\n')
+            for row in record_reader:
+                missing = [None for i in range(len(row), 3)]
+                path, checksum, size = row + missing
+                if local:
+                    path = path.replace('/', os.sep)
+                    path = os.path.join(sys.prefix, path)
+                results.append((path, checksum, size))
+        return results
+
+    def get_resource_path(self, relative_path):
+        with self.get_distinfo_file('RESOURCES') as resources_file:
+            resources_reader = csv.reader(resources_file, delimiter=',',
+                                           lineterminator='\n')
+            for relative, destination in resources_reader:
+                if relative == relative_path:
+                    return destination
+        raise KeyError(
+            'no resource file with relative path %r is installed' %
+            relative_path)
+
+    def list_installed_files(self, local=False):
+        """
+        Iterates over the ``RECORD`` entries and returns a tuple
+        ``(path, md5, size)`` for each line. If *local* is ``True``,
+        the returned path is transformed into a local absolute path.
+        Otherwise the raw value from RECORD is returned.
+
+        A local absolute path is an absolute path in which occurrences of
+        ``'/'`` have been replaced by the system separator given by ``os.sep``.
+
+        :parameter local: flag to say if the path should be returned a local
+                          absolute path
+
+        :type local: boolean
+        :returns: iterator of (path, md5, size)
+        """
+        for result in self._get_records(local):
+            yield result
+
+    def uses(self, path):
+        """
+        Returns ``True`` if path is listed in ``RECORD``. *path* can be a local
+        absolute path or a relative ``'/'``-separated path.
+
+        :rtype: boolean
+        """
+        for p, checksum, size in self._get_records():
+            local_absolute = os.path.join(sys.prefix, p)
+            if path == p or path == local_absolute:
+                return True
+        return False
+
+    def get_distinfo_file(self, path, binary=False):
+        """
+        Returns a file located under the ``.dist-info`` directory. Returns a
+        ``file`` instance for the file pointed by *path*.
+
+        :parameter path: a ``'/'``-separated path relative to the
+                         ``.dist-info`` directory or an absolute path;
+                         If *path* is an absolute path and doesn't start
+                         with the ``.dist-info`` directory path,
+                         a :class:`PackagingError` is raised
+        :type path: string
+        :parameter binary: If *binary* is ``True``, opens the file in read-only
+                           binary mode (``rb``), otherwise opens it in
+                           read-only mode (``r``).
+        :rtype: file object
+        """
+        open_flags = 'r'
+        if binary:
+            open_flags += 'b'
+
+        # Check if it is an absolute path  # XXX use relpath, add tests
+        if path.find(os.sep) >= 0:
+            # it's an absolute path?
+            distinfo_dirname, path = path.split(os.sep)[-2:]
+            if distinfo_dirname != self.path.split(os.sep)[-1]:
+                raise PackagingError(
+                    'dist-info file %r does not belong to the %r %s '
+                    'distribution' % (path, self.name, self.version))
+
+        # The file must be relative
+        if path not in DIST_FILES:
+            raise PackagingError('invalid path for a dist-info file: %r' %
+                                 path)
+
+        path = os.path.join(self.path, path)
+        return open(path, open_flags)
+
+    def list_distinfo_files(self, local=False):
+        """
+        Iterates over the ``RECORD`` entries and returns paths for each line if
+        the path is pointing to a file located in the ``.dist-info`` directory
+        or one of its subdirectories.
+
+        :parameter local: If *local* is ``True``, each returned path is
+                          transformed into a local absolute path. Otherwise the
+                          raw value from ``RECORD`` is returned.
+        :type local: boolean
+        :returns: iterator of paths
+        """
+        for path, checksum, size in self._get_records(local):
+            yield path
+
+    def __eq__(self, other):
+        return isinstance(other, Distribution) and self.path == other.path
+
+    # See http://docs.python.org/reference/datamodel#object.__hash__
+    __hash__ = object.__hash__
+
+
+class EggInfoDistribution(object):
+    """Created with the *path* of the ``.egg-info`` directory or file provided
+    to the constructor. It reads the metadata contained in the file itself, or
+    if the given path happens to be a directory, the metadata is read from the
+    file ``PKG-INFO`` under that directory."""
+
+    name = ''
+    """The name of the distribution."""
+
+    version = ''
+    """The version of the distribution."""
+
+    metadata = None
+    """A :class:`distutils2.metadata.Metadata` instance loaded with
+    the distribution's ``METADATA`` file."""
+
+    _REQUIREMENT = re.compile(
+        r'(?P<name>[-A-Za-z0-9_.]+)\s*'
+        r'(?P<first>(?:<|<=|!=|==|>=|>)[-A-Za-z0-9_.]+)?\s*'
+        r'(?P<rest>(?:\s*,\s*(?:<|<=|!=|==|>=|>)[-A-Za-z0-9_.]+)*)\s*'
+        r'(?P<extras>\[.*\])?')
+
+    def __init__(self, path):
+        self.path = path
+        if _cache_enabled and path in _cache_path_egg:
+            self.metadata = _cache_path_egg[path].metadata
+            self.name = self.metadata['Name']
+            self.version = self.metadata['Version']
+            return
+
+        # reused from Distribute's pkg_resources
+        def yield_lines(strs):
+            """Yield non-empty/non-comment lines of a ``basestring``
+            or sequence"""
+            if isinstance(strs, basestring):
+                for s in strs.splitlines():
+                    s = s.strip()
+                    # skip blank lines/comments
+                    if s and not s.startswith('#'):
+                        yield s
+            else:
+                for ss in strs:
+                    for s in yield_lines(ss):
+                        yield s
+
+        requires = None
+
+        if path.endswith('.egg'):
+            if os.path.isdir(path):
+                meta_path = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
+                self.metadata = Metadata(path=meta_path)
+                try:
+                    req_path = os.path.join(path, 'EGG-INFO', 'requires.txt')
+                    with open(req_path, 'r') as fp:
+                        requires = fp.read()
+                except IOError:
+                    requires = None
+            else:
+                # FIXME handle the case where zipfile is not available
+                zipf = zipimport.zipimporter(path)
+                fileobj = StringIO(
+                    zipf.get_data('EGG-INFO/PKG-INFO').decode('utf8'))
+                self.metadata = Metadata(fileobj=fileobj)
+                try:
+                    requires = zipf.get_data('EGG-INFO/requires.txt')
+                except IOError:
+                    requires = None
+            self.name = self.metadata['Name']
+            self.version = self.metadata['Version']
+
+        elif path.endswith('.egg-info'):
+            if os.path.isdir(path):
+                path = os.path.join(path, 'PKG-INFO')
+                try:
+                    with open(os.path.join(path, 'requires.txt'), 'r') as fp:
+                        requires = fp.read()
+                except IOError:
+                    requires = None
+            self.metadata = Metadata(path=path)
+            self.name = self.metadata['Name']
+            self.version = self.metadata['Version']
+
+        else:
+            raise ValueError('path must end with .egg-info or .egg, got %r' %
+                             path)
+
+        if requires is not None:
+            if self.metadata['Metadata-Version'] == '1.1':
+                # we can't have 1.1 metadata *and* Setuptools requires
+                for field in ('Obsoletes', 'Requires', 'Provides'):
+                    del self.metadata[field]
+
+        reqs = []
+
+        if requires is not None:
+            for line in yield_lines(requires):
+                if line.startswith('['):
+                    logger.warning(
+                        'extensions in requires.txt are not supported '
+                        '(used by %r %s)', self.name, self.version)
+                    break
+                else:
+                    match = self._REQUIREMENT.match(line.strip())
+                    if not match:
+                        # this happens when we encounter extras; since they
+                        # are written at the end of the file we just exit
+                        break
+                    else:
+                        if match.group('extras'):
+                            msg = ('extra requirements are not supported '
+                                   '(used by %r %s)', self.name, self.version)
+                            logger.warning(msg, self.name)
+                        name = match.group('name')
+                        version = None
+                        if match.group('first'):
+                            version = match.group('first')
+                            if match.group('rest'):
+                                version += match.group('rest')
+                            version = version.replace(' ', '')  # trim spaces
+                        if version is None:
+                            reqs.append(name)
+                        else:
+                            reqs.append('%s (%s)' % (name, version))
+
+            if len(reqs) > 0:
+                self.metadata['Requires-Dist'] += reqs
+
+        if _cache_enabled:
+            _cache_path_egg[self.path] = self
+
+    def __repr__(self):
+        return '<EggInfoDistribution %r %s at %r>' % (
+            self.name, self.version, self.path)
+
+    def list_installed_files(self, local=False):
+
+        def _md5(path):
+            with open(path, 'rb') as f:
+                content = f.read()
+            return md5(content).hexdigest()
+
+        def _size(path):
+            return os.stat(path).st_size
+
+        path = self.path
+        if local:
+            path = path.replace('/', os.sep)
+
+        # XXX What about scripts and data files ?
+        if os.path.isfile(path):
+            return [(path, _md5(path), _size(path))]
+        else:
+            files = []
+            for root, dir, files_ in os.walk(path):
+                for item in files_:
+                    item = os.path.join(root, item)
+                    files.append((item, _md5(item), _size(item)))
+            return files
+
+        return []
+
+    def uses(self, path):
+        return False
+
+    def __eq__(self, other):
+        return (isinstance(other, EggInfoDistribution) and
+                self.path == other.path)
+
+    # See http://docs.python.org/reference/datamodel#object.__hash__
+    __hash__ = object.__hash__
+
+
+def distinfo_dirname(name, version):
+    """
+    The *name* and *version* parameters are converted into their
+    filename-escaped form, i.e. any ``'-'`` characters are replaced
+    with ``'_'`` other than the one in ``'dist-info'`` and the one
+    separating the name from the version number.
+
+    :parameter name: is converted to a standard distribution name by replacing
+                     any runs of non- alphanumeric characters with a single
+                     ``'-'``.
+    :type name: string
+    :parameter version: is converted to a standard version string. Spaces
+                        become dots, and all other non-alphanumeric characters
+                        (except dots) become dashes, with runs of multiple
+                        dashes condensed to a single dash.
+    :type version: string
+    :returns: directory name
+    :rtype: string"""
+    file_extension = '.dist-info'
+    name = name.replace('-', '_')
+    normalized_version = suggest_normalized_version(version)
+    # Because this is a lookup procedure, something will be returned even if
+    #   it is a version that cannot be normalized
+    if normalized_version is None:
+        # Unable to achieve normality?
+        normalized_version = version
+    return '-'.join([name, normalized_version]) + file_extension
+
+
+def get_distributions(use_egg_info=False, paths=None):
+    """
+    Provides an iterator that looks for ``.dist-info`` directories in
+    ``sys.path`` and returns :class:`Distribution` instances for each one of
+    them. If the parameters *use_egg_info* is ``True``, then the ``.egg-info``
+    files and directores are iterated as well.
+
+    :rtype: iterator of :class:`Distribution` and :class:`EggInfoDistribution`
+            instances
+    """
+    if paths is None:
+        paths = sys.path
+
+    if not _cache_enabled:
+        for dist in _yield_distributions(True, use_egg_info, paths):
+            yield dist
+    else:
+        _generate_cache(use_egg_info, paths)
+
+        for dist in _cache_path.values():
+            yield dist
+
+        if use_egg_info:
+            for dist in _cache_path_egg.values():
+                yield dist
+
+
+def get_distribution(name, use_egg_info=False, paths=None):
+    """
+    Scans all elements in ``sys.path`` and looks for all directories
+    ending with ``.dist-info``. Returns a :class:`Distribution`
+    corresponding to the ``.dist-info`` directory that contains the
+    ``METADATA`` that matches *name* for the *name* metadata field.
+    If no distribution exists with the given *name* and the parameter
+    *use_egg_info* is set to ``True``, then all files and directories ending
+    with ``.egg-info`` are scanned. A :class:`EggInfoDistribution` instance is
+    returned if one is found that has metadata that matches *name* for the
+    *name* metadata field.
+
+    This function only returns the first result found, as no more than one
+    value is expected. If the directory is not found, ``None`` is returned.
+
+    :rtype: :class:`Distribution` or :class:`EggInfoDistribution` or None
+    """
+    if paths is None:
+        paths = sys.path
+
+    if not _cache_enabled:
+        for dist in _yield_distributions(True, use_egg_info, paths):
+            if dist.name == name:
+                return dist
+    else:
+        _generate_cache(use_egg_info, paths)
+
+        if name in _cache_name:
+            return _cache_name[name][0]
+        elif use_egg_info and name in _cache_name_egg:
+            return _cache_name_egg[name][0]
+        else:
+            return None
+
+
+def obsoletes_distribution(name, version=None, use_egg_info=False):
+    """
+    Iterates over all distributions to find which distributions obsolete
+    *name*.
+
+    If a *version* is provided, it will be used to filter the results.
+    If the argument *use_egg_info* is set to ``True``, then ``.egg-info``
+    distributions will be considered as well.
+
+    :type name: string
+    :type version: string
+    :parameter name:
+    """
+    for dist in get_distributions(use_egg_info):
+        obsoleted = (dist.metadata['Obsoletes-Dist'] +
+                     dist.metadata['Obsoletes'])
+        for obs in obsoleted:
+            o_components = obs.split(' ', 1)
+            if len(o_components) == 1 or version is None:
+                if name == o_components[0]:
+                    yield dist
+                    break
+            else:
+                try:
+                    predicate = VersionPredicate(obs)
+                except ValueError:
+                    raise PackagingError(
+                        'distribution %r has ill-formed obsoletes field: '
+                        '%r' % (dist.name, obs))
+                if name == o_components[0] and predicate.match(version):
+                    yield dist
+                    break
+
+
+def provides_distribution(name, version=None, use_egg_info=False):
+    """
+    Iterates over all distributions to find which distributions provide *name*.
+    If a *version* is provided, it will be used to filter the results. Scans
+    all elements in ``sys.path``  and looks for all directories ending with
+    ``.dist-info``. Returns a :class:`Distribution`  corresponding to the
+    ``.dist-info`` directory that contains a ``METADATA`` that matches *name*
+    for the name metadata. If the argument *use_egg_info* is set to ``True``,
+    then all files and directories ending with ``.egg-info`` are considered
+    as well and returns an :class:`EggInfoDistribution` instance.
+
+    This function only returns the first result found, since no more than
+    one values are expected. If the directory is not found, returns ``None``.
+
+    :parameter version: a version specifier that indicates the version
+                        required, conforming to the format in ``PEP-345``
+
+    :type name: string
+    :type version: string
+    """
+    predicate = None
+    if not version is None:
+        try:
+            predicate = VersionPredicate(name + ' (' + version + ')')
+        except ValueError:
+            raise PackagingError('invalid name or version: %r, %r' %
+                                 (name, version))
+
+    for dist in get_distributions(use_egg_info):
+        provided = dist.metadata['Provides-Dist'] + dist.metadata['Provides']
+
+        for p in provided:
+            p_components = p.rsplit(' ', 1)
+            if len(p_components) == 1 or predicate is None:
+                if name == p_components[0]:
+                    yield dist
+                    break
+            else:
+                p_name, p_ver = p_components
+                if len(p_ver) < 2 or p_ver[0] != '(' or p_ver[-1] != ')':
+                    raise PackagingError(
+                        'distribution %r has invalid Provides field: %r' %
+                        (dist.name, p))
+                p_ver = p_ver[1:-1]  # trim off the parenthesis
+                if p_name == name and predicate.match(p_ver):
+                    yield dist
+                    break
+
+
+def get_file_users(path):
+    """
+    Iterates over all distributions to find out which distributions use
+    *path*.
+
+    :parameter path: can be a local absolute path or a relative
+                     ``'/'``-separated path.
+    :type path: string
+    :rtype: iterator of :class:`Distribution` instances
+    """
+    for dist in get_distributions():
+        if dist.uses(path):
+            yield dist
+
+
+def get_file_path(distribution_name, relative_path):
+    """Return the path to a resource file."""
+    dist = get_distribution(distribution_name)
+    if dist is not None:
+        return dist.get_resource_path(relative_path)
+    raise LookupError('no distribution named %r found' % distribution_name)
+
+
+def get_file(distribution_name, relative_path, *args, **kwargs):
+    """Open and return a resource file."""
+    return open(get_file_path(distribution_name, relative_path),
+                *args, **kwargs)
diff --git a/distutils2/depgraph.py b/distutils2/depgraph.py
--- a/distutils2/depgraph.py
+++ b/distutils2/depgraph.py
@@ -1,29 +1,34 @@
-"""Analyse the relationships between the distributions in the system
-and generate a dependency graph.
+"""Class and functions dealing with dependencies between distributions.
+
+This module provides a DependencyGraph class to represent the
+dependencies between distributions.  Auxiliary functions can generate a
+graph, find reverse dependencies, and print a graph in DOT format.
 """
+
 import sys
+
 from StringIO import StringIO
-from distutils2.errors import DistutilsError
+from distutils2.errors import PackagingError
 from distutils2.version import VersionPredicate, IrrationalVersionError
 
 __all__ = ['DependencyGraph', 'generate_graph', 'dependent_dists',
            'graph_to_dot']
 
 
-class DependencyGraph(object):
+class DependencyGraph:
     """
     Represents a dependency graph between distributions.
 
     The dependency relationships are stored in an ``adjacency_list`` that maps
     distributions to a list of ``(other, label)`` tuples where  ``other``
-    is a distribution and the edge is labelled with ``label`` (i.e. the version
+    is a distribution and the edge is labeled with ``label`` (i.e. the version
     specifier, if such was provided). Also, for more efficient traversal, for
     every distribution ``x``, a list of predecessors is kept in
     ``reverse_list[x]``. An edge from distribution ``a`` to
     distribution ``b`` means that ``a`` depends on ``b``. If any missing
-    depencies are found, they are stored in ``missing``, which is a dictionary
-    that maps distributions to a list of requirements that were not provided by
-    any other distributions.
+    dependencies are found, they are stored in ``missing``, which is a
+    dictionary that maps distributions to a list of requirements that were not
+    provided by any other distributions.
     """
 
     def __init__(self):
@@ -34,40 +39,40 @@
     def add_distribution(self, distribution):
         """Add the *distribution* to the graph.
 
-        :type distribution: :class:`pkgutil.Distribution` or
-                            :class:`pkgutil.EggInfoDistribution`
+        :type distribution: :class:`distutils2.database.Distribution` or
+                            :class:`distutils2.database.EggInfoDistribution`
         """
-        self.adjacency_list[distribution] = list()
-        self.reverse_list[distribution] = list()
-        self.missing[distribution] = list()
+        self.adjacency_list[distribution] = []
+        self.reverse_list[distribution] = []
+        self.missing[distribution] = []
 
     def add_edge(self, x, y, label=None):
         """Add an edge from distribution *x* to distribution *y* with the given
         *label*.
 
-        :type x: :class:`pkgutil.Distribution` or
-                 :class:`pkgutil.EggInfoDistribution`
-        :type y: :class:`pkgutil.Distribution` or
-                 :class:`pkgutil.EggInfoDistribution`
+        :type x: :class:`distutils2.database.Distribution` or
+                 :class:`distutils2.database.EggInfoDistribution`
+        :type y: :class:`distutils2.database.Distribution` or
+                 :class:`distutils2.database.EggInfoDistribution`
         :type label: ``str`` or ``None``
         """
         self.adjacency_list[x].append((y, label))
         # multiple edges are allowed, so be careful
-        if not x in self.reverse_list[y]:
+        if x not in self.reverse_list[y]:
             self.reverse_list[y].append(x)
 
     def add_missing(self, distribution, requirement):
         """
         Add a missing *requirement* for the given *distribution*.
 
-        :type distribution: :class:`pkgutil.Distribution` or
-                            :class:`pkgutil.EggInfoDistribution`
+        :type distribution: :class:`distutils2.database.Distribution` or
+                            :class:`distutils2.database.EggInfoDistribution`
         :type requirement: ``str``
         """
         self.missing[distribution].append(requirement)
 
     def _repr_dist(self, dist):
-        return '%s %s' % (dist.name, dist.metadata['Version'])
+        return '%r %s' % (dist.name, dist.version)
 
     def repr_node(self, dist, level=1):
         """Prints only a subgraph"""
@@ -77,7 +82,7 @@
             dist = self._repr_dist(other)
             if label is not None:
                 dist = '%s [%s]' % (dist, label)
-            output.append('    ' * level + '%s' % dist)
+            output.append('    ' * level + str(dist))
             suboutput = self.repr_node(other, level + 1)
             subs = suboutput.split('\n')
             output.extend(subs[1:])
@@ -86,7 +91,7 @@
     def __repr__(self):
         """Representation of the graph"""
         output = []
-        for dist, adjs in self.adjacency_list.iteritems():
+        for dist, adjs in self.adjacency_list.items():
             output.append(self.repr_node(dist))
         return '\n'.join(output)
 
@@ -102,46 +107,45 @@
     """
     disconnected = []
 
-    f.write("digraph dependencies {\n")
-    for dist, adjs in graph.adjacency_list.iteritems():
+    f.write(u"digraph dependencies {\n")
+    for dist, adjs in graph.adjacency_list.items():
         if len(adjs) == 0 and not skip_disconnected:
             disconnected.append(dist)
-        for (other, label) in adjs:
+        for other, label in adjs:
             if not label is None:
-                f.write('"%s" -> "%s" [label="%s"]\n' %
+                f.write(u'"%s" -> "%s" [label="%s"]\n' %
                                             (dist.name, other.name, label))
             else:
-                f.write('"%s" -> "%s"\n' % (dist.name, other.name))
+                f.write(u'"%s" -> "%s"\n' % (dist.name, other.name))
     if not skip_disconnected and len(disconnected) > 0:
-        f.write('subgraph disconnected {\n')
-        f.write('label = "Disconnected"\n')
-        f.write('bgcolor = red\n')
+        f.write(u'subgraph disconnected {\n')
+        f.write(u'label = "Disconnected"\n')
+        f.write(u'bgcolor = red\n')
 
         for dist in disconnected:
-            f.write('"%s"' % dist.name)
-            f.write('\n')
-        f.write('}\n')
-    f.write('}\n')
+            f.write(u'"%s"' % dist.name)
+            f.write(u'\n')
+        f.write(u'}\n')
+    f.write(u'}\n')
 
 
 def generate_graph(dists):
     """Generates a dependency graph from the given distributions.
 
     :parameter dists: a list of distributions
-    :type dists: list of :class:`pkgutil.Distribution` and
-                         :class:`pkgutil.EggInfoDistribution` instances
-    :rtype: an :class:`DependencyGraph` instance
+    :type dists: list of :class:`distutils2.database.Distribution` and
+                 :class:`distutils2.database.EggInfoDistribution` instances
+    :rtype: a :class:`DependencyGraph` instance
     """
     graph = DependencyGraph()
     provided = {}  # maps names to lists of (version, dist) tuples
-    dists = list(dists)  # maybe use generator_tools in future
 
     # first, build the graph and find out the provides
     for dist in dists:
         graph.add_distribution(dist)
         provides = (dist.metadata['Provides-Dist'] +
                     dist.metadata['Provides'] +
-                    ['%s (%s)' % (dist.name, dist.metadata['Version'])])
+                    ['%s (%s)' % (dist.name, dist.version)])
 
         for p in provides:
             comps = p.strip().rsplit(" ", 1)
@@ -150,10 +154,10 @@
             if len(comps) == 2:
                 version = comps[1]
                 if len(version) < 3 or version[0] != '(' or version[-1] != ')':
-                    raise DistutilsError('Distribution %s has ill formed' \
-                                         'provides field: %s' % (dist.name, p))
+                    raise PackagingError('distribution %r has ill-formed'
+                                         'provides field: %r' % (dist.name, p))
                 version = version[1:-1]  # trim off parenthesis
-            if not name in provided:
+            if name not in provided:
                 provided[name] = []
             provided[name].append((version, dist))
 
@@ -170,7 +174,7 @@
 
             name = predicate.name
 
-            if not name in provided:
+            if name not in provided:
                 graph.add_missing(dist, req)
             else:
                 matched = False
@@ -200,8 +204,9 @@
     :param dists: a list of distributions
     :param dist: a distribution, member of *dists* for which we are interested
     """
-    if not dist in dists:
-        raise ValueError('The given distribution is not a member of the list')
+    if dist not in dists:
+        raise ValueError('given distribution %r is not a member of the list' %
+                         dist.name)
     graph = generate_graph(dists)
 
     dep = [dist]  # dependent distributions
@@ -211,7 +216,7 @@
         node = fringe.pop()
         dep.append(node)
         for prev in graph.reverse_list[node]:
-            if not prev in dep:
+            if prev not in dep:
                 fringe.append(prev)
 
     dep.pop(0)  # remove dist from dep, was there to prevent infinite loops
@@ -219,7 +224,7 @@
 
 
 def main():
-    from distutils2._backport.pkgutil import get_distributions
+    from distutils2.database import get_distributions
     tempout = StringIO()
     try:
         old = sys.stderr
@@ -229,20 +234,23 @@
             graph = generate_graph(dists)
         finally:
             sys.stderr = old
-    except Exception, e:
+    except Exception:
+        e = sys.exc_info()[1]
         tempout.seek(0)
         tempout = tempout.read()
-        print('Could not generate the graph\n%s\n%s\n' % (tempout, str(e)))
+        print(u'Could not generate the graph')
+        print(tempout)
+        print(e)
         sys.exit(1)
 
-    for dist, reqs in graph.missing.iteritems():
+    for dist, reqs in graph.missing.items():
         if len(reqs) > 0:
-            print("Warning: Missing dependencies for %s: %s" % (dist.name,
-                                                       ", ".join(reqs)))
+            print(u"Warning: Missing dependencies for %r:" % dist.name,
+                  ", ".join(reqs))
     # XXX replace with argparse
     if len(sys.argv) == 1:
-        print('Dependency graph:')
-        print('    ' + repr(graph).replace('\n', '\n    '))
+        print(u'Dependency graph:')
+        print(u'   ', repr(graph).replace(u'\n', u'\n    '))
         sys.exit(0)
     elif len(sys.argv) > 1 and sys.argv[1] in ('-d', '--dot'):
         if len(sys.argv) > 2:
@@ -250,15 +258,12 @@
         else:
             filename = 'depgraph.dot'
 
-        f = open(filename, 'w')
-        try:
+        with open(filename, 'w') as f:
             graph_to_dot(graph, f, True)
-        finally:
-            f.close()
         tempout.seek(0)
         tempout = tempout.read()
         print(tempout)
-        print('Dot file written at "%s"' % filename)
+        print('Dot file written at %r' % filename)
         sys.exit(0)
     else:
         print('Supported option: -d [filename]')
diff --git a/distutils2/dist.py b/distutils2/dist.py
--- a/distutils2/dist.py
+++ b/distutils2/dist.py
@@ -1,17 +1,11 @@
-"""distutils.dist
-
-Provides the Distribution class, which represents the module distribution
-being built/installed/distributed.
-"""
-
+"""Class representing the distribution being built/installed/etc."""
 
 import os
 import re
-import warnings
-import logging
+import sys
 
-from distutils2.errors import (DistutilsOptionError, DistutilsArgError,
-                               DistutilsModuleError, DistutilsClassError)
+from distutils2.errors import (PackagingOptionError, PackagingArgError,
+                              PackagingModuleError, PackagingClassError)
 from distutils2.fancy_getopt import FancyGetopt
 from distutils2.util import strtobool, resolve_name
 from distutils2 import logger
@@ -19,7 +13,7 @@
 from distutils2.config import Config
 from distutils2.command import get_command_class, STANDARD_COMMANDS
 
-# Regex to define acceptable Distutils command names.  This is not *quite*
+# Regex to define acceptable Packaging command names.  This is not *quite*
 # the same as a Python NAME -- I don't allow leading underscores.  The fact
 # that they're very similar is no coincidence; the default naming scheme is
 # to look for a Python module named after the command.
@@ -32,14 +26,16 @@
    or: %(script)s cmd --help
 """
 
+
 def gen_usage(script_name):
     script = os.path.basename(script_name)
     return USAGE % {'script': script}
 
+
 class Distribution(object):
-    """The core of the Distutils.  Most of the work hiding behind 'setup'
+    """The core of the Packaging.  Most of the work hiding behind 'setup'
     is really done within a Distribution instance, which farms the work out
-    to the Distutils commands specified on the command line.
+    to the Packaging commands specified on the command line.
 
     Setup scripts will almost never instantiate Distribution directly,
     unless the 'setup()' function is totally inadequate to their needs.
@@ -52,33 +48,31 @@
 
     # 'global_options' describes the command-line options that may be
     # supplied to the setup script prior to any actual commands.
-    # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of
+    # Eg. "pysetup -n" or "pysetup --dry-run" both take advantage of
     # these global options.  This list should be kept to a bare minimum,
     # since every global option is also valid as a command option -- and we
     # don't want to pollute the commands with too many options that they
     # have minimal control over.
-    # The fourth entry for verbose means that it can be repeated.
-    global_options = [('verbose', 'v', "run verbosely (default)", 1),
-                      ('quiet', 'q', "run quietly (turns verbosity off)"),
-                      ('dry-run', 'n', "don't actually do anything"),
-                      ('help', 'h', "show detailed help message"),
-                      ('no-user-cfg', None,
-                       'ignore pydistutils.cfg in your home directory'),
+    global_options = [
+        ('dry-run', 'n', "don't actually do anything"),
+        ('help', 'h', "show detailed help message"),
+        ('no-user-cfg', None, 'ignore pydistutils.cfg in your home directory'),
     ]
 
     # 'common_usage' is a short (2-3 line) string describing the common
     # usage of the setup script.
-    common_usage = """\
+    common_usage = u"""\
 Common commands: (see '--help-commands' for more)
 
-  setup.py build      will build the package underneath 'build/'
-  setup.py install    will install the package
+  pysetup run build      will build the package underneath 'build/'
+  pysetup run install    will install the package
 """
 
     # options that are not propagated to the commands
     display_options = [
         ('help-commands', None,
          "list all available commands"),
+        # XXX this is obsoleted by the pysetup metadata action
         ('name', None,
          "print package name"),
         ('version', 'V',
@@ -127,7 +121,7 @@
     display_option_names = [x[0].replace('-', '_') for x in display_options]
 
     # negative options are options that exclude other options
-    negative_opt = {'quiet': 'verbose'}
+    negative_opt = {}
 
     # -- Creation/initialization methods -------------------------------
     def __init__(self, attrs=None):
@@ -142,11 +136,10 @@
         """
 
         # Default values for our command-line options
-        self.verbose = 1
-        self.dry_run = 0
-        self.help = 0
+        self.dry_run = False
+        self.help = False
         for attr in self.display_option_names:
-            setattr(self, attr, 0)
+            setattr(self, attr, False)
 
         # Store the configuration
         self.config = Config(self)
@@ -237,21 +230,21 @@
             options = attrs.get('options')
             if options is not None:
                 del attrs['options']
-                for (command, cmd_options) in options.iteritems():
+                for command, cmd_options in options.items():
                     opt_dict = self.get_option_dict(command)
-                    for (opt, val) in cmd_options.iteritems():
+                    for opt, val in cmd_options.items():
                         opt_dict[opt] = ("setup script", val)
 
             # Now work on the rest of the attributes.  Any attribute that's
             # not already defined is invalid!
-            for key, val in attrs.iteritems():
+            for key, val in attrs.items():
                 if self.metadata.is_metadata_field(key):
                     self.metadata[key] = val
                 elif hasattr(self, key):
                     setattr(self, key, val)
                 else:
-                    msg = "Unknown distribution option: %r" % key
-                    warnings.warn(msg)
+                    logger.warning(
+                        'unknown argument given to Distribution: %r', key)
 
         # no-user-cfg is handled before other command line args
         # because other args override the config files, and this
@@ -292,24 +285,23 @@
             commands = sorted(self.command_options)
 
         if header is not None:
-            self.announce(indent + header)
+            logger.info(indent + header)
             indent = indent + "  "
 
         if not commands:
-            self.announce(indent + "no commands known yet")
+            logger.info(indent + "no commands known yet")
             return
 
         for cmd_name in commands:
             opt_dict = self.command_options.get(cmd_name)
             if opt_dict is None:
-                self.announce(indent +
-                              "no option dict for %r command" % cmd_name)
+                logger.info(indent + "no option dict for %r command",
+                            cmd_name)
             else:
-                self.announce(indent +
-                              "option dict for %r command:" % cmd_name)
+                logger.info(indent + "option dict for %r command:", cmd_name)
                 out = pformat(opt_dict)
                 for line in out.split('\n'):
-                    self.announce(indent + "  " + line)
+                    logger.info(indent + "  " + line)
 
     # -- Config file finding/parsing methods ---------------------------
     # XXX to be removed
@@ -326,15 +318,15 @@
         'script_args' instance attribute (which defaults to 'sys.argv[1:]'
         -- see 'setup()' in run.py).  This list is first processed for
         "global options" -- options that set attributes of the Distribution
-        instance.  Then, it is alternately scanned for Distutils commands
+        instance.  Then, it is alternately scanned for Packaging commands
         and options for that command.  Each new command terminates the
         options for the previous command.  The allowed options for a
         command are determined by the 'user_options' attribute of the
         command class -- thus, we have to be able to load command classes
         in order to parse the command line.  Any error in that 'options'
-        attribute raises DistutilsGetoptError; any error on the
-        command line raises DistutilsArgError.  If no Distutils commands
-        were found on the command line, raises DistutilsArgError.  Return
+        attribute raises PackagingGetoptError; any error on the
+        command line raises PackagingArgError.  If no Packaging commands
+        were found on the command line, raises PackagingArgError.  Return
         true if command line was successfully parsed and we should carry
         on with executing commands; false if no errors but we shouldn't
         execute commands (currently, this only happens if user asks for
@@ -360,14 +352,6 @@
         args = parser.getopt(args=self.script_args, object=self)
         option_order = parser.get_option_order()
 
-        handler = logging.StreamHandler()
-        logger.addHandler(handler)
-
-        if self.verbose:
-            handler.setLevel(logging.DEBUG)
-        else:
-            handler.setLevel(logging.INFO)
-
         # for display options we return immediately
         if self.handle_display_options(option_order):
             return
@@ -378,8 +362,8 @@
                 return
 
         # Handle the cases of --help as a "global" option, ie.
-        # "setup.py --help" and "setup.py --help command ...".  For the
-        # former, we show global options (--verbose, --dry-run, etc.)
+        # "pysetup run --help" and "pysetup run --help command ...".  For the
+        # former, we show global options (--dry-run, etc.)
         # and display-only options (--name, --version, etc.); for the
         # latter, we omit the display-only options and show help for
         # each command listed on the command line.
@@ -419,24 +403,24 @@
         # it takes.
         try:
             cmd_class = get_command_class(command)
-        except DistutilsModuleError, msg:
-            raise DistutilsArgError(msg)
+        except PackagingModuleError:
+            raise PackagingArgError(sys.exc_info()[1])
 
-        # XXX We want to push this in distutils.command
+        # XXX We want to push this in distutils2.command
         #
         # Require that the command class be derived from Command -- want
         # to be sure that the basic "command" interface is implemented.
         for meth in ('initialize_options', 'finalize_options', 'run'):
             if hasattr(cmd_class, meth):
                 continue
-            raise DistutilsClassError(
+            raise PackagingClassError(
                 'command %r must implement %r' % (cmd_class, meth))
 
         # Also make sure that the command object provides a list of its
         # known options.
         if not (hasattr(cmd_class, 'user_options') and
                 isinstance(cmd_class.user_options, list)):
-            raise DistutilsClassError(
+            raise PackagingClassError(
                 "command class %s must provide "
                 "'user_options' attribute (a list of tuples)" % cmd_class)
 
@@ -451,7 +435,7 @@
         # format (tuple of four) so we need to preprocess them here.
         if (hasattr(cmd_class, 'help_options') and
             isinstance(cmd_class.help_options, list)):
-            help_options = fix_help_options(cmd_class.help_options)
+            help_options = cmd_class.help_options[:]
         else:
             help_options = []
 
@@ -461,21 +445,22 @@
                                 cmd_class.user_options +
                                 help_options)
         parser.set_negative_aliases(negative_opt)
-        (args, opts) = parser.getopt(args[1:])
+        args, opts = parser.getopt(args[1:])
         if hasattr(opts, 'help') and opts.help:
-            self._show_help(parser, display_options=0, commands=[cmd_class])
+            self._show_help(parser, display_options=False,
+                            commands=[cmd_class])
             return
 
         if (hasattr(cmd_class, 'help_options') and
             isinstance(cmd_class.help_options, list)):
-            help_option_found = 0
-            for (help_option, short, desc, func) in cmd_class.help_options:
+            help_option_found = False
+            for help_option, short, desc, func in cmd_class.help_options:
                 if hasattr(opts, help_option.replace('-', '_')):
-                    help_option_found = 1
+                    help_option_found = True
                     if hasattr(func, '__call__'):
                         func()
                     else:
-                        raise DistutilsClassError(
+                        raise PackagingClassError(
                             "invalid help function %r for help option %r: "
                             "must be a callable object (function, etc.)"
                             % (func, help_option))
@@ -486,7 +471,7 @@
         # Put the options from the command line into their official
         # holding pen, the 'command_options' dictionary.
         opt_dict = self.get_option_dict(command)
-        for (name, value) in vars(opts).iteritems():
+        for name, value in vars(opts).items():
             opt_dict[name] = ("command line", value)
 
         return args
@@ -502,7 +487,7 @@
         else:
             self.convert_2to3_doctests = []
 
-    def _show_help(self, parser, global_options=1, display_options=1,
+    def _show_help(self, parser, global_options=True, display_options=True,
                    commands=[]):
         """Show help for the setup script command line in the form of
         several lists of command-line options.  'parser' should be a
@@ -511,7 +496,7 @@
         generate the correct help text.
 
         If 'global_options' is true, lists the global options:
-        --verbose, --dry-run, etc.  If 'display_options' is true, lists
+        --dry-run, etc.  If 'display_options' is true, lists
         the "display-only" options: --name, --version, etc.  Finally,
         lists per-command help for every command name or command class
         in 'commands'.
@@ -526,14 +511,14 @@
                 options = self.global_options
             parser.set_option_table(options)
             parser.print_help(self.common_usage + "\nGlobal options:")
-            print('')
+            print(u'')
 
         if display_options:
             parser.set_option_table(self.display_options)
             parser.print_help(
                 "Information display options (just display " +
                 "information, ignore any commands)")
-            print('')
+            print(u'')
 
         for command in self.commands:
             if isinstance(command, type) and issubclass(command, Command):
@@ -542,12 +527,11 @@
                 cls = get_command_class(command)
             if (hasattr(cls, 'help_options') and
                 isinstance(cls.help_options, list)):
-                parser.set_option_table(cls.user_options +
-                                        fix_help_options(cls.help_options))
+                parser.set_option_table(cls.user_options + cls.help_options)
             else:
                 parser.set_option_table(cls.user_options)
             parser.print_help("Options for %r command:" % cls.__name__)
-            print('')
+            print(u'')
 
         print(gen_usage(self.script_name))
 
@@ -562,30 +546,30 @@
         # we ignore "foo bar").
         if self.help_commands:
             self.print_commands()
-            print('')
+            print()
             print(gen_usage(self.script_name))
             return 1
 
         # If user supplied any of the "display metadata" options, then
         # display that metadata in the order in which the user supplied the
         # metadata options.
-        any_display_options = 0
-        is_display_option = {}
+        any_display_options = False
+        is_display_option = set()
         for option in self.display_options:
-            is_display_option[option[0]] = 1
+            is_display_option.add(option[0])
 
         for opt, val in option_order:
-            if val and is_display_option.get(opt):
+            if val and opt in is_display_option:
                 opt = opt.replace('-', '_')
                 value = self.metadata[opt]
-                if opt in ['keywords', 'platform']:
+                if opt in ('keywords', 'platform'):
                     print(','.join(value))
                 elif opt in ('classifier', 'provides', 'requires',
                              'obsoletes'):
                     print('\n'.join(value))
                 else:
                     print(value)
-                any_display_options = 1
+                any_display_options = True
 
         return any_display_options
 
@@ -630,14 +614,14 @@
                                 "Standard commands",
                                 max_length)
         if extra_commands:
-            print
+            print()
             self.print_command_list(extra_commands,
                                     "Extra commands",
                                     max_length)
 
     # -- Command class/object methods ----------------------------------
 
-    def get_command_obj(self, command, create=1):
+    def get_command_obj(self, command, create=True):
         """Return the command object for 'command'.  Normally this object
         is cached on a previous call to 'get_command_obj()'; if no command
         object for 'command' is in the cache, then we either create and
@@ -660,7 +644,6 @@
             options = self.command_options.get(command)
             if options:
                 self._set_command_options(cmd_obj, options)
-
         return cmd_obj
 
     def _set_command_options(self, command_obj, option_dict=None):
@@ -678,7 +661,7 @@
 
         logger.debug("  setting options for %r command:", command_name)
 
-        for (option, (source, value)) in option_dict.iteritems():
+        for option, (source, value) in option_dict.items():
             logger.debug("    %s = %s (from %s)", option, value, source)
             try:
                 bool_opts = [x.replace('-', '_')
@@ -691,7 +674,7 @@
                 neg_opt = {}
 
             try:
-                is_string = isinstance(value, str)
+                is_string = isinstance(value, basestring)
                 if option in neg_opt and is_string:
                     setattr(command_obj, neg_opt[option], not strtobool(value))
                 elif option in bool_opts and is_string:
@@ -699,13 +682,13 @@
                 elif hasattr(command_obj, option):
                     setattr(command_obj, option, value)
                 else:
-                    raise DistutilsOptionError(
+                    raise PackagingOptionError(
                         "error in %s: command %r has no such option %r" %
                         (source, command_name, option))
-            except ValueError, msg:
-                raise DistutilsOptionError(msg)
+            except ValueError:
+                raise PackagingOptionError(sys.exc_info()[1])
 
-    def get_reinitialized_command(self, command, reinit_subcommands=0):
+    def get_reinitialized_command(self, command, reinit_subcommands=False):
         """Reinitializes a command to the state it was in when first
         returned by 'get_command_obj()': ie., initialized but not yet
         finalized.  This provides the opportunity to sneak option
@@ -734,8 +717,8 @@
         if not command.finalized:
             return command
         command.initialize_options()
-        command.finalized = 0
         self.have_run[command_name] = 0
+        command.finalized = False
         self._set_command_options(command)
 
         if reinit_subcommands:
@@ -746,9 +729,6 @@
 
     # -- Methods that operate on the Distribution ----------------------
 
-    def announce(self, msg, level=logging.INFO):
-        logger.log(level, msg)
-
     def run_commands(self):
         """Run each command that was seen on the setup script command line.
         Uses the list of commands found and cache of command objects
@@ -796,17 +776,17 @@
         if hooks is None:
             return
 
-        for hook in hooks.itervalues():
+        for hook in hooks.values():
             if isinstance(hook, basestring):
                 try:
                     hook_obj = resolve_name(hook)
-                except ImportError, e:
-                    raise DistutilsModuleError(e)
+                except ImportError:
+                    raise PackagingModuleError(sys.exc_info()[1])
             else:
                 hook_obj = hook
 
             if not hasattr(hook_obj, '__call__'):
-                raise DistutilsOptionError('hook %r is not callable' % hook)
+                raise PackagingOptionError('hook %r is not callable' % hook)
 
             logger.info('running %s %s for command %s',
                         hook_kind, hook, cmd_obj.get_command_name())
@@ -838,15 +818,3 @@
         return (self.has_pure_modules() and
                 not self.has_ext_modules() and
                 not self.has_c_libraries())
-
-
-# XXX keep for compat or remove?
-
-def fix_help_options(options):
-    """Convert a 4-tuple 'help_options' list as found in various command
-    classes to the 3-tuple form required by FancyGetopt.
-    """
-    new_options = []
-    for help_tuple in options:
-        new_options.append(help_tuple[0:3])
-    return new_options
diff --git a/distutils2/errors.py b/distutils2/errors.py
--- a/distutils2/errors.py
+++ b/distutils2/errors.py
@@ -1,84 +1,82 @@
-"""distutils.errors
+"""Exceptions used throughout the package.
 
-Provides exceptions used by the Distutils modules.  Note that Distutils
-modules may raise standard exceptions; in particular, SystemExit is
-usually raised for errors that are obviously the end-user's fault
-(eg. bad command-line arguments).
+Submodules of distutils2 may raise exceptions defined in this module as
+well as standard exceptions; in particular, SystemExit is usually raised
+for errors that are obviously the end-user's fault (e.g. bad
+command-line arguments).
+"""
 
-This module is safe to use in "from ... import *" mode; it only exports
-symbols whose names start with "Distutils" and end with "Error"."""
 
+class PackagingError(Exception):
+    """The root of all Packaging evil."""
 
-class DistutilsError(Exception):
-    """The root of all Distutils evil."""
 
-
-class DistutilsModuleError(DistutilsError):
+class PackagingModuleError(PackagingError):
     """Unable to load an expected module, or to find an expected class
     within some module (in particular, command modules and classes)."""
 
 
-class DistutilsClassError(DistutilsError):
+class PackagingClassError(PackagingError):
     """Some command class (or possibly distribution class, if anyone
     feels a need to subclass Distribution) is found not to be holding
     up its end of the bargain, ie. implementing some part of the
     "command "interface."""
 
 
-class DistutilsGetoptError(DistutilsError):
+class PackagingGetoptError(PackagingError):
     """The option table provided to 'fancy_getopt()' is bogus."""
 
 
-class DistutilsArgError(DistutilsError):
+class PackagingArgError(PackagingError):
     """Raised by fancy_getopt in response to getopt.error -- ie. an
     error in the command line usage."""
 
 
-class DistutilsFileError(DistutilsError):
+class PackagingFileError(PackagingError):
     """Any problems in the filesystem: expected file not found, etc.
     Typically this is for problems that we detect before IOError or
     OSError could be raised."""
 
 
-class DistutilsOptionError(DistutilsError):
+class PackagingOptionError(PackagingError):
     """Syntactic/semantic errors in command options, such as use of
     mutually conflicting options, or inconsistent options,
     badly-spelled values, etc.  No distinction is made between option
     values originating in the setup script, the command line, config
     files, or what-have-you -- but if we *know* something originated in
-    the setup script, we'll raise DistutilsSetupError instead."""
+    the setup script, we'll raise PackagingSetupError instead."""
 
 
-class DistutilsSetupError(DistutilsError):
+class PackagingSetupError(PackagingError):
     """For errors that can be definitely blamed on the setup script,
     such as invalid keyword arguments to 'setup()'."""
 
 
-class DistutilsPlatformError(DistutilsError):
+class PackagingPlatformError(PackagingError):
     """We don't know how to do something on the current platform (but
     we do know how to do it on some platform) -- eg. trying to compile
     C files on a platform not supported by a CCompiler subclass."""
 
 
-class DistutilsExecError(DistutilsError):
+class PackagingExecError(PackagingError):
     """Any problems executing an external program (such as the C
     compiler, when compiling C files)."""
 
 
-class DistutilsInternalError(DistutilsError):
+class PackagingInternalError(PackagingError):
     """Internal inconsistencies or impossibilities (obviously, this
     should never be seen if the code is working!)."""
 
 
-class DistutilsTemplateError(DistutilsError):
+class PackagingTemplateError(PackagingError):
     """Syntax error in a file list template."""
 
 
-class DistutilsByteCompileError(DistutilsError):
+class PackagingByteCompileError(PackagingError):
     """Byte compile error."""
 
 
-class DistutilsIndexError(DistutilsError):
+class PackagingPyPIError(PackagingError):
     """Any problem occuring during using the indexes."""
 
 
@@ -109,15 +107,15 @@
     """Attempt to process an unknown file type."""
 
 
-class MetadataMissingError(DistutilsError):
+class MetadataMissingError(PackagingError):
     """A required metadata is missing"""
 
 
-class MetadataConflictError(DistutilsError):
+class MetadataConflictError(PackagingError):
     """Attempt to read or write metadata fields that are conflictual."""
 
 
-class MetadataUnrecognizedVersionError(DistutilsError):
+class MetadataUnrecognizedVersionError(PackagingError):
     """Unknown metadata version number."""
 
 
diff --git a/distutils2/fancy_getopt.py b/distutils2/fancy_getopt.py
--- a/distutils2/fancy_getopt.py
+++ b/distutils2/fancy_getopt.py
@@ -1,22 +1,23 @@
-"""distutils.fancy_getopt
+"""Command line parsing machinery.
 
-Wrapper around the standard getopt module that provides the following
-additional features:
+The FancyGetopt class is a Wrapper around the getopt module that
+provides the following additional features:
   * short and long options are tied together
   * options have help strings, so fancy_getopt could potentially
     create a complete usage summary
-  * options set attributes of a passed-in object
+  * options set attributes of a passed-in object.
+
+It is used under the hood by the command classes.  Do not use directly.
 """
 
+import getopt
+import re
+import sys
+import textwrap
 
-import sys
-import string
-import re
-import getopt
-import textwrap
-from distutils2.errors import DistutilsGetoptError, DistutilsArgError
+from distutils2.errors import PackagingGetoptError, PackagingArgError
 
-# Much like command_re in distutils.core, this is close to but not quite
+# Much like command_re in distutils2.core, this is close to but not quite
 # the same as a Python NAME -- except, in the spirit of most GNU
 # utilities, we use '-' in place of '_'.  (The spirit of LISP lives on!)
 # The similarities to NAME are again not a coincidence...
@@ -38,6 +39,7 @@
         --quiet is the "negative alias" of --verbose, then "--quiet"
         on the command line sets 'verbose' to false
     """
+
     def __init__(self, option_table=None):
 
         # The option table is (currently) a list of tuples.  The
@@ -90,7 +92,7 @@
 
     def add_option(self, long_option, short_option=None, help_string=None):
         if long_option in self.option_index:
-            raise DistutilsGetoptError(
+            raise PackagingGetoptError(
                   "option conflict: already an option '%s'" % long_option)
         else:
             option = (long_option, short_option, help_string)
@@ -104,13 +106,13 @@
 
     def _check_alias_dict(self, aliases, what):
         assert isinstance(aliases, dict)
-        for (alias, opt) in aliases.iteritems():
+        for alias, opt in aliases.items():
             if alias not in self.option_index:
-                raise DistutilsGetoptError(
+                raise PackagingGetoptError(
                       ("invalid %s '%s': "
                        "option '%s' not defined") % (what, alias, alias))
             if opt not in self.option_index:
-                raise DistutilsGetoptError(
+                raise PackagingGetoptError(
                       ("invalid %s '%s': "
                        "aliased option '%s' not defined") % (what, alias, opt))
 
@@ -139,76 +141,76 @@
 
         for option in self.option_table:
             if len(option) == 3:
-                long, short, help = option
+                longopt, short, help = option
                 repeat = 0
             elif len(option) == 4:
-                long, short, help, repeat = option
+                longopt, short, help, repeat = option
             else:
                 # the option table is part of the code, so simply
                 # assert that it is correct
                 raise ValueError("invalid option tuple: %r" % option)
 
             # Type- and value-check the option names
-            if not isinstance(long, str) or len(long) < 2:
-                raise DistutilsGetoptError(
+            if not isinstance(longopt, basestring) or len(longopt) < 2:
+                raise PackagingGetoptError(
                       ("invalid long option '%s': "
-                       "must be a string of length >= 2") % long)
+                       "must be a string of length >= 2") % longopt)
 
             if (not ((short is None) or
-                     (isinstance(short, str) and len(short) == 1))):
-                raise DistutilsGetoptError(
+                     (isinstance(short, basestring) and len(short) == 1))):
+                raise PackagingGetoptError(
                       ("invalid short option '%s': "
-                       "must a single character or None") % short)
+                       "must be a single character or None") % short)
 
-            self.repeat[long] = repeat
-            self.long_opts.append(long)
+            self.repeat[longopt] = repeat
+            self.long_opts.append(longopt)
 
-            if long[-1] == '=':             # option takes an argument?
+            if longopt[-1] == '=':             # option takes an argument?
                 if short:
                     short = short + ':'
-                long = long[0:-1]
-                self.takes_arg[long] = 1
+                longopt = longopt[0:-1]
+                self.takes_arg[longopt] = 1
             else:
 
                 # Is option is a "negative alias" for some other option (eg.
                 # "quiet" == "!verbose")?
-                alias_to = self.negative_alias.get(long)
+                alias_to = self.negative_alias.get(longopt)
                 if alias_to is not None:
                     if self.takes_arg[alias_to]:
-                        raise DistutilsGetoptError(
+                        raise PackagingGetoptError(
                               ("invalid negative alias '%s': "
                                "aliased option '%s' takes a value") % \
-                               (long, alias_to))
+                               (longopt, alias_to))
 
-                    self.long_opts[-1] = long   # XXX redundant?!
-                    self.takes_arg[long] = 0
+                    self.long_opts[-1] = longopt   # XXX redundant?!
+                    self.takes_arg[longopt] = 0
 
                 else:
-                    self.takes_arg[long] = 0
+                    self.takes_arg[longopt] = 0
 
             # If this is an alias option, make sure its "takes arg" flag is
             # the same as the option it's aliased to.
-            alias_to = self.alias.get(long)
+            alias_to = self.alias.get(longopt)
             if alias_to is not None:
-                if self.takes_arg[long] != self.takes_arg[alias_to]:
-                    raise DistutilsGetoptError(
+                if self.takes_arg[longopt] != self.takes_arg[alias_to]:
+                    raise PackagingGetoptError(
                           ("invalid alias '%s': inconsistent with "
                            "aliased option '%s' (one of them takes a value, "
-                           "the other doesn't") % (long, alias_to))
+                           "the other doesn't") % (longopt, alias_to))
 
             # Now enforce some bondage on the long option name, so we can
             # later translate it to an attribute name on some object.  Have
             # to do this a bit late to make sure we've removed any trailing
             # '='.
-            if not longopt_re.match(long):
-                raise DistutilsGetoptError(
+            if not longopt_re.match(longopt):
+                raise PackagingGetoptError(
                       ("invalid long option name '%s' " +
-                       "(must be letters, numbers, hyphens only") % long)
+                       "(must be letters, numbers, hyphens only") % longopt)
 
-            self.attr_name[long] = long.replace('-', '_')
+            self.attr_name[longopt] = longopt.replace('-', '_')
             if short:
                 self.short_opts.append(short)
-                self.short2long[short[0]] = long
+                self.short2long[short[0]] = longopt
 
     def getopt(self, args=None, object=None):
         """Parse command-line options in args. Store as attributes on object.
@@ -231,11 +233,12 @@
 
         self._grok_option_table()
 
-        short_opts = string.join(self.short_opts)
+        short_opts = ' '.join(self.short_opts)
+
         try:
             opts, args = getopt.getopt(args, short_opts, self.long_opts)
-        except getopt.error, msg:
-            raise DistutilsArgError(msg)
+        except getopt.error:
+            raise PackagingArgError(sys.exc_info()[1])
 
         for opt, val in opts:
             if len(opt) == 2 and opt[0] == '-':   # it's a short option
@@ -278,6 +281,8 @@
         """
         if self.option_order is None:
             raise RuntimeError("'getopt()' hasn't been called yet")
+        else:
+            return self.option_order
 
         return self.option_order
 
@@ -291,10 +296,10 @@
         # First pass: determine maximum length of long option names
         max_opt = 0
         for option in self.option_table:
-            long = option[0]
+            longopt = option[0]
             short = option[1]
-            l = len(long)
-            if long[-1] == '=':
+            l = len(longopt)
+            if longopt[-1] == '=':
                 l = l - 1
             if short is not None:
                 l = l + 5                   # " (-x)" where short == 'x'
@@ -334,22 +339,20 @@
             lines = ['Option summary:']
 
         for option in self.option_table:
-            long, short, help = option[:3]
+            longopt, short, help = option[:3]
             text = textwrap.wrap(help, text_width)
-            if long[-1] == '=':
-                long = long[0:-1]
 
             # Case 1: no short option at all (makes life easy)
             if short is None:
                 if text:
-                    lines.append("  --%-*s  %s" % (max_opt, long, text[0]))
+                    lines.append("  --%-*s  %s" % (max_opt, longopt, text[0]))
                 else:
-                    lines.append("  --%-*s  " % (max_opt, long))
+                    lines.append("  --%-*s  " % (max_opt, longopt))
 
             # Case 2: we have a short option, so we have to include it
             # just after the long option
             else:
-                opt_names = "%s (-%s)" % (long, short)
+                opt_names = "%s (-%s)" % (longopt, short)
                 if text:
                     lines.append("  --%-*s  %s" %
                                  (max_opt, opt_names, text[0]))
@@ -365,7 +368,7 @@
         if file is None:
             file = sys.stdout
         for line in self.generate_help(header):
-            file.write(line + "\n")
+            file.write(line + u"\n")
 
 
 def fancy_getopt(options, negative_opt, object, args):
@@ -374,71 +377,6 @@
     return parser.getopt(args, object)
 
 
-if 'maketrans' in str.__dict__ :
-    # Python 3.2+
-    WS_TRANS = str.maketrans(string.whitespace, ' ' * len(string.whitespace))
-else :
-    # Depreciated syntax
-    WS_TRANS = string.maketrans(string.whitespace, ' ' * len(string.whitespace))
-
-
-def wrap_text(text, width):
-    """wrap_text(text : string, width : int) -> [string]
-
-    Split 'text' into multiple lines of no more than 'width' characters
-    each, and return the list of strings that results.
-    """
-
-    if text is None:
-        return []
-    if len(text) <= width:
-        return [text]
-
-    text = string.expandtabs(text)
-    text = string.translate(text, WS_TRANS)
-    chunks = re.split(r'( +|-+)', text)
-    chunks = filter(None, chunks)      # ' - ' results in empty strings
-    lines = []
-
-    while chunks:
-
-        cur_line = []                   # list of chunks (to-be-joined)
-        cur_len = 0                     # length of current line
-
-        while chunks:
-            l = len(chunks[0])
-            if cur_len + l <= width:    # can squeeze (at least) this chunk in
-                cur_line.append(chunks[0])
-                del chunks[0]
-                cur_len = cur_len + l
-            else:                       # this line is full
-                # drop last chunk if all space
-                if cur_line and cur_line[-1][0] == ' ':
-                    del cur_line[-1]
-                break
-
-        if chunks:                      # any chunks left to process?
-
-            # if the current line is still empty, then we had a single
-            # chunk that's too big too fit on a line -- so we break
-            # down and break it up at the line width
-            if cur_len == 0:
-                cur_line.append(chunks[0][0:width])
-                chunks[0] = chunks[0][width:]
-
-            # all-whitespace chunks at the end of a line can be discarded
-            # (and we know from the re.split above that if a chunk has
-            # *any* whitespace, it is *all* whitespace)
-            if chunks[0][0] == ' ':
-                del chunks[0]
-
-        # and store this line in the list-of-all-lines -- as a single
-        # string, of course!
-        lines.append(string.join(cur_line, ''))
-
-    return lines
-
-
 class OptionDummy(object):
     """Dummy class just used as a place to hold command-line option
     values as instance attributes."""
diff --git a/distutils2/install.py b/distutils2/install.py
--- a/distutils2/install.py
+++ b/distutils2/install.py
@@ -1,34 +1,37 @@
-"""Provides installations scripts.
+"""Building blocks for installers.
 
-The goal of this script is to install a release from the indexes (eg.
-PyPI), including the dependencies of the releases if needed.
+When used as a script, this module installs a release thanks to info
+obtained from an index (e.g. PyPI), with dependencies.
 
-It uses the work made in pkgutil and by the index crawlers to browse the
-installed distributions, and rely on the instalation commands to install.
+This is a higher-level module built on distutils2.database and
+distutils2.pypi.
 """
-import shutil
 import os
 import sys
 import stat
 import errno
-import itertools
+import shutil
 import logging
 import tempfile
+from sysconfig import get_config_var, get_path, is_python_build
 
 from distutils2 import logger
-from distutils2._backport.pkgutil import get_distributions
-from distutils2._backport.pkgutil import get_distribution
-from distutils2._backport.sysconfig import get_config_var
+from distutils2.dist import Distribution
+from distutils2.util import (_is_archive_file, ask, get_install_method,
+                            egginfo_to_distinfo, unpack_archive)
+from distutils2.pypi import wrapper
+from distutils2.version import get_version_predicate
+from distutils2.database import get_distributions, get_distribution
 from distutils2.depgraph import generate_graph
-from distutils2.index import wrapper
-from distutils2.index.errors import ProjectNotFound, ReleaseNotFound
-from distutils2.errors import (DistutilsError, InstallationException,
-                               InstallationConflict)
-from distutils2.version import get_version_predicate
+
+from distutils2.errors import (PackagingError, InstallationException,
+                              InstallationConflict, CCompilerError)
+from distutils2.pypi.errors import ProjectNotFound, ReleaseNotFound
+from distutils2 import database
 
 
 __all__ = ['install_dists', 'install_from_infos', 'get_infos', 'remove',
-           'install']
+           'install', 'install_local_project']
 
 
 def _move_files(files, destination):
@@ -40,42 +43,53 @@
     :param files: a list of files to move.
     :param destination: the destination directory to put on the files.
     """
+
     for old in files:
-        # not using os.path.join() because basename() might not be
-        # unique in destination
-        new = "%s%s" % (destination, old)
-
+        filename = os.path.split(old)[-1]
+        new = os.path.join(destination, filename)
         # try to make the paths.
         try:
             os.makedirs(os.path.dirname(new))
-        except OSError, e:
-            if e.errno == errno.EEXIST:
-                pass
-            else:
-                raise e
+        except OSError:
+            e = sys.exc_info()[1]
+            if e.errno != errno.EEXIST:
+                raise
         os.rename(old, new)
         yield old, new
 
 
-def _run_d1_install(archive_dir, path):
+def _run_distutils_install(path):
     # backward compat: using setuptools or plain-distutils
-    cmd = '%s setup.py install --root=%s --record=%s'
-    setup_py = os.path.join(archive_dir, 'setup.py')
-    if 'setuptools' in open(setup_py).read():
-        cmd += ' --single-version-externally-managed'
-
-    # how to place this file in the egg-info dir
-    # for non-distutils2 projects ?
-    record_file = os.path.join(archive_dir, 'RECORD')
-    os.system(cmd % (sys.executable, path, record_file))
+    cmd = '%s setup.py install --record=%s'
+    record_file = os.path.join(path, 'RECORD')
+    os.system(cmd % (sys.executable, record_file))
     if not os.path.exists(record_file):
         raise ValueError('failed to install')
-    return open(record_file).read().split('\n')
+    else:
+        egginfo_to_distinfo(record_file, remove_egginfo=True)
 
 
-def _run_d2_install(archive_dir, path):
-    # using our own install command
-    raise NotImplementedError()
+def _run_setuptools_install(path):
+    cmd = '%s setup.py install --record=%s --single-version-externally-managed'
+    record_file = os.path.join(path, 'RECORD')
+
+    os.system(cmd % (sys.executable, record_file))
+    if not os.path.exists(record_file):
+        raise ValueError('failed to install')
+    else:
+        egginfo_to_distinfo(record_file, remove_egginfo=True)
+
+
+def _run_packaging_install(path):
+    # XXX check for a valid setup.cfg?
+    dist = Distribution()
+    dist.parse_config_files()
+    try:
+        dist.run_command('install_dist')
+        name = dist.metadata['Name']
+        return database.get_distribution(name) is not None
+    except (IOError, os.error, PackagingError, CCompilerError):
+        raise ValueError("Failed to install, " + str(sys.exc_info()[1]))
 
 
 def _install_dist(dist, path):
@@ -87,64 +101,105 @@
     * copy the files in "path"
     * determine if the distribution is distutils2 or distutils1.
     """
-    where = dist.unpack(path)
+    where = dist.unpack()
 
-    # get into the dir
-    archive_dir = None
-    for item in os.listdir(where):
-        fullpath = os.path.join(where, item)
-        if os.path.isdir(fullpath):
-            archive_dir = fullpath
-            break
-
-    if archive_dir is None:
+    if where is None:
         raise ValueError('Cannot locate the unpacked archive')
 
-    # install
+    return _run_install_from_archive(where)
+
+
+def install_local_project(path):
+    """Install a distribution from a source directory.
+
+    If the source directory contains a setup.py install using distutils1.
+    If a setup.cfg is found, install using the install_dist command.
+
+    Returns True on success, False on Failure.
+    """
+    path = os.path.abspath(path)
+    if os.path.isdir(path):
+        logger.info('Installing from source directory: %r', path)
+        return _run_install_from_dir(path)
+    elif _is_archive_file(path):
+        logger.info('Installing from archive: %r', path)
+        _unpacked_dir = tempfile.mkdtemp()
+        try:
+            unpack_archive(path, _unpacked_dir)
+            return _run_install_from_archive(_unpacked_dir)
+        finally:
+            shutil.rmtree(_unpacked_dir)
+    else:
+        logger.warning('No project to install.')
+        return False
+
+
+def _run_install_from_archive(source_dir):
+    # XXX need a better way
+    for item in os.listdir(source_dir):
+        fullpath = os.path.join(source_dir, item)
+        if os.path.isdir(fullpath):
+            source_dir = fullpath
+            break
+    return _run_install_from_dir(source_dir)
+
+
+install_methods = {
+    'distutils2': _run_packaging_install,
+    'setuptools': _run_setuptools_install,
+    'distutils': _run_distutils_install}
+
+
+def _run_install_from_dir(source_dir):
     old_dir = os.getcwd()
-    os.chdir(archive_dir)
+    os.chdir(source_dir)
+    install_method = get_install_method(source_dir)
+    func = install_methods[install_method]
     try:
-        # distutils2 or distutils1 ?
-        if 'setup.py' in os.listdir(archive_dir):
-            return _run_d1_install(archive_dir, path)
-        else:
-            return _run_d2_install(archive_dir, path)
+        func = install_methods[install_method]
+        try:
+            func(source_dir)
+            return True
+        except ValueError:
+            # failed to install
+            logger.info(str(sys.exc_info()[1]))
+            return False
     finally:
         os.chdir(old_dir)
 
 
-def install_dists(dists, path, paths=sys.path):
+def install_dists(dists, path, paths=None):
     """Install all distributions provided in dists, with the given prefix.
 
     If an error occurs while installing one of the distributions, uninstall all
     the installed distribution (in the context if this function).
 
-    Return a list of installed files.
+    Return a list of installed dists.
 
     :param dists: distributions to install
     :param path: base path to install distribution in
     :param paths: list of paths (defaults to sys.path) to look for info
     """
 
-    installed_dists, installed_files = [], []
+    installed_dists = []
     for dist in dists:
-        logger.info('installing %s %s', dist.name, dist.version)
+        logger.info('Installing %r %s...', dist.name, dist.version)
         try:
-            installed_files.extend(_install_dist(dist, path))
+            _install_dist(dist, path)
             installed_dists.append(dist)
-        except Exception, e:
-            logger.info('failed: %s', e)
+        except Exception:
+            logger.info('Failed: %s', sys.exc_info()[1])
 
             # reverting
             for installed_dist in installed_dists:
-                _remove_dist(installed_dist, paths)
+                logger.info('Reverting %r', installed_dist)
+                remove(installed_dist.name, paths)
             raise e
-
-    return installed_files
+    return installed_dists
 
 
 def install_from_infos(install_path=None, install=[], remove=[], conflicts=[],
-                       paths=sys.path):
+                       paths=None):
     """Install and remove the given distributions.
 
     The function signature is made to be compatible with the one of get_infos.
@@ -188,7 +243,7 @@
     if remove:
         temp_dir = tempfile.mkdtemp()
         for dist in remove:
-            files = dist.get_installed_files()
+            files = dist.list_installed_files()
             temp_files[dist] = _move_files(files, temp_dir)
     try:
         if install:
@@ -236,23 +291,31 @@
     Conflict contains all the conflicting distributions, if there is a
     conflict.
     """
+    # this function does several things:
+    # 1. get a release specified by the requirements
+    # 2. gather its metadata, using setuptools compatibility if needed
+    # 3. compare this tree with what is currently installed on the system,
+    #    return the requirements of what is missing
+    # 4. do that recursively and merge back the results
+    # 5. return a dict containing information about what is needed to install
+    #    or remove
+
     if not installed:
-        logger.info('reading installed distributions')
-        installed = get_distributions(use_egg_info=True)
+        logger.debug('Reading installed distributions')
+        installed = list(get_distributions(use_egg_info=True))
 
     infos = {'install': [], 'remove': [], 'conflict': []}
-    # Is a compatible version of the project is already installed ?
+    # Is a compatible version of the project already installed ?
     predicate = get_version_predicate(requirements)
     found = False
-    installed = list(installed)
 
-    # check that the project isnt already installed
+    # check that the project isn't already installed
     for installed_project in installed:
         # is it a compatible project ?
         if predicate.name.lower() != installed_project.name.lower():
             continue
         found = True
-        logger.info('found %s %s', installed_project.name,
+        logger.info('Found %r %s', installed_project.name,
                     installed_project.version)
 
         # if we already have something installed, check it matches the
@@ -262,50 +325,45 @@
         break
 
     if not found:
-        logger.info('project not installed')
+        logger.debug('Project not installed')
 
     if not index:
         index = wrapper.ClientWrapper()
 
+    if not installed:
+        installed = get_distributions(use_egg_info=True)
+
     # Get all the releases that match the requirements
     try:
-        releases = index.get_releases(requirements)
+        release = index.get_release(requirements)
     except (ReleaseNotFound, ProjectNotFound):
-        raise InstallationException('Release not found: "%s"' % requirements)
-
-    # Pick up a release, and try to get the dependency tree
-    release = releases.get_last(requirements, prefer_final=prefer_final)
+        raise InstallationException('Release not found: %r' % requirements)
 
     if release is None:
-        logger.info('could not find a matching project')
+        logger.info('Could not find a matching project')
         return infos
 
-    # this works for Metadata 1.2
     metadata = release.fetch_metadata()
 
-    # for earlier, we need to build setuptools deps if any
+    # we need to build setuptools deps if any
     if 'requires_dist' not in metadata:
-        deps = _get_setuptools_deps(release)
-    else:
-        deps = metadata['requires_dist']
+        metadata['requires_dist'] = _get_setuptools_deps(release)
 
-    # XXX deps not used
+    # build the dependency graph with local and required dependencies
+    dists = list(installed)
+    dists.append(release)
+    depgraph = generate_graph(dists)
 
-    distributions = itertools.chain(installed, [release])
-    depgraph = generate_graph(distributions)
-
-    # Store all the already_installed packages in a list, in case of rollback.
     # Get what the missing deps are
     dists = depgraph.missing[release]
     if dists:
-        logger.info("missing dependencies found, retrieving metadata")
+        logger.info("Missing dependencies found, retrieving metadata")
         # we have missing deps
         for dist in dists:
             _update_infos(infos, get_infos(dist, index, installed))
 
     # Fill in the infos
     existing = [d for d in installed if d.name == release.name]
-
     if existing:
         infos['remove'].append(existing[0])
         infos['conflict'].extend(depgraph.reverse_list[existing[0]])
@@ -322,26 +380,38 @@
             infos[key].extend(new_infos[key])
 
 
-def _remove_dist(dist, paths=sys.path):
-    remove(dist.name, paths)
+def remove(project_name, paths=None, auto_confirm=True):
+    """Removes a single project from the installation.
 
-
-def remove(project_name, paths=sys.path):
-    """Removes a single project from the installation"""
+    Returns True on success
+    """
     dist = get_distribution(project_name, use_egg_info=True, paths=paths)
     if dist is None:
-        raise DistutilsError('Distribution "%s" not found' % project_name)
-    files = dist.get_installed_files(local=True)
+        raise PackagingError('Distribution %r not found' % project_name)
+    files = dist.list_installed_files(local=True)
     rmdirs = []
     rmfiles = []
     tmp = tempfile.mkdtemp(prefix=project_name + '-uninstall')
+
+    def _move_file(source, target):
+        try:
+            os.rename(source, target)
+        except OSError:
+            return sys.exc_info()[1]
+        return None
+
+    success = True
+    error = None
     try:
         for file_, md5, size in files:
             if os.path.isfile(file_):
                 dirname, filename = os.path.split(file_)
                 tmpfile = os.path.join(tmp, filename)
                 try:
-                    os.rename(file_, tmpfile)
+                    error = _move_file(file_, tmpfile)
+                    if error is not None:
+                        success = False
+                        break
                 finally:
                     if not os.path.isfile(file_):
                         os.rename(tmpfile, file_)
@@ -352,72 +422,119 @@
     finally:
         shutil.rmtree(tmp)
 
-    logger.info('removing %r...', project_name)
+    if not success:
+        logger.info('%r cannot be removed.', project_name)
+        logger.info('Error: %s', error)
+        return False
 
-    file_count = 0
+    logger.info('Removing %r: ', project_name)
+
     for file_ in rmfiles:
-        os.remove(file_)
-        file_count += 1
+        logger.info('  %s', file_)
 
-    dir_count = 0
-    for dirname in rmdirs:
-        if not os.path.exists(dirname):
-            # could
-            continue
+    # Taken from the pip project
+    if auto_confirm:
+        response = 'y'
+    else:
+        response = ask('Proceed (y/n)? ', ('y', 'n'))
 
-        files_count = 0
-        for root, dir, files in os.walk(dirname):
-            files_count += len(files)
+    if response == 'y':
+        file_count = 0
+        for file_ in rmfiles:
+            os.remove(file_)
+            file_count += 1
 
-        if files_count > 0:
-            # XXX Warning
-            continue
+        dir_count = 0
+        for dirname in rmdirs:
+            if not os.path.exists(dirname):
+                # could
+                continue
 
-        # empty dirs with only empty dirs
-        if bool(os.stat(dirname).st_mode & stat.S_IWUSR):
-            # XXX Add a callable in shutil.rmtree to count
-            # the number of deleted elements
-            shutil.rmtree(dirname)
-            dir_count += 1
+            files_count = 0
+            for root, dir, files in os.walk(dirname):
+                files_count += len(files)
 
-    # removing the top path
-    # XXX count it ?
-    if os.path.exists(dist.path):
-        shutil.rmtree(dist.path)
+            if files_count > 0:
+                # XXX Warning
+                continue
 
-    logger.info('success: removed %d files and %d dirs',
-                file_count, dir_count)
+            # empty dirs with only empty dirs
+            if os.stat(dirname).st_mode & stat.S_IWUSR:
+                # XXX Add a callable in shutil.rmtree to count
+                # the number of deleted elements
+                shutil.rmtree(dirname)
+                dir_count += 1
+
+        # removing the top path
+        # XXX count it ?
+        if os.path.exists(dist.path):
+            shutil.rmtree(dist.path)
+
+        logger.info('Success: removed %d files and %d dirs',
+                    file_count, dir_count)
+
+    return True
 
 
 def install(project):
-    logger.info('getting information about %r', project)
+    """Installs a project.
+
+    Returns True on success, False on failure
+    """
+    if is_python_build():
+        # Python would try to install into the site-packages directory under
+        # $PREFIX, but when running from an uninstalled code checkout we don't
+        # want to create directories under the installation root
+        message = ('installing third-party projects from an uninstalled '
+                   'Python is not supported')
+        logger.error(message)
+        return False
+
+    logger.info('Checking the installation location...')
+    purelib_path = get_path('purelib')
+
+    # trying to write a file there
+    try:
+        with tempfile.NamedTemporaryFile(suffix=project,
+                                         dir=purelib_path) as testfile:
+            testfile.write(b'test')
+    except OSError:
+        # FIXME this should check the errno, or be removed altogether (race
+        # condition: the directory permissions could be changed between here
+        # and the actual install)
+        logger.info('Unable to write in "%s". Do you have the permissions ?'
+                    % purelib_path)
+        return False
+
+    logger.info('Getting information about %r...', project)
     try:
         info = get_infos(project)
     except InstallationException:
-        logger.info('cound not find %r', project)
-        return
+        logger.info('Cound not find %r', project)
+        return False
 
     if info['install'] == []:
-        logger.info('nothing to install')
-        return
+        logger.info('Nothing to install')
+        return False
 
     install_path = get_config_var('base')
     try:
         install_from_infos(install_path,
                            info['install'], info['remove'], info['conflict'])
 
-    except InstallationConflict, e:
+    except InstallationConflict:
+        e = sys.exc_info()[1]
         if logger.isEnabledFor(logging.INFO):
-            projects = ['%s %s' % (p.name, p.version) for p in e.args[0]]
+            projects = ('%r %s' % (p.name, p.version) for p in e.args[0])
             logger.info('%r conflicts with %s', project, ','.join(projects))
 
+    return True
+
 
 def _main(**attrs):
     if 'script_args' not in attrs:
-        import sys
         attrs['requirements'] = sys.argv[1]
     get_infos(**attrs)
 
-
 if __name__ == '__main__':
     _main()
diff --git a/distutils2/manifest.py b/distutils2/manifest.py
--- a/distutils2/manifest.py
+++ b/distutils2/manifest.py
@@ -1,22 +1,20 @@
-"""distutils2.manifest
+"""Class representing the list of files in a distribution.
 
-Provides a Manifest class that can be used to:
+The Manifest class can be used to:
 
  - read or write a MANIFEST file
  - read a template file and find out the file list
-
-Basically, Manifest *is* the file list.
-
-XXX todo: document + add tests
 """
+# XXX todo: document + add tests
 import re
 import os
+import sys
 import fnmatch
-import logging
 
+from distutils2 import logger
 from distutils2.util import write_file, convert_path
-from distutils2.errors import (DistutilsTemplateError,
-                               DistutilsInternalError)
+from distutils2.errors import (PackagingTemplateError,
+                              PackagingInternalError)
 
 __all__ = ['Manifest']
 
@@ -24,6 +22,7 @@
 _COLLAPSE_PATTERN = re.compile('\\\w*\n', re.M)
 _COMMENTED_LINE = re.compile('#.*?(?=\n)|\n(?=$)', re.M | re.S)
 
+
 class Manifest(object):
     """A list of files built by on exploring the filesystem and filtered by
     applying various patterns to what we find there.
@@ -48,11 +47,8 @@
 
     def sort(self):
         # Not a strict lexical sort!
-        sortable_files = map(os.path.split, self.files)
-        sortable_files.sort()
-        self.files = []
-        for sort_tuple in sortable_files:
-            self.files.append(os.path.join(*sort_tuple))
+        self.files = [os.path.join(*path_tuple) for path_tuple in
+                      sorted(os.path.split(path) for path in self.files)]
 
     def clear(self):
         """Clear all collected files."""
@@ -72,7 +68,7 @@
 
         Updates the list accordingly.
         """
-        if isinstance(path_or_file, str):
+        if isinstance(path_or_file, basestring):
             f = open(path_or_file)
         else:
             f = path_or_file
@@ -94,8 +90,8 @@
                 continue
             try:
                 self._process_template_line(line)
-            except DistutilsTemplateError, msg:
-                logging.warning("%s, %s", path_or_file, msg)
+            except PackagingTemplateError:
+                logger.warning("%s, %s", path_or_file, sys.exc_info()[1])
 
     def write(self, path):
         """Write the file list in 'self.filelist' (presumably as filled in
@@ -103,22 +99,19 @@
         named by 'self.manifest'.
         """
         if os.path.isfile(path):
-            fp = open(path)
-            try:
+            with open(path) as fp:
                 first_line = fp.readline()
-            finally:
-                fp.close()
 
-            if first_line != '# file GENERATED by distutils, do NOT edit\n':
-                logging.info("not writing to manually maintained "
-                             "manifest file %r", path)
+            if first_line != '# file GENERATED by distutils2, do NOT edit\n':
+                logger.info("not writing to manually maintained "
+                            "manifest file %r", path)
                 return
 
         self.sort()
         self.remove_duplicates()
         content = self.files[:]
-        content.insert(0, '# file GENERATED by distutils, do NOT edit')
-        logging.info("writing manifest file %r", path)
+        content.insert(0, '# file GENERATED by distutils2, do NOT edit')
+        logger.info("writing manifest file %r", path)
         write_file(path, content)
 
     def read(self, path):
@@ -126,28 +119,26 @@
         fill in 'self.filelist', the list of files to include in the source
         distribution.
         """
-        logging.info("reading manifest file %r", path)
-        manifest = open(path)
-        try:
+        logger.info("reading manifest file %r", path)
+        with open(path) as manifest:
             for line in manifest.readlines():
                 self.append(line)
-        finally:
-            manifest.close()
 
-    def exclude_pattern(self, pattern, anchor=1, prefix=None, is_regex=0):
+    def exclude_pattern(self, pattern, anchor=True, prefix=None,
+                        is_regex=False):
         """Remove strings (presumably filenames) from 'files' that match
         'pattern'.
 
         Other parameters are the same as for 'include_pattern()', above.
-        The list 'self.files' is modified in place. Return 1 if files are
+        The list 'self.files' is modified in place. Return True if files are
         found.
         """
-        files_found = 0
+        files_found = False
         pattern_re = _translate_pattern(pattern, anchor, prefix, is_regex)
-        for i in range(len(self.files)-1, -1, -1):
+        for i in range(len(self.files) - 1, -1, -1):
             if pattern_re.search(self.files[i]):
                 del self.files[i]
-                files_found = 1
+                files_found = True
 
         return files_found
 
@@ -167,28 +158,28 @@
         if action in ('include', 'exclude',
                       'global-include', 'global-exclude'):
             if len(words) < 2:
-                raise DistutilsTemplateError(
+                raise PackagingTemplateError(
                       "%r expects <pattern1> <pattern2> ..." % action)
 
-            patterns = map(convert_path, words[1:])
+            patterns = [convert_path(word) for word in words[1:]]
 
         elif action in ('recursive-include', 'recursive-exclude'):
             if len(words) < 3:
-                raise DistutilsTemplateError(
+                raise PackagingTemplateError(
                       "%r expects <dir> <pattern1> <pattern2> ..." % action)
 
             dir = convert_path(words[1])
-            patterns = map(convert_path, words[2:])
+            patterns = [convert_path(word) for word in words[2:]]
 
         elif action in ('graft', 'prune'):
             if len(words) != 2:
-                raise DistutilsTemplateError(
+                raise PackagingTemplateError(
                      "%r expects a single <dir_pattern>" % action)
 
             dir_pattern = convert_path(words[1])
 
         else:
-            raise DistutilsTemplateError("unknown action %r" % action)
+            raise PackagingTemplateError("unknown action %r" % action)
 
         return action, patterns, dir, dir_pattern
 
@@ -205,55 +196,56 @@
         # can proceed with minimal error-checking.
         if action == 'include':
             for pattern in patterns:
-                if not self._include_pattern(pattern, anchor=1):
-                    logging.warning("no files found matching %r", pattern)
+                if not self._include_pattern(pattern, anchor=True):
+                    logger.warning("no files found matching %r", pattern)
 
         elif action == 'exclude':
             for pattern in patterns:
-                if not self.exclude_pattern(pattern, anchor=1):
-                    logging.warning("no previously-included files "
-                                    "found matching %r", pattern)
+                if not self.exclude_pattern(pattern, anchor=True):
+                    logger.warning("no previously-included files "
+                                   "found matching %r", pattern)
 
         elif action == 'global-include':
             for pattern in patterns:
-                if not self._include_pattern(pattern, anchor=0):
-                    logging.warning("no files found matching %r "
-                                    "anywhere in distribution", pattern)
+                if not self._include_pattern(pattern, anchor=False):
+                    logger.warning("no files found matching %r "
+                                   "anywhere in distribution", pattern)
 
         elif action == 'global-exclude':
             for pattern in patterns:
-                if not self.exclude_pattern(pattern, anchor=0):
-                    logging.warning("no previously-included files "
-                                    "matching %r found anywhere in "
-                                    "distribution", pattern)
+                if not self.exclude_pattern(pattern, anchor=False):
+                    logger.warning("no previously-included files "
+                                   "matching %r found anywhere in "
+                                   "distribution", pattern)
 
         elif action == 'recursive-include':
             for pattern in patterns:
                 if not self._include_pattern(pattern, prefix=dir):
-                    logging.warning("no files found matching %r "
-                                    "under directory %r", pattern, dir)
+                    logger.warning("no files found matching %r "
+                                   "under directory %r", pattern, dir)
 
         elif action == 'recursive-exclude':
             for pattern in patterns:
                 if not self.exclude_pattern(pattern, prefix=dir):
-                    logging.warning("no previously-included files "
-                                    "matching %r found under directory %r",
-                                    pattern, dir)
+                    logger.warning("no previously-included files "
+                                   "matching %r found under directory %r",
+                                   pattern, dir)
 
         elif action == 'graft':
             if not self._include_pattern(None, prefix=dir_pattern):
-                logging.warning("no directories found matching %r",
-                                dir_pattern)
+                logger.warning("no directories found matching %r",
+                               dir_pattern)
 
         elif action == 'prune':
             if not self.exclude_pattern(None, prefix=dir_pattern):
-                logging.warning("no previously-included directories found "
-                                "matching %r", dir_pattern)
+                logger.warning("no previously-included directories found "
+                               "matching %r", dir_pattern)
         else:
-            raise DistutilsInternalError(
-                  "this cannot happen: invalid action %r" % action)
+            raise PackagingInternalError(
+                "this cannot happen: invalid action %r" % action)
 
-    def _include_pattern(self, pattern, anchor=1, prefix=None, is_regex=0):
+    def _include_pattern(self, pattern, anchor=True, prefix=None,
+                         is_regex=False):
         """Select strings (presumably filenames) from 'self.files' that
         match 'pattern', a Unix-style wildcard (glob) pattern.
 
@@ -277,9 +269,9 @@
 
         Selected strings will be added to self.files.
 
-        Return 1 if files are found.
+        Return True if files are found.
         """
-        files_found = 0
+        files_found = False
         pattern_re = _translate_pattern(pattern, anchor, prefix, is_regex)
 
         # delayed loading of allfiles list
@@ -289,21 +281,19 @@
         for name in self.allfiles:
             if pattern_re.search(name):
                 self.files.append(name)
-                files_found = 1
+                files_found = True
 
         return files_found
 
 
-
 #
 # Utility functions
 #
-
 def _findall(dir=os.curdir):
     """Find all files under 'dir' and return the list of full filenames
     (relative to 'dir').
     """
-    from stat import ST_MODE, S_ISREG, S_ISDIR, S_ISLNK
+    from stat import S_ISREG, S_ISDIR, S_ISLNK
 
     list = []
     stack = [dir]
@@ -322,7 +312,7 @@
 
             # Avoid excess stat calls -- just one will do, thank you!
             stat = os.stat(fullname)
-            mode = stat[ST_MODE]
+            mode = stat.st_mode
             if S_ISREG(mode):
                 list.append(fullname)
             elif S_ISDIR(mode) and not S_ISLNK(mode):
@@ -331,7 +321,6 @@
     return list
 
 
-
 def _glob_to_re(pattern):
     """Translate a shell-like glob pattern to a regular expression.
 
@@ -353,7 +342,7 @@
     return pattern_re
 
 
-def _translate_pattern(pattern, anchor=1, prefix=None, is_regex=0):
+def _translate_pattern(pattern, anchor=True, prefix=None, is_regex=False):
     """Translate a shell-like wildcard pattern to a compiled regular
     expression.
 
@@ -362,7 +351,7 @@
     or just returned as-is (assumes it's a regex object).
     """
     if is_regex:
-        if isinstance(pattern, str):
+        if isinstance(pattern, basestring):
             return re.compile(pattern)
         else:
             return pattern
diff --git a/distutils2/markers.py b/distutils2/markers.py
--- a/distutils2/markers.py
+++ b/distutils2/markers.py
@@ -1,10 +1,11 @@
-""" Micro-language for PEP 345 environment markers
-"""
+"""Parser for the environment markers micro-language defined in PEP 345."""
+
 import sys
 import platform
 import os
-from tokenize import tokenize, NAME, OP, STRING, ENDMARKER
-from StringIO import StringIO
+
+from tokenize import generate_tokens, NAME, OP, STRING, ENDMARKER
+from StringIO import StringIO as BytesIO
 
 __all__ = ['interpret']
 
@@ -30,7 +31,8 @@
          'python_full_version': sys.version.split(' ', 1)[0],
          'os.name': os.name,
          'platform.version': platform.version(),
-         'platform.machine': platform.machine()}
+         'platform.machine': platform.machine(),
+         'platform.python_implementation': platform.python_implementation()}
 
 
 class _Operation(object):
@@ -124,39 +126,39 @@
         return self.left() and self.right()
 
 
-class _CHAIN(object):
-
-    def __init__(self, execution_context=None):
-        self.ops = []
-        self.op_starting = True
-        self.execution_context = execution_context
-
-    def eat(self, toktype, tokval, rowcol, line, logical_line):
+def interpret(marker, execution_context=None):
+    """Interpret a marker and return a result depending on environment."""
+    marker = marker.strip().encode()
+    ops = []
+    op_starting = True
+    for token in generate_tokens(BytesIO(marker).readline):
+        # Unpack token
+        toktype, tokval, rowcol, line, logical_line = token
         if toktype not in (NAME, OP, STRING, ENDMARKER):
             raise SyntaxError('Type not supported "%s"' % tokval)
 
-        if self.op_starting:
-            op = _Operation(self.execution_context)
-            if len(self.ops) > 0:
-                last = self.ops[-1]
+        if op_starting:
+            op = _Operation(execution_context)
+            if len(ops) > 0:
+                last = ops[-1]
                 if isinstance(last, (_OR, _AND)) and not last.filled():
                     last.right = op
                 else:
-                    self.ops.append(op)
+                    ops.append(op)
             else:
-                self.ops.append(op)
-            self.op_starting = False
+                ops.append(op)
+            op_starting = False
         else:
-            op = self.ops[-1]
+            op = ops[-1]
 
         if (toktype == ENDMARKER or
             (toktype == NAME and tokval in ('and', 'or'))):
             if toktype == NAME and tokval == 'and':
-                self.ops.append(_AND(self.ops.pop()))
+                ops.append(_AND(ops.pop()))
             elif toktype == NAME and tokval == 'or':
-                self.ops.append(_OR(self.ops.pop()))
-            self.op_starting = True
-            return
+                ops.append(_OR(ops.pop()))
+            op_starting = True
+            continue
 
         if isinstance(op, (_OR, _AND)) and op.right is not None:
             op = op.right
@@ -179,16 +181,7 @@
             else:
                 op.op = tokval
 
-    def result(self):
-        for op in self.ops:
-            if not op():
-                return False
-        return True
-
-
-def interpret(marker, execution_context=None):
-    """Interpret a marker and return a result depending on environment."""
-    marker = marker.strip()
-    operations = _CHAIN(execution_context)
-    tokenize(StringIO(marker).readline, operations.eat)
-    return operations.result()
+    for op in ops:
+        if not op():
+            return False
+    return True
diff --git a/distutils2/metadata.py b/distutils2/metadata.py
--- a/distutils2/metadata.py
+++ b/distutils2/metadata.py
@@ -3,17 +3,19 @@
 Supports all metadata formats (1.0, 1.1, 1.2).
 """
 
+import codecs
 import re
+import logging
+
 from StringIO import StringIO
 from email import message_from_file
-
 from distutils2 import logger
 from distutils2.markers import interpret
 from distutils2.version import (is_valid_predicate, is_valid_version,
-                                is_valid_versions)
+                               is_valid_versions)
 from distutils2.errors import (MetadataMissingError,
-                               MetadataConflictError,
-                               MetadataUnrecognizedVersionError)
+                              MetadataConflictError,
+                              MetadataUnrecognizedVersionError)
 
 try:
     # docutils is installed
@@ -39,8 +41,7 @@
     _HAS_DOCUTILS = False
 
 # public API of this module
-__all__ = ['Metadata', 'get_metadata_version', 'metadata_to_dict',
-           'PKG_INFO_ENCODING', 'PKG_INFO_PREFERRED_VERSION']
+__all__ = ['Metadata', 'PKG_INFO_ENCODING', 'PKG_INFO_PREFERRED_VERSION']
 
 # Encoding used for the PKG-INFO files
 PKG_INFO_ENCODING = 'utf-8'
@@ -99,7 +100,7 @@
                 return True
         return False
 
-    keys = fields.keys()
+    keys = list(fields)
     possible_versions = ['1.0', '1.1', '1.2']
 
     # first let's try to see if a field is not part of one of the version
@@ -138,52 +139,6 @@
     return '1.2'
 
 
-def get_metadata_version(metadata):
-    """Return the Metadata-Version attribute
-
-    - *metadata* give a METADATA object
-    """
-    return metadata['Metadata-Version']
-
-
-def metadata_to_dict(metadata):
-    """Convert a metadata object to a dict
-
-    - *metadata* give a METADATA object
-    """
-    data = {
-        'metadata_version': metadata['Metadata-Version'],
-        'name': metadata['Name'],
-        'version': metadata['Version'],
-        'summary': metadata['Summary'],
-        'home_page': metadata['Home-page'],
-        'author': metadata['Author'],
-        'author_email': metadata['Author-email'],
-        'license': metadata['License'],
-        'description': metadata['Description'],
-        'keywords': metadata['Keywords'],
-        'platform': metadata['Platform'],
-        'classifier': metadata['Classifier'],
-        'download_url': metadata['Download-URL'],
-    }
-
-    if metadata['Metadata-Version'] == '1.2':
-        data['requires_dist'] = metadata['Requires-Dist']
-        data['requires_python'] = metadata['Requires-Python']
-        data['requires_external'] = metadata['Requires-External']
-        data['provides_dist'] = metadata['Provides-Dist']
-        data['obsoletes_dist'] = metadata['Obsoletes-Dist']
-        data['project_url'] = [','.join(url) for url in
-                               metadata['Project-URL']]
-
-    elif metadata['Metadata-Version'] == '1.1':
-        data['provides'] = metadata['Provides']
-        data['requires'] = metadata['Requires']
-        data['obsoletes'] = metadata['Obsoletes']
-
-    return data
-
-
 _ATTR2FIELD = {
     'metadata_version': 'Metadata-Version',
     'name': 'Name',
@@ -225,6 +180,8 @@
 
 _UNICODEFIELDS = ('Author', 'Maintainer', 'Summary', 'Description')
 
+_MISSING = object()
+
 
 class NoDefault(object):
     """Marker object used for clean representation"""
@@ -248,10 +205,8 @@
     # also document the mapping API and UNKNOWN default key
 
     def __init__(self, path=None, platform_dependent=False,
-                 execution_context=None, fileobj=None, mapping=None,
-                 display_warnings=False):
+                 execution_context=None, fileobj=None, mapping=None):
         self._fields = {}
-        self.display_warnings = display_warnings
         self.requires_files = []
         self.docutils_support = _HAS_DOCUTILS
         self.platform_dependent = platform_dependent
@@ -269,12 +224,7 @@
         self._fields['Metadata-Version'] = _best_version(self._fields)
 
     def _write_field(self, file, name, value):
-        file.write('%s: %s\n' % (name, value))
-
-    def _encode_field(self, value):
-        if isinstance(value, unicode):
-            return value.encode(PKG_INFO_ENCODING)
-        return str(value)
+        file.write(u'%s: %s\n' % (name, value))
 
     def __getitem__(self, name):
         return self.get(name)
@@ -358,7 +308,8 @@
 
     def read(self, filepath):
         """Read the metadata values from a file path."""
-        self.read_file(open(filepath))
+        with codecs.open(filepath, 'r', encoding='utf-8') as fp:
+            self.read_file(fp)
 
     def read_file(self, fileob):
         """Read the metadata values from a file object."""
@@ -380,11 +331,8 @@
 
     def write(self, filepath):
         """Write the metadata fields to filepath."""
-        pkg_info = open(filepath, 'w')
-        try:
-            self.write_file(pkg_info)
-        finally:
-            pkg_info.close()
+        with codecs.open(filepath, 'w', encoding='utf-8') as fp:
+            self.write_file(fp)
 
     def write_file(self, fileobject):
         """Write the PKG-INFO format data to a file object."""
@@ -437,36 +385,38 @@
 
         if ((name in _ELEMENTSFIELD or name == 'Platform') and
             not isinstance(value, (list, tuple))):
-            if isinstance(value, str):
+            if isinstance(value, basestring):
                 value = [v.strip() for v in value.split(',')]
             else:
                 value = []
         elif (name in _LISTFIELDS and
               not isinstance(value, (list, tuple))):
-            if isinstance(value, str):
+            if isinstance(value, basestring):
                 value = [value]
             else:
                 value = []
 
-        if self.display_warnings:
+        if logger.isEnabledFor(logging.WARNING):
+            project_name = self['Name']
+
             if name in _PREDICATE_FIELDS and value is not None:
                 for v in value:
                     # check that the values are valid predicates
                     if not is_valid_predicate(v.split(';')[0]):
-                        logger.warn('"%s" is not a valid predicate (field "%s")' %
-                            (v, name))
+                        logger.warning(
+                            '%r: %r is not a valid predicate (field %r)',
+                            project_name, v, name)
             # FIXME this rejects UNKNOWN, is that right?
             elif name in _VERSIONS_FIELDS and value is not None:
                 if not is_valid_versions(value):
-                    logger.warn('"%s" is not a valid version (field "%s")' %
-                        (value, name))
+                    logger.warning('%r: %r is not a valid version (field %r)',
+                                   project_name, value, name)
             elif name in _VERSION_FIELDS and value is not None:
                 if not is_valid_version(value):
-                    logger.warn('"%s" is not a valid version (field "%s")' %
-                        (value, name))
+                    logger.warning('%r: %r is not a valid version (field %r)',
+                                   project_name, value, name)
 
         if name in _UNICODEFIELDS:
-            value = self._encode_field(value)
             if name == 'Description':
                 value = self._remove_line_prefix(value)
 
@@ -482,7 +432,7 @@
             return default
         if name in _UNICODEFIELDS:
             value = self._fields[name]
-            return self._encode_field(value)
+            return value
         elif name in _LISTFIELDS:
             value = self._fields[name]
             if value is None:
@@ -493,17 +443,17 @@
                 if not valid:
                     continue
                 if name not in _LISTTUPLEFIELDS:
-                    res.append(self._encode_field(val))
+                    res.append(val)
                 else:
                     # That's for Project-URL
-                    res.append((self._encode_field(val[0]), val[1]))
+                    res.append((val[0], val[1]))
             return res
 
         elif name in _ELEMENTSFIELD:
             valid, value = self._platform(self._fields[name])
             if not valid:
                 return []
-            if isinstance(value, str):
+            if isinstance(value, basestring):
                 return value.split(',')
         valid, value = self._platform(self._fields[name])
         if not valid:
@@ -551,13 +501,55 @@
 
         return missing, warnings
 
+    def todict(self):
+        """Return fields as a dict.
+
+        Field names will be converted to use the underscore-lowercase style
+        instead of hyphen-mixed case (i.e. home_page instead of Home-page).
+        """
+        data = {
+            'metadata_version': self['Metadata-Version'],
+            'name': self['Name'],
+            'version': self['Version'],
+            'summary': self['Summary'],
+            'home_page': self['Home-page'],
+            'author': self['Author'],
+            'author_email': self['Author-email'],
+            'license': self['License'],
+            'description': self['Description'],
+            'keywords': self['Keywords'],
+            'platform': self['Platform'],
+            'classifier': self['Classifier'],
+            'download_url': self['Download-URL'],
+        }
+
+        if self['Metadata-Version'] == '1.2':
+            data['requires_dist'] = self['Requires-Dist']
+            data['requires_python'] = self['Requires-Python']
+            data['requires_external'] = self['Requires-External']
+            data['provides_dist'] = self['Provides-Dist']
+            data['obsoletes_dist'] = self['Obsoletes-Dist']
+            data['project_url'] = [','.join(url) for url in
+                                   self['Project-URL']]
+
+        elif self['Metadata-Version'] == '1.1':
+            data['provides'] = self['Provides']
+            data['requires'] = self['Requires']
+            data['obsoletes'] = self['Obsoletes']
+
+        return data
+
     # Mapping API
 
     def keys(self):
         return _version2fieldlist(self['Metadata-Version'])
 
+    def __iter__(self):
+        for key in self.keys():
+            yield key
+
     def values(self):
-        return [self[key] for key in self.keys()]
+        return [self[key] for key in list(self.keys())]
 
     def items(self):
-        return [(key, self[key]) for key in self.keys()]
+        return [(key, self[key]) for key in list(self.keys())]
diff --git a/distutils2/pypi/__init__.py b/distutils2/pypi/__init__.py
--- a/distutils2/pypi/__init__.py
+++ b/distutils2/pypi/__init__.py
@@ -1,6 +1,4 @@
-"""Package containing ways to interact with Index APIs.
-
-"""
+"""Low-level and high-level APIs to interact with project indexes."""
 
 __all__ = ['simple',
            'xmlrpc',
@@ -8,4 +6,4 @@
            'errors',
            'mirrors']
 
-from dist import ReleaseInfo, ReleasesList, DistInfo
+from distutils2.pypi.dist import ReleaseInfo, ReleasesList, DistInfo
diff --git a/distutils2/pypi/base.py b/distutils2/pypi/base.py
--- a/distutils2/pypi/base.py
+++ b/distutils2/pypi/base.py
@@ -1,4 +1,6 @@
-from distutils2.index.dist import ReleasesList
+"""Base class for index crawlers."""
+
+from distutils2.pypi.dist import ReleasesList
 
 
 class BaseClient(object):
diff --git a/distutils2/pypi/dist.py b/distutils2/pypi/dist.py
--- a/distutils2/pypi/dist.py
+++ b/distutils2/pypi/dist.py
@@ -1,35 +1,25 @@
-"""distutils2.index.dist
+"""Classes representing releases and distributions retrieved from indexes.
 
-Provides useful classes to represent the release and distributions retrieved
-from indexes.
+A project (= unique name) can have several releases (= versions) and
+each release can have several distributions (= sdist and bdists).
 
-A project can have several releases (=versions) and each release can have
-several distributions (sdist, bdist).
+Release objects contain metadata-related information (see PEP 376);
+distribution objects contain download-related information.
+"""
 
-The release contains the metadata related informations (see PEP 384), and the
-distributions contains download related informations.
-
-"""
-import mimetypes
 import re
-import tarfile
+import hashlib
 import tempfile
 import urllib
 import urlparse
-import zipfile
-try:
-    import hashlib
-except ImportError:
-    from distutils2._backport import hashlib
+from distutils2.errors import IrrationalVersionError
+from distutils2.version import (suggest_normalized_version, NormalizedVersion,
+                               get_version_predicate)
+from distutils2.metadata import Metadata
+from distutils2.pypi.errors import (HashDoesNotMatch, UnsupportedHashName,
+                                   CantParseArchiveName)
+from distutils2.util import unpack_archive
 
-from distutils2._backport.shutil import unpack_archive
-from distutils2.errors import IrrationalVersionError
-from distutils2.index.errors import (HashDoesNotMatch, UnsupportedHashName,
-                                     CantParseArchiveName)
-from distutils2.version import (suggest_normalized_version, NormalizedVersion,
-                                get_version_predicate)
-from distutils2.metadata import Metadata
-from distutils2.util import splitext
 
 __all__ = ['ReleaseInfo', 'DistInfo', 'ReleasesList', 'get_infos_from_url']
 
@@ -94,7 +84,7 @@
     def fetch_metadata(self):
         """If the metadata is not set, use the indexes to get it"""
         if not self.metadata:
-            self._index.get_metadata(self.name, '%s' % self.version)
+            self._index.get_metadata(self.name, str(self.version))
         return self.metadata
 
     @property
@@ -104,7 +94,7 @@
 
     def fetch_distributions(self):
         if self.dists is None:
-            self._index.get_distributions(self.name, '%s' % self.version)
+            self._index.get_distributions(self.name, str(self.version))
             if self.dists is None:
                 self.dists = {}
         return self.dists
@@ -140,14 +130,14 @@
         not return one existing distribution.
         """
         if len(self.dists) == 0:
-            raise LookupError()
+            raise LookupError
         if dist_type:
             return self[dist_type]
         if prefer_source:
             if "sdist" in self.dists:
                 dist = self["sdist"]
             else:
-                dist = self.dists.values()[0]
+                dist = next(self.dists.values())
             return dist
 
     def unpack(self, path=None, prefer_source=True):
@@ -254,14 +244,14 @@
         self._url = None
         self.add_url(url, hashname, hashval, is_external)
 
-    def add_url(self, url, hashname=None, hashval=None, is_external=True):
+    def add_url(self, url=None, hashname=None, hashval=None, is_external=True):
         """Add a new url to the list of urls"""
         if hashname is not None:
             try:
                 hashlib.new(hashname)
             except ValueError:
                 raise UnsupportedHashName(hashname)
-        if not url in [u['url'] for u in self.urls]:
+        if url not in [u['url'] for u in self.urls]:
             self.urls.append({
                 'url': url,
                 'hashname': hashname,
@@ -323,20 +313,21 @@
                 path = tempfile.mkdtemp()
 
             filename = self.download(path)
-            content_type = mimetypes.guess_type(filename)[0]
-            self._unpacked_dir = unpack_archive(filename, path)
+            unpack_archive(filename, path)
+            self._unpacked_dir = path
 
-        return self._unpacked_dir
+        return path
 
     def _check_md5(self, filename):
         """Check that the md5 checksum of the given file matches the one in
         url param"""
         hashname = self.url['hashname']
         expected_hashval = self.url['hashval']
-        if not None in (expected_hashval, hashname):
-            f = open(filename)
-            hashval = hashlib.new(hashname)
-            hashval.update(f.read())
+        if None not in (expected_hashval, hashname):
+            with open(filename, 'rb') as f:
+                hashval = hashlib.new(hashname)
+                hashval.update(f.read())
+
             if hashval.hexdigest() != expected_hashval:
                 raise HashDoesNotMatch("got %s instead of %s"
                     % (hashval.hexdigest(), expected_hashval))
@@ -408,19 +399,19 @@
         """
         if release:
             if release.name.lower() != self.name.lower():
-                raise ValueError("%s is not the same project than %s" %
+                raise ValueError("%s is not the same project as %s" %
                                  (release.name, self.name))
-            version = '%s' % release.version
+            version = str(release.version)
 
-            if not version in self.get_versions():
+            if version not in self.get_versions():
                 # append only if not already exists
                 self.releases.append(release)
-            for dist in release.dists.itervalues():
+            for dist in release.dists.values():
                 for url in dist.urls:
                     self.add_release(version, dist.dist_type, **url)
         else:
-            matches = [r for r in self.releases if '%s' % r.version == version
-                                                 and r.name == self.name]
+            matches = [r for r in self.releases
+                       if str(r.version) == version and r.name == self.name]
             if not matches:
                 release = ReleaseInfo(self.name, version, index=self._index)
                 self.releases.append(release)
@@ -448,19 +439,19 @@
         sort_by.append("version")
 
         self.releases.sort(
-            key=lambda i: [getattr(i, arg) for arg in sort_by],
+            key=lambda i: tuple(getattr(i, arg) for arg in sort_by),
             reverse=reverse, *args, **kwargs)
 
     def get_release(self, version):
         """Return a release from its version."""
-        matches = [r for r in self.releases if "%s" % r.version == version]
+        matches = [r for r in self.releases if str(r.version) == version]
         if len(matches) != 1:
             raise KeyError(version)
         return matches[0]
 
     def get_versions(self):
         """Return a list of releases versions contained"""
-        return ["%s" % r.version for r in self.releases]
+        return [str(r.version) for r in self.releases]
 
     def __getitem__(self, key):
         return self.releases[key]
@@ -532,7 +523,7 @@
             # we dont get a good version number: recurse !
             return eager_split(str, maxsplit - 1)
         else:
-            return (name, version)
+            return name, version
     if probable_name is not None:
         probable_name = probable_name.lower()
     name = None
@@ -545,6 +536,6 @@
 
     version = suggest_normalized_version(version)
     if version is not None and name != "":
-        return (name.lower(), version)
+        return name.lower(), version
     else:
         raise CantParseArchiveName(archive_name)
diff --git a/distutils2/pypi/errors.py b/distutils2/pypi/errors.py
--- a/distutils2/pypi/errors.py
+++ b/distutils2/pypi/errors.py
@@ -1,27 +1,25 @@
-"""distutils2.pypi.errors
+"""Exceptions raised by distutils2.pypi code."""
 
-All errors and exceptions raised by PyPiIndex classes.
-"""
-from distutils2.errors import DistutilsIndexError
+from distutils2.errors import PackagingPyPIError
 
 
-class ProjectNotFound(DistutilsIndexError):
+class ProjectNotFound(PackagingPyPIError):
     """Project has not been found"""
 
 
-class DistributionNotFound(DistutilsIndexError):
+class DistributionNotFound(PackagingPyPIError):
     """The release has not been found"""
 
 
-class ReleaseNotFound(DistutilsIndexError):
+class ReleaseNotFound(PackagingPyPIError):
     """The release has not been found"""
 
 
-class CantParseArchiveName(DistutilsIndexError):
+class CantParseArchiveName(PackagingPyPIError):
     """An archive name can't be parsed to find distribution name and version"""
 
 
-class DownloadError(DistutilsIndexError):
+class DownloadError(PackagingPyPIError):
     """An error has occurs while downloading"""
 
 
@@ -29,13 +27,13 @@
     """Compared hashes does not match"""
 
 
-class UnsupportedHashName(DistutilsIndexError):
+class UnsupportedHashName(PackagingPyPIError):
     """A unsupported hashname has been used"""
 
 
-class UnableToDownload(DistutilsIndexError):
+class UnableToDownload(PackagingPyPIError):
     """All mirrors have been tried, without success"""
 
 
-class InvalidSearchField(DistutilsIndexError):
+class InvalidSearchField(PackagingPyPIError):
     """An invalid search field has been used"""
diff --git a/distutils2/pypi/mirrors.py b/distutils2/pypi/mirrors.py
--- a/distutils2/pypi/mirrors.py
+++ b/distutils2/pypi/mirrors.py
@@ -1,6 +1,4 @@
-"""Utilities related to the mirror infrastructure defined in PEP 381.
-See http://www.python.org/dev/peps/pep-0381/
-"""
+"""Utilities related to the mirror infrastructure defined in PEP 381."""
 
 from string import ascii_lowercase
 import socket
@@ -12,7 +10,7 @@
     """Return the list of mirrors from the last record found on the DNS
     entry::
 
-    >>> from distutils2.index.mirrors import get_mirrors
+    >>> from distutils2.pypi.mirrors import get_mirrors
     >>> get_mirrors()
     ['a.pypi.python.org', 'b.pypi.python.org', 'c.pypi.python.org',
     'd.pypi.python.org']
@@ -46,7 +44,7 @@
 
 
 def product(*args, **kwds):
-    pools = map(tuple, args) * kwds.get('repeat', 1)
+    pools = [tuple(arg) for arg in args] * kwds.get('repeat', 1)
     result = [[]]
     for pool in pools:
         result = [x + [y] for x in result for y in pool]
diff --git a/distutils2/pypi/simple.py b/distutils2/pypi/simple.py
--- a/distutils2/pypi/simple.py
+++ b/distutils2/pypi/simple.py
@@ -1,10 +1,11 @@
-"""index.simple
+"""Spider using the screen-scraping "simple" PyPI API.
 
-Contains the class "SimpleIndexCrawler", a simple spider to find and retrieve
-distributions on the Python Package Index, using its "simple" API,
-avalaible at http://pypi.python.org/simple/
+This module contains the class Crawler, a simple spider that
+can be used to find and retrieve distributions from a project index
+(like the Python Package Index), using its so-called simple API (see
+reference implementation available at http://pypi.python.org/simple/).
 """
-from fnmatch import translate
+
 import httplib
 import re
 import socket
@@ -13,17 +14,20 @@
 import urlparse
 import os
 
+from fnmatch import translate
+from functools import wraps
 from distutils2 import logger
-from distutils2.index.base import BaseClient
-from distutils2.index.dist import (ReleasesList, EXTENSIONS,
-                                   get_infos_from_url, MD5_HASH)
-from distutils2.index.errors import (DistutilsIndexError, DownloadError,
-                                     UnableToDownload, CantParseArchiveName,
-                                     ReleaseNotFound, ProjectNotFound)
-from distutils2.index.mirrors import get_mirrors
 from distutils2.metadata import Metadata
 from distutils2.version import get_version_predicate
-from distutils2 import __version__ as __distutils2_version__
+from distutils2 import __version__ as distutils2_version
+from distutils2.pypi.base import BaseClient
+from distutils2.pypi.dist import (ReleasesList, EXTENSIONS,
+                                  get_infos_from_url, MD5_HASH)
+from distutils2.pypi.errors import (PackagingPyPIError, DownloadError,
+                                    UnableToDownload, CantParseArchiveName,
+                                    ReleaseNotFound, ProjectNotFound)
+from distutils2.pypi.mirrors import get_mirrors
+from distutils2.metadata import Metadata
 
 __all__ = ['Crawler', 'DEFAULT_SIMPLE_INDEX_URL']
 
@@ -32,7 +36,7 @@
 DEFAULT_HOSTS = ("*",)
 SOCKET_TIMEOUT = 15
 USER_AGENT = "Python-urllib/%s distutils2/%s" % (
-    sys.version[:3], __distutils2_version__)
+    sys.version[:3], distutils2_version)
 
 # -- Regexps -------------------------------------------------
 EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.]+)$')
@@ -48,8 +52,9 @@
 def socket_timeout(timeout=SOCKET_TIMEOUT):
     """Decorator to add a socket timeout when requesting pages on PyPI.
     """
-    def _socket_timeout(func):
-        def _socket_timeout(self, *args, **kwargs):
+    def wrapper(func):
+        @wraps(func)
+        def wrapped(self, *args, **kwargs):
             old_timeout = socket.getdefaulttimeout()
             if hasattr(self, "_timeout"):
                 timeout = self._timeout
@@ -58,13 +63,14 @@
                 return func(self, *args, **kwargs)
             finally:
                 socket.setdefaulttimeout(old_timeout)
-        return _socket_timeout
-    return _socket_timeout
+        return wrapped
+    return wrapper
 
 
 def with_mirror_support():
     """Decorator that makes the mirroring support easier"""
     def wrapper(func):
+        @wraps(func)
         def wrapped(self, *args, **kwargs):
             try:
                 return func(self, *args, **kwargs)
@@ -103,7 +109,7 @@
     :param follow_externals: tell if following external links is needed or
                              not. Default is False.
     :param mirrors_url: the url to look on for DNS records giving mirror
-                        adresses.
+                        addresses.
     :param mirrors: a list of mirrors (see PEP 381).
     :param timeout: time in seconds to consider a url has timeouted.
     :param mirrors_max_tries": number of times to try requesting informations
@@ -113,13 +119,20 @@
     def __init__(self, index_url=DEFAULT_SIMPLE_INDEX_URL, prefer_final=False,
                  prefer_source=True, hosts=DEFAULT_HOSTS,
                  follow_externals=False, mirrors_url=None, mirrors=None,
-                 timeout=SOCKET_TIMEOUT, mirrors_max_tries=0):
+                 timeout=SOCKET_TIMEOUT, mirrors_max_tries=0, verbose=False):
         super(Crawler, self).__init__(prefer_final, prefer_source)
         self.follow_externals = follow_externals
+        self.verbose = verbose
 
         # mirroring attributes.
-        if not index_url.endswith("/"):
-            index_url += "/"
+        parsed = urlparse.urlparse(index_url)
+        self.scheme = parsed[0]
+        if self.scheme == 'file':
+            ender = os.path.sep
+        else:
+            ender = '/'
+        if not index_url.endswith(ender):
+            index_url += ender
         # if no mirrors are defined, use the method described in PEP 381.
         if mirrors is None:
             mirrors = get_mirrors(mirrors_url)
@@ -145,33 +158,39 @@
 
         Return a list of names.
         """
-        index = self._open_url(self.index_url)
-        if '*' in name:
-            name.replace('*', '.*')
-        else:
-            name = "%s%s%s" % ('*.?', name, '*.?')
-        name = name.replace('*', '[^<]*')  # avoid matching of the tag's end
-        projectname = re.compile("""<a[^>]*>(%s)</a>""" % name, flags=re.I)
-        matching_projects = []
-        for match in projectname.finditer(index.read()):
+        with self._open_url(self.index_url) as index:
+            if '*' in name:
+                name.replace('*', '.*')
+            else:
+                name = "%s%s%s" % ('*.?', name, '*.?')
+            name = name.replace('*', '[^<]*')  # avoid matching end tag
+            projectname = re.compile('<a[^>]*>(%s)</a>' % name, re.I)
+            matching_projects = []
+
+            index_content = index.read()
+
+        # FIXME should use bytes I/O and regexes instead of decoding
+        index_content = index_content.decode()
+
+        for match in projectname.finditer(index_content):
             project_name = match.group(1)
             matching_projects.append(self._get_project(project_name))
         return matching_projects
 
     def get_releases(self, requirements, prefer_final=None,
                      force_update=False):
-        """Search for releases and return a ReleaseList object containing
+        """Search for releases and return a ReleasesList object containing
         the results.
         """
         predicate = get_version_predicate(requirements)
         if predicate.name.lower() in self._projects and not force_update:
             return self._projects.get(predicate.name.lower())
         prefer_final = self._get_prefer_final(prefer_final)
-        logger.info('reading info on PyPI about %s', predicate.name)
+        logger.debug('Reading info on PyPI about %s', predicate.name)
         self._process_index_page(predicate.name)
 
         if predicate.name.lower() not in self._projects:
-            raise ProjectNotFound()
+            raise ProjectNotFound
 
         releases = self._projects.get(predicate.name.lower())
         releases.sort_releases(prefer_final=prefer_final)
@@ -199,10 +218,10 @@
         Currently, download one archive, extract it and use the PKG-INFO file.
         """
         release = self.get_distributions(project_name, version)
-        if not release._metadata:
+        if not release.metadata:
             location = release.get_distribution().unpack()
             pkg_info = os.path.join(location, 'PKG-INFO')
-            release._metadata = Metadata(pkg_info)
+            release.metadata = Metadata(pkg_info)
         return release
 
     def _switch_to_next_mirror(self):
@@ -213,7 +232,8 @@
         """
         self._mirrors_used.add(self.index_url)
         index_url = self._mirrors.pop()
-        if not ("http://" or "https://" or "file://") in index_url:
+        # XXX use urlparse for a real check of missing scheme part
+        if not index_url.startswith(("http://", "https://", "file://")):
             index_url = "http://%s" % index_url
 
         if not index_url.endswith("/simple"):
@@ -264,9 +284,8 @@
             name = release.name
         else:
             name = release_info['name']
-        if not name.lower() in self._projects:
-            self._projects[name.lower()] = ReleasesList(name,
-                                                        index=self._index)
+        if name.lower() not in self._projects:
+            self._projects[name.lower()] = ReleasesList(name, index=self._index)
 
         if release:
             self._projects[name.lower()].add_release(release=release)
@@ -292,27 +311,32 @@
                              method on it)
         """
         f = self._open_url(url)
-        base_url = f.url
-        if url not in self._processed_urls:
-            self._processed_urls.append(url)
-            link_matcher = self._get_link_matcher(url)
-            for link, is_download in link_matcher(f.read(), base_url):
-                if link not in self._processed_urls:
-                    if self._is_distribution(link) or is_download:
-                        self._processed_urls.append(link)
-                        # it's a distribution, so create a dist object
-                        try:
-                            infos = get_infos_from_url(link, project_name,
-                                        is_external=not self.index_url in url)
-                        except CantParseArchiveName, e:
-                            logger.warning(
-                                "version has not been parsed: %s", e)
+        try:
+            base_url = f.url
+            if url not in self._processed_urls:
+                self._processed_urls.append(url)
+                link_matcher = self._get_link_matcher(url)
+                for link, is_download in link_matcher(f.read().decode(), base_url):
+                    if link not in self._processed_urls:
+                        if self._is_distribution(link) or is_download:
+                            self._processed_urls.append(link)
+                            # it's a distribution, so create a dist object
+                            try:
+                                infos = get_infos_from_url(link, project_name,
+                                            is_external=self.index_url not in url)
+                            except CantParseArchiveName:
+                                e = sys.exc_info()[1]
+                                if self.verbose:
+                                    logger.warning(
+                                        "version has not been parsed: %s", e)
+                            else:
+                                self._register_release(release_info=infos)
                         else:
-                            self._register_release(release_info=infos)
-                    else:
-                        if self._is_browsable(link) and follow_links:
-                            self._process_url(link, project_name,
-                                follow_links=False)
+                            if self._is_browsable(link) and follow_links:
+                                self._process_url(link, project_name,
+                                    follow_links=False)
+        finally:
+            f.close()
 
     def _get_link_matcher(self, url):
         """Returns the right link matcher function of the given url
@@ -331,6 +355,9 @@
         This matches the simple index requirements for matching links.
         If follow_externals is set to False, dont yeld the external
         urls.
+
+        :param content: the content of the page we want to parse
+        :param base_url: the url of this page.
         """
         for match in HREF.finditer(content):
             url = self._get_full_url(match.group(1), base_url)
@@ -340,7 +367,7 @@
         for match in REL.finditer(content):
             # search for rel links.
             tag, rel = match.groups()
-            rels = map(str.strip, rel.lower().split(','))
+            rels = [s.strip() for s in rel.lower().split(',')]
             if 'homepage' in rels or 'download' in rels:
                 for match in HREF.finditer(tag):
                     url = self._get_full_url(match.group(1), base_url)
@@ -363,7 +390,11 @@
         :param name: the name of the project to find the page
         """
         # Browse and index the content of the given PyPI page.
-        url = self.index_url + name + "/"
+        if self.scheme == 'file':
+            ender = os.path.sep
+        else:
+            ender = '/'
+        url = self.index_url + name + ender
         self._process_url(url, name)
 
     @socket_timeout()
@@ -376,19 +407,19 @@
 
         # authentication stuff
         if scheme in ('http', 'https'):
-            auth, host = urllib2.splituser(netloc)
+            auth, host = urlparse.splituser(netloc)
         else:
             auth = None
 
         # add index.html automatically for filesystem paths
         if scheme == 'file':
-            if url.endswith('/'):
+            if url.endswith(os.path.sep):
                 url += "index.html"
 
         # add authorization headers if auth is provided
         if auth:
             auth = "Basic " + \
-                urllib2.unquote(auth).encode('base64').strip()
+                urlparse.unquote(auth).encode('base64').strip()
             new_url = urlparse.urlunparse((
                 scheme, host, path, params, query, frag))
             request = urllib2.Request(new_url)
@@ -398,17 +429,21 @@
         request.add_header('User-Agent', USER_AGENT)
         try:
             fp = urllib2.urlopen(request)
-        except (ValueError, httplib.InvalidURL), v:
+        except (ValueError, httplib.InvalidURL):
+            v = sys.exc_info()[1]
             msg = ' '.join([str(arg) for arg in v.args])
-            raise DistutilsIndexError('%s %s' % (url, msg))
-        except urllib2.HTTPError, v:
-            return v
-        except urllib2.URLError, v:
+            raise PackagingPyPIError('%s %s' % (url, msg))
+        except urllib2.HTTPError:
+            return sys.exc_info()[1]
+        except urllib2.URLError:
+            v = sys.exc_info()[1]
             raise DownloadError("Download error for %s: %s" % (url, v.reason))
-        except httplib.BadStatusLine, v:
+        except httplib.BadStatusLine:
+            v = sys.exc_info()[1]
             raise DownloadError('%s returned a bad status line. '
                 'The server might be down, %s' % (url, v.line))
-        except httplib.HTTPException, v:
+        except httplib.HTTPException:
+            v = sys.exc_info()[1]
             raise DownloadError("Download error for %s: %s" % (url, v))
         except socket.timeout:
             raise DownloadError("The server timeouted")
@@ -430,9 +465,9 @@
         elif what.startswith('#'):
             what = int(what[1:])
         else:
-            from htmlentitydefs import name2codepoint
+            from html.entities import name2codepoint
             what = name2codepoint.get(what, match.group(0))
-        return unichr(what)
+        return chr(what)
 
     def _htmldecode(self, text):
         """Decode HTML entities in the given text."""
diff --git a/distutils2/pypi/wrapper.py b/distutils2/pypi/wrapper.py
--- a/distutils2/pypi/wrapper.py
+++ b/distutils2/pypi/wrapper.py
@@ -1,4 +1,10 @@
-from distutils2.index import simple, xmlrpc
+"""Convenient client for all PyPI APIs.
+
+This module provides a ClientWrapper class which will use the "simple"
+or XML-RPC API to request information or files from an index.
+"""
+
+from distutils2.pypi import simple, xmlrpc
 
 _WRAPPER_MAPPINGS = {'get_release': 'simple',
                      'get_releases': 'simple',
@@ -19,14 +25,14 @@
         exception = None
         methods = [func]
         for f in wrapper._indexes.values():
-            if f != func.im_self and hasattr(f, func.__name__):
+            if f != func.__self__ and hasattr(f, func.__name__):
                 methods.append(getattr(f, func.__name__))
         for method in methods:
             try:
                 response = method(*args, **kwargs)
                 retry = False
-            except Exception, e:
-                exception = e
+            except Exception:
+                exception = sys.exc_info()[1]
             if not retry:
                 break
         if retry and exception:
@@ -43,7 +49,7 @@
     mappings.
     If one of the indexes returns an error, tries to use others indexes.
 
-    :param index: tell wich index to rely on by default.
+    :param index: tell which index to rely on by default.
     :param index_classes: a dict of name:class to use as indexes.
     :param indexes: a dict of name:index already instantiated
     :param mappings: the mappings to use for this wrapper
@@ -58,7 +64,7 @@
 
         # instantiate the classes and set their _project attribute to the one
         # of the wrapper.
-        for name, cls in index_classes.iteritems():
+        for name, cls in index_classes.items():
             obj = self._indexes.setdefault(name, cls())
             obj._projects = self._projects
             obj._index = self
diff --git a/distutils2/pypi/xmlrpc.py b/distutils2/pypi/xmlrpc.py
--- a/distutils2/pypi/xmlrpc.py
+++ b/distutils2/pypi/xmlrpc.py
@@ -1,12 +1,20 @@
-import logging
-import xmlrpclib
+"""Spider using the XML-RPC PyPI API.
 
+This module contains the class Client, a spider that can be used to find
+and retrieve distributions from a project index (like the Python Package
+Index), using its XML-RPC API (see documentation of the reference
+implementation at http://wiki.python.org/moin/PyPiXmlRpc).
+"""
+
+import xmlrpclib, sys
+
+from distutils2 import logger
 from distutils2.errors import IrrationalVersionError
-from distutils2.index.base import BaseClient
-from distutils2.index.errors import (ProjectNotFound, InvalidSearchField,
-                                     ReleaseNotFound)
-from distutils2.index.dist import ReleaseInfo
 from distutils2.version import get_version_predicate
+from distutils2.pypi.base import BaseClient
+from distutils2.pypi.errors import (ProjectNotFound, InvalidSearchField,
+                                   ReleaseNotFound)
+from distutils2.pypi.dist import ReleaseInfo
 
 __all__ = ['Client', 'DEFAULT_XMLRPC_INDEX_URL']
 
@@ -23,11 +31,11 @@
     If no server_url is specified, use the default PyPI XML-RPC URL,
     defined in the DEFAULT_XMLRPC_INDEX_URL constant::
 
-        >>> client = XMLRPCClient()
+        >>> client = Client()
         >>> client.server_url == DEFAULT_XMLRPC_INDEX_URL
         True
 
-        >>> client = XMLRPCClient("http://someurl/")
+        >>> client = Client("http://someurl/")
         >>> client.server_url
         'http://someurl/'
     """
@@ -46,8 +54,8 @@
         predicate = get_version_predicate(requirements)
         releases = self.get_releases(predicate.name)
         release = releases.get_last(predicate, prefer_final)
-        self.get_metadata(release.name, "%s" % release.version)
-        self.get_distributions(release.name, "%s" % release.version)
+        self.get_metadata(release.name, str(release.version))
+        self.get_distributions(release.name, str(release.version))
         return release
 
     def get_releases(self, requirements, prefer_final=None, show_hidden=True,
@@ -61,7 +69,7 @@
         informations (eg. make a new XML-RPC call).
         ::
 
-            >>> client = XMLRPCClient()
+            >>> client = Client()
             >>> client.get_releases('Foo')
             ['1.1', '1.2', '1.3']
 
@@ -84,8 +92,7 @@
                 # list of releases that does not contains hidden ones
                 all_versions = get_versions(project_name, show_hidden)
                 existing_versions = project.get_versions()
-                hidden_versions = list(set(all_versions) -
-                                       set(existing_versions))
+                hidden_versions = set(all_versions) - set(existing_versions)
                 for version in hidden_versions:
                     project.add_release(release=ReleaseInfo(project_name,
                                             version, index=self._index))
@@ -103,6 +110,7 @@
         project.sort_releases(prefer_final)
         return project
 
+
     def get_distributions(self, project_name, version):
         """Grab informations about distributions from XML-RPC.
 
@@ -163,8 +171,9 @@
                 project.add_release(release=ReleaseInfo(p['name'],
                     p['version'], metadata={'summary': p['summary']},
                     index=self._index))
-            except IrrationalVersionError, e:
-                logging.warn("Irrational version error found: %s", e)
+            except IrrationalVersionError:
+                e = sys.exc_info()[1]
+                logger.warning("Irrational version error found: %s", e)
         return [self._projects[p['name'].lower()] for p in projects]
 
     def get_all_projects(self):
@@ -181,7 +190,7 @@
 
         If no server proxy is defined yet, creates a new one::
 
-            >>> client = XmlRpcClient()
+            >>> client = Client()
             >>> client.proxy()
             <ServerProxy for python.org/pypi>
 
diff --git a/distutils2/resources.py b/distutils2/resources.py
deleted file mode 100644
--- a/distutils2/resources.py
+++ /dev/null
@@ -1,25 +0,0 @@
-import os
-
-from distutils2.util import iglob
-
-
-def _rel_path(base, path):
-    assert path.startswith(base)
-    return path[len(base):].lstrip('/')
-
-
-def resources_dests(resources_root, rules):
-    """find destination of resources files"""
-    destinations = {}
-    for (base, suffix, dest) in rules:
-        prefix = os.path.join(resources_root, base)
-        for abs_base in iglob(prefix):
-            abs_glob = os.path.join(abs_base, suffix)
-            for abs_path in iglob(abs_glob):
-                resource_file = _rel_path(resources_root, abs_path)
-                if dest is None:  # remove the entry if it was here
-                    destinations.pop(resource_file, None)
-                else:
-                    rel_path = _rel_path(abs_base, abs_path)
-                    destinations[resource_file] = os.path.join(dest, rel_path)
-    return destinations
diff --git a/distutils2/run.py b/distutils2/run.py
--- a/distutils2/run.py
+++ b/distutils2/run.py
@@ -1,35 +1,26 @@
-"""distutils2.dispatcher
+"""Main command line parser.  Implements the pysetup script."""
 
-Parses the command line.
-"""
+import os
+import re
+import sys
+import getopt
 import logging
-import re
-import os
-import sys
-
-from distutils2.errors import DistutilsError, CCompilerError
-from distutils2._backport.pkgutil import get_distributions, get_distribution
-from distutils2.depgraph import generate_graph
-from distutils2.install import install, remove
-from distutils2.dist import Distribution
-
-from distutils2.command import get_command_class, STANDARD_COMMANDS
-
-from distutils2.errors import (DistutilsOptionError, DistutilsArgError,
-                               DistutilsModuleError, DistutilsClassError)
 
 from distutils2 import logger
+from distutils2.dist import Distribution
+from distutils2.util import _is_archive_file, generate_setup_py
+from distutils2.command import get_command_class, STANDARD_COMMANDS
+from distutils2.install import install, install_local_project, remove
+from distutils2.database import get_distribution, get_distributions
+from distutils2.depgraph import generate_graph
 from distutils2.fancy_getopt import FancyGetopt
+from distutils2.errors import (PackagingArgError, PackagingError,
+                              PackagingModuleError, PackagingClassError,
+                              CCompilerError)
+
 
 command_re = re.compile(r'^[a-zA-Z]([a-zA-Z0-9_]*)$')
 
-run_usage = """\
-usage: pysetup run [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
-   or: pysetup run --help
-   or: pysetup run --list-commands
-   or: pysetup run cmd --help
-"""
-
 common_usage = """\
 Actions:
 %(actions)s
@@ -39,77 +30,252 @@
     pysetup action --help
 """
 
-global_options = [('verbose', 'v', "run verbosely (default)", 1),
-                  ('quiet', 'q', "run quietly (turns verbosity off)"),
-                  ('dry-run', 'n', "don't actually do anything"),
-                  ('help', 'h', "show detailed help message"),
-                  ('no-user-cfg', None,
-                   'ignore pydistutils.cfg in your home directory'),
-                  ('version', None, 'Display the version'),
-    ]
+create_usage = """\
+Usage: pysetup create
+   or: pysetup create --help
+
+Create a new Python project.
+"""
+
+generate_usage = """\
+Usage: pysetup generate-setup
+   or: pysetup generate-setup --help
+
+Generate a setup.py script for backward-compatibility purposes.
+"""
+
+
+graph_usage = """\
+Usage: pysetup graph dist
+   or: pysetup graph --help
+
+Print dependency graph for the distribution.
+
+positional arguments:
+   dist  installed distribution name
+"""
+
+install_usage = """\
+Usage: pysetup install [dist]
+   or: pysetup install [archive]
+   or: pysetup install [src_dir]
+   or: pysetup install --help
+
+Install a Python distribution from the indexes, source directory, or sdist.
+
+positional arguments:
+   archive  path to source distribution (zip, tar.gz)
+   dist     distribution name to install from the indexes
+   scr_dir  path to source directory
+
+"""
+
+metadata_usage = """\
+Usage: pysetup metadata [dist] [-f field ...]
+   or: pysetup metadata [dist] [--all]
+   or: pysetup metadata --help
+
+Print metadata for the distribution.
+
+positional arguments:
+   dist  installed distribution name
+
+optional arguments:
+   -f     metadata field to print
+   --all  print all metadata fields
+"""
+
+remove_usage = """\
+Usage: pysetup remove dist [-y]
+   or: pysetup remove --help
+
+Uninstall a Python distribution.
+
+positional arguments:
+   dist  installed distribution name
+
+optional arguments:
+   -y  auto confirm distribution removal
+"""
+
+run_usage = """\
+Usage: pysetup run [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
+   or: pysetup run --help
+   or: pysetup run --list-commands
+   or: pysetup run cmd --help
+"""
+
+list_usage = """\
+Usage: pysetup list dist [dist ...]
+   or: pysetup list --help
+   or: pysetup list --all
+
+Print name, version and location for the matching installed distributions.
+
+positional arguments:
+   dist  installed distribution name
+
+optional arguments:
+   --all  list all installed distributions
+"""
+
+search_usage = """\
+Usage: pysetup search [project] [--simple [url]] [--xmlrpc [url] [--fieldname value ...] --operator or|and]
+   or: pysetup search --help
+
+Search the indexes for the matching projects.
+
+positional arguments:
+    project     the project pattern to search for
+
+optional arguments:
+    --xmlrpc [url]      wether to use the xmlrpc index or not. If an url is
+                        specified, it will be used rather than the default one.
+
+    --simple [url]      wether to use the simple index or not. If an url is
+                        specified, it will be used rather than the default one.
+
+    --fieldname value   Make a search on this field. Can only be used if
+                        --xmlrpc has been selected or is the default index.
+
+    --operator or|and   Defines what is the operator to use when doing xmlrpc
+                        searchs with multiple fieldnames. Can only be used if
+                        --xmlrpc has been selected or is the default index.
+"""
+
+global_options = [
+    # The fourth entry for verbose means that it can be repeated.
+    ('verbose', 'v', "run verbosely (default)", True),
+    ('quiet', 'q', "run quietly (turns verbosity off)"),
+    ('dry-run', 'n', "don't actually do anything"),
+    ('help', 'h', "show detailed help message"),
+    ('no-user-cfg', None, 'ignore pydistutils.cfg in your home directory'),
+    ('version', None, 'Display the version'),
+]
+
+negative_opt = {'quiet': 'verbose'}
 
 display_options = [
-        ('help-commands', None,
-         "list all available commands"),
-        ]
-
+    ('help-commands', None, "list all available commands"),
+]
 
 display_option_names = [x[0].replace('-', '_') for x in display_options]
-negative_opt = {'quiet': 'verbose'}
 
-def _set_logger():
-    logger.setLevel(logging.INFO)
-    sth = logging.StreamHandler(sys.stderr)
-    sth.setLevel(logging.INFO)
-    logger.addHandler(sth)
-    logger.propagate = 0
 
+def _parse_args(args, options, long_options):
+    """Transform sys.argv input into a dict.
+
+    :param args: the args to parse (i.e sys.argv)
+    :param options: the list of options to pass to getopt
+    :param long_options: the list of string with the names of the long options
+                         to be passed to getopt.
+
+    The function returns a dict with options/long_options as keys and matching
+    values as values.
+    """
+    optlist, args = getopt.gnu_getopt(args, options, long_options)
+    optdict = {}
+    optdict['args'] = args
+    for k, v in optlist:
+        k = k.lstrip('-')
+        if k not in optdict:
+            optdict[k] = []
+            if v:
+                optdict[k].append(v)
+        else:
+            optdict[k].append(v)
+    return optdict
+
+
+class action_help(object):
+    """Prints a help message when the standard help flags: -h and --help
+    are used on the commandline.
+    """
+
+    def __init__(self, help_msg):
+        self.help_msg = help_msg
+
+    def __call__(self, f):
+        def wrapper(*args, **kwargs):
+            f_args = args[1]
+            if '--help' in f_args or '-h' in f_args:
+                print(self.help_msg)
+                return
+            return f(*args, **kwargs)
+        return wrapper
+
+
+ at action_help(create_usage)
+def _create(distpatcher, args, **kw):
+    from distutils2.create import main
+    return main()
+
+
+ at action_help(generate_usage)
+def _generate(distpatcher, args, **kw):
+    generate_setup_py()
+    logger.info('The setup.py was generated')
+
+
+ at action_help(graph_usage)
 def _graph(dispatcher, args, **kw):
-    # XXX
-    dists = get_distributions(use_egg_info=True)
-    graph = generate_graph(dists)
-    print(graph)
-    return 0
-
-
-    name = args[0]
+    name = args[1]
     dist = get_distribution(name, use_egg_info=True)
     if dist is None:
-        print('Distribution not found.')
+        logger.warning('Distribution not found.')
+        return 1
     else:
         dists = get_distributions(use_egg_info=True)
         graph = generate_graph(dists)
         print(graph.repr_node(dist))
 
-    return 0
 
+ at action_help(install_usage)
+def _install(dispatcher, args, **kw):
+    # first check if we are in a source directory
+    if len(args) < 2:
+        # are we inside a project dir?
+        if os.path.isfile('setup.cfg') or os.path.isfile('setup.py'):
+            args.insert(1, os.getcwd())
+        else:
+            logger.warning('No project to install.')
+            return 1
 
+    target = args[1]
+    # installing from a source dir or archive file?
+    if os.path.isdir(target) or _is_archive_file(target):
+        return not install_local_project(target)
+    else:
+        # download from PyPI
+        return not install(target)
 
-def _search(dispatcher, args, **kw):
-    search = args[0].lower()
-    for dist in get_distributions(use_egg_info=True):
-        name = dist.name.lower()
-        if search in name:
-            print('%s %s at %s' % (dist.name, dist.metadata['version'],
-                                    dist.path))
 
-    return 0
+ at action_help(metadata_usage)
+def _metadata(dispatcher, args, **kw):
+    opts = _parse_args(args[1:], 'f:', ['all'])
+    if opts['args']:
+        name = opts['args'][0]
+        dist = get_distribution(name, use_egg_info=True)
+        if dist is None:
+            logger.warning('%r not installed', name)
+            return 1
+    elif os.path.isfile('setup.cfg'):
+        logger.info('searching local dir for metadata')
+        dist = Distribution()  # XXX use config module
+        dist.parse_config_files()
+    else:
+        logger.warning('no argument given and no local setup.cfg found')
+        return 1
 
-
-def _metadata(dispatcher, args, **kw):
-    ### XXX Needs to work on any installed package as well
-    from distutils2.dist import Distribution
-    dist = Distribution()
-    dist.parse_config_files()
     metadata = dist.metadata
 
-    if 'all' in args:
+    if 'all' in opts:
         keys = metadata.keys()
     else:
-        keys = args
-        if len(keys) == 1:
-            print metadata[keys[0]]
-            return
+        if 'f' in opts:
+            keys = (k for k in opts['f'] if k in metadata)
+        else:
+            keys = ()
 
     for key in keys:
         if key in metadata:
@@ -117,26 +283,40 @@
             value = metadata[key]
             if isinstance(value, list):
                 for v in value:
-                    print('    ' + v)
+                    print('   ', v)
             else:
-                print('    ' + value.replace('\n', '\n    '))
-    return 0
+                print('   ', value.replace('\n', '\n    '))
 
+
+ at action_help(remove_usage)
+def _remove(distpatcher, args, **kw):
+    opts = _parse_args(args[1:], 'y', [])
+    if 'y' in opts:
+        auto_confirm = True
+    else:
+        auto_confirm = False
+
+    retcode = 0
+    for dist in set(opts['args']):
+        try:
+            remove(dist, auto_confirm=auto_confirm)
+        except PackagingError:
+            logger.warning('%r not installed', dist)
+            retcode = 1
+
+    return retcode
+
+
+ at action_help(run_usage)
 def _run(dispatcher, args, **kw):
     parser = dispatcher.parser
     args = args[1:]
 
     commands = STANDARD_COMMANDS  # + extra commands
 
-    # do we have a global option ?
-    if args in (['--help'], []):
-        print(run_usage)
-        return
-
     if args == ['--list-commands']:
         print('List of available commands:')
-        cmds = list(commands)
-        cmds.sort()
+        cmds = sorted(commands)
 
         for cmd in cmds:
             cls = dispatcher.cmdclass.get(cmd) or get_command_class(cmd)
@@ -160,53 +340,63 @@
     # XXX still need to be extracted from Distribution
     dist.parse_config_files()
 
-
-    try:
-        for cmd in dispatcher.commands:
-            dist.run_command(cmd, dispatcher.command_options[cmd])
-
-    except KeyboardInterrupt:
-        raise SystemExit("interrupted")
-    except (IOError, os.error, DistutilsError, CCompilerError), msg:
-        raise SystemExit("error: " + str(msg))
+    for cmd in dispatcher.commands:
+        dist.run_command(cmd, dispatcher.command_options[cmd])
 
     # XXX this is crappy
     return dist
 
-def _install(dispatcher, args, **kw):
-    install(args[0])
-    return 0
 
-def _remove(distpatcher, args, **kw):
-    remove(options.remove)
-    return 0
+ at action_help(list_usage)
+def _list(dispatcher, args, **kw):
+    opts = _parse_args(args[1:], '', ['all'])
+    dists = get_distributions(use_egg_info=True)
+    if 'all' in opts or opts['args'] == []:
+        results = dists
+        listall = True
+    else:
+        results = (d for d in dists if d.name.lower() in opts['args'])
+        listall = False
 
-def _create(distpatcher, args, **kw):
-    from distutils2.mkcfg import main
-    main()
-    return 0
+    number = 0
+    for dist in results:
+        print('%r %s (from %r)' % (dist.name, dist.version, dist.path))
+        number += 1
 
+    if number == 0:
+        if listall:
+            logger.info('Nothing seems to be installed.')
+        else:
+            logger.warning('No matching distribution found.')
+            return 1
+    else:
+        logger.info('Found %d projects installed.', number)
 
-actions = [('run', 'Run one or several commands', _run),
-           ('metadata', 'Display the metadata of a project', _metadata),
-           ('install', 'Install a project', _install),
-           ('remove', 'Remove a project', _remove),
-           ('search', 'Search for a project', _search),
-           ('graph', 'Display a graph', _graph),
-           ('create', 'Create a Project', _create),]
 
+ at action_help(search_usage)
+def _search(dispatcher, args, **kw):
+    """The search action.
 
+    It is able to search for a specific index (specified with --index), using
+    the simple or xmlrpc index types (with --type xmlrpc / --type simple)
+    """
+    #opts = _parse_args(args[1:], '', ['simple', 'xmlrpc'])
+    # 1. what kind of index is requested ? (xmlrpc / simple)
+    logger.error('not implemented')
+    return 1
 
 
-def fix_help_options(options):
-    """Convert a 4-tuple 'help_options' list as found in various command
-    classes to the 3-tuple form required by FancyGetopt.
-    """
-    new_options = []
-    for help_tuple in options:
-        new_options.append(help_tuple[0:3])
-    return new_options
-
+actions = [
+    ('run', 'Run one or several commands', _run),
+    ('metadata', 'Display the metadata of a project', _metadata),
+    ('install', 'Install a project', _install),
+    ('remove', 'Remove a project', _remove),
+    ('search', 'Search for a project in the indexes', _search),
+    ('list', 'List installed releases', _list),
+    ('graph', 'Display a graph', _graph),
+    ('create', 'Create a project', _create),
+    ('generate-setup', 'Generate a backward-comptatible setup.py', _generate),
+]
 
 
 class Dispatcher(object):
@@ -214,22 +404,21 @@
     """
     def __init__(self, args=None):
         self.verbose = 1
-        self.dry_run = 0
-        self.help = 0
-        self.script_name = 'pysetup'
+        self.dry_run = False
+        self.help = False
         self.cmdclass = {}
         self.commands = []
         self.command_options = {}
 
         for attr in display_option_names:
-            setattr(self, attr, 0)
+            setattr(self, attr, False)
 
         self.parser = FancyGetopt(global_options + display_options)
         self.parser.set_negative_aliases(negative_opt)
+        # FIXME this parses everything, including command options (e.g. "run
+        # build -i" errors with "option -i not recognized")
         args = self.parser.getopt(args=args, object=self)
 
-        #args = args[1:]
-
         # if first arg is "run", we have some commands
         if len(args) == 0:
             self.action = None
@@ -239,31 +428,44 @@
         allowed = [action[0] for action in actions] + [None]
         if self.action not in allowed:
             msg = 'Unrecognized action "%s"' % self.action
-            raise DistutilsArgError(msg)
+            raise PackagingArgError(msg)
 
-        # setting up the logger
-        handler = logging.StreamHandler()
-        logger.addHandler(handler)
-
-        if self.verbose:
-            handler.setLevel(logging.DEBUG)
-        else:
-            handler.setLevel(logging.INFO)
+        self._set_logger()
+        self.args = args
 
         # for display options we return immediately
-        option_order = self.parser.get_option_order()
-
-        self.args = args
-
         if self.help or self.action is None:
             self._show_help(self.parser, display_options_=False)
-            return
+
+    def _set_logger(self):
+        # setting up the logging level from the command-line options
+        # -q gets warning, error and critical
+        if self.verbose == 0:
+            level = logging.WARNING
+        # default level or -v gets info too
+        # XXX there's a bug somewhere: the help text says that -v is default
+        # (and verbose is set to 1 above), but when the user explicitly gives
+        # -v on the command line, self.verbose is incremented to 2!  Here we
+        # compensate for that (I tested manually).  On a related note, I think
+        # it's a good thing to use -q/nothing/-v/-vv on the command line
+        # instead of logging constants; it will be easy to add support for
+        # logging configuration in setup.cfg for advanced users. --merwok
+        elif self.verbose in (1, 2):
+            level = logging.INFO
+        else:  # -vv and more for debug
+            level = logging.DEBUG
+
+        # setting up the stream handler
+        handler = logging.StreamHandler(sys.stderr)
+        handler.setLevel(level)
+        logger.addHandler(handler)
+        logger.setLevel(level)
 
     def _parse_command_opts(self, parser, args):
         # Pull the current command from the head of the command line
         command = args[0]
         if not command_re.match(command):
-            raise SystemExit("invalid command name %r" % command)
+            raise SystemExit("invalid command name %r" % (command,))
         self.commands.append(command)
 
         # Dig up the command class that implements this command, so we
@@ -271,24 +473,24 @@
         # it takes.
         try:
             cmd_class = get_command_class(command)
-        except DistutilsModuleError, msg:
-            raise DistutilsArgError(msg)
+        except PackagingModuleError:
+            raise PackagingArgError(sys.exc_info()[1])
 
-        # XXX We want to push this in distutils.command
+        # XXX We want to push this in distutils2.command
         #
         # Require that the command class be derived from Command -- want
         # to be sure that the basic "command" interface is implemented.
         for meth in ('initialize_options', 'finalize_options', 'run'):
             if hasattr(cmd_class, meth):
                 continue
-            raise DistutilsClassError(
+            raise PackagingClassError(
                 'command %r must implement %r' % (cmd_class, meth))
 
         # Also make sure that the command object provides a list of its
         # known options.
         if not (hasattr(cmd_class, 'user_options') and
                 isinstance(cmd_class.user_options, list)):
-            raise DistutilsClassError(
+            raise PackagingClassError(
                 "command class %s must provide "
                 "'user_options' attribute (a list of tuples)" % cmd_class)
 
@@ -303,7 +505,7 @@
         # format (tuple of four) so we need to preprocess them here.
         if (hasattr(cmd_class, 'help_options') and
             isinstance(cmd_class.help_options, list)):
-            help_options = fix_help_options(cmd_class.help_options)
+            help_options = cmd_class.help_options[:]
         else:
             help_options = []
 
@@ -321,14 +523,14 @@
 
         if (hasattr(cmd_class, 'help_options') and
             isinstance(cmd_class.help_options, list)):
-            help_option_found = 0
-            for (help_option, short, desc, func) in cmd_class.help_options:
+            help_option_found = False
+            for help_option, short, desc, func in cmd_class.help_options:
                 if hasattr(opts, help_option.replace('-', '_')):
-                    help_option_found = 1
+                    help_option_found = True
                     if hasattr(func, '__call__'):
                         func()
                     else:
-                        raise DistutilsClassError(
+                        raise PackagingClassError(
                             "invalid help function %r for help option %r: "
                             "must be a callable object (function, etc.)"
                             % (func, help_option))
@@ -339,7 +541,7 @@
         # Put the options from the command line into their official
         # holding pen, the 'command_options' dictionary.
         opt_dict = self.get_option_dict(command)
-        for (name, value) in vars(opts).iteritems():
+        for name, value in vars(opts).items():
             opt_dict[name] = ("command line", value)
 
         return args
@@ -366,23 +568,23 @@
 
         parser.print_help(usage + "\nGlobal options:")
 
-    def _show_help(self, parser, global_options_=1, display_options_=1,
+    def _show_help(self, parser, global_options_=True, display_options_=True,
                    commands=[]):
         # late import because of mutual dependence between these modules
         from distutils2.command.cmd import Command
 
         print('Usage: pysetup [options] action [action_options]')
-        print('')
+        print()
         if global_options_:
             self.print_usage(self.parser)
-            print('')
+            print()
 
         if display_options_:
             parser.set_option_table(display_options)
             parser.print_help(
                 "Information display options (just display " +
                 "information, ignore any commands)")
-            print('')
+            print()
 
         for command in commands:
             if isinstance(command, type) and issubclass(command, Command):
@@ -391,35 +593,30 @@
                 cls = get_command_class(command)
             if (hasattr(cls, 'help_options') and
                 isinstance(cls.help_options, list)):
-                parser.set_option_table(cls.user_options +
-                                        fix_help_options(cls.help_options))
+                parser.set_option_table(cls.user_options + cls.help_options)
             else:
                 parser.set_option_table(cls.user_options)
 
-
             parser.print_help("Options for %r command:" % cls.__name__)
-            print('')
+            print()
 
     def _show_command_help(self, command):
-        from distutils2.command.cmd import Command
-        if isinstance(command, str):
+        if isinstance(command, basestring):
             command = get_command_class(command)
 
-        name = command.get_command_name()
-
         desc = getattr(command, 'description', '(no description available)')
-        print('Description: %s' % desc)
-        print('')
+        print('Description:', desc)
+        print()
 
         if (hasattr(command, 'help_options') and
             isinstance(command.help_options, list)):
             self.parser.set_option_table(command.user_options +
-                        fix_help_options(command.help_options))
+                                         command.help_options)
         else:
             self.parser.set_option_table(command.user_options)
 
         self.parser.print_help("Options:")
-        print('')
+        print()
 
     def _get_command_groups(self):
         """Helper function to retrieve all the command class names divided
@@ -440,21 +637,16 @@
         'description'.
         """
         std_commands, extra_commands = self._get_command_groups()
-        max_length = 0
-        for cmd in list(std_commands) + list(extra_commands):
-            if len(cmd) > max_length:
-                max_length = len(cmd)
+        max_length = max(len(command)
+                         for commands in (std_commands, extra_commands)
+                         for command in commands)
 
-        self.print_command_list(std_commands,
-                                "Standard commands",
-                                max_length)
+        self.print_command_list(std_commands, "Standard commands", max_length)
         if extra_commands:
-            print
-            self.print_command_list(extra_commands,
-                                    "Extra commands",
+            print()
+            self.print_command_list(extra_commands, "Extra commands",
                                     max_length)
 
-
     def print_command_list(self, commands, header, max_length):
         """Print a subset of the list of all commands -- used by
         'print_commands()'.
@@ -468,10 +660,10 @@
 
             print("  %-*s  %s" % (max_length, cmd, description))
 
-
     def __call__(self):
         if self.action is None:
-            return 0
+            return
+
         for action, desc, func in actions:
             if action == self.action:
                 return func(self, self.args)
@@ -479,11 +671,23 @@
 
 
 def main(args=None):
-    dispatcher = Dispatcher(args)
-    if dispatcher.action is None:
-        return 0
+    old_level = logger.level
+    old_handlers = list(logger.handlers)
+    try:
+        dispatcher = Dispatcher(args)
+        if dispatcher.action is None:
+            return
+        return dispatcher()
+    except KeyboardInterrupt:
+        logger.info('interrupted')
+        return 1
+    except (IOError, os.error, PackagingError, CCompilerError):
+        logger.exception(sys.exc_info()[1])
+        return 1
+    finally:
+        logger.setLevel(old_level)
+        logger.handlers[:] = old_handlers
 
-    return dispatcher()
 
 if __name__ == '__main__':
     sys.exit(main())
diff --git a/distutils2/tests/__init__.py b/distutils2/tests/__init__.py
--- a/distutils2/tests/__init__.py
+++ b/distutils2/tests/__init__.py
@@ -5,39 +5,23 @@
 'test' and contains a function test_suite().  The function is expected
 to return an initialized unittest.TestSuite instance.
 
-Tests for the command classes in the distutils2.command package are
-included in distutils2.tests as well, instead of using a separate
-distutils2.command.tests package, since command identification is done
-by import rather than matching pre-defined names.
+Utility code is included in distutils2.tests.support.
+"""
 
-Always import unittest from this module, it will be the right version
-(standard library unittest for 3.2 and higher, third-party unittest2
-release for older versions).
-
-Utility code is included in distutils2.tests.support.  
-"""
+# Put this text back for the backport
+#Always import unittest from this module, it will be the right version
+#(standard library unittest for 3.2 and higher, third-party unittest2
+#elease for older versions).
 
 import os
 import sys
+import unittest2 as unittest
+from .support import TESTFN
 
-if sys.version_info >= (3, 2):
-    # improved unittest package from 3.2's standard library
-    import unittest
-else:
-    try:
-        # external release of same package for older versions
-        import unittest2 as unittest
-    except ImportError:
-        sys.exit('Error: You have to install unittest2')
-
-# use TESTFN from stdlib, pull in unlink for other modules to use as well
-if sys.version_info[0] == 3:
-  from test.support import TESTFN, unlink
-else :
-  from test.test_support import TESTFN, unlink
+# XXX move helpers to support, add tests for them, remove things that
+# duplicate test.support (or keep them for the backport; needs thinking)
 
 here = os.path.dirname(__file__) or os.curdir
-
 verbose = 1
 
 def test_suite():
@@ -50,6 +34,7 @@
             suite.addTest(module.test_suite())
     return suite
 
+
 class Error(Exception):
     """Base class for regression test exceptions."""
 
@@ -88,12 +73,13 @@
 def run_unittest(classes, verbose_=1):
     """Run tests from unittest.TestCase-derived classes.
 
-    Extracted from stdlib test.test_support and modified to support unittest.
+    Originally extracted from stdlib test.test_support and modified to
+    support unittest2.
     """
     valid_types = (unittest.TestSuite, unittest.TestCase)
     suite = unittest.TestSuite()
     for cls in classes:
-        if isinstance(cls, str):
+        if isinstance(cls, basestring):
             if cls in sys.modules:
                 suite.addTest(unittest.findTestCases(sys.modules[cls]))
             else:
@@ -111,7 +97,7 @@
     stick around to hog resources and create problems when looking
     for refleaks.
 
-    Extracted from stdlib test.test_support.
+    Extracted from stdlib test.support.
     """
 
     # Reap all our dead child processes so we don't leave zombies around.
@@ -127,10 +113,11 @@
             except:
                 break
 
+
 def captured_stdout(func, *args, **kw):
-    import StringIO
+    from StringIO import StringIO
     orig_stdout = getattr(sys, 'stdout')
-    setattr(sys, 'stdout', StringIO.StringIO())
+    setattr(sys, 'stdout', StringIO())
     try:
         res = func(*args, **kw)
         sys.stdout.seek(0)
@@ -138,12 +125,9 @@
     finally:
         setattr(sys, 'stdout', orig_stdout)
 
+
 def unload(name):
     try:
         del sys.modules[name]
     except KeyError:
         pass
-
-
-if __name__ == "__main__":
-    unittest.main(defaultTest="test_suite")
diff --git a/distutils2/tests/__main__.py b/distutils2/tests/__main__.py
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/__main__.py
@@ -0,0 +1,23 @@
+"""Packaging test suite runner."""
+
+# Ripped from importlib tests, thanks Brett!
+
+import os
+import sys
+import unittest2
+from .support import run_unittest, reap_children, reap_threads
+
+
+ at reap_threads
+def test_main():
+    try:
+        start_dir = os.path.dirname(__file__)
+        top_dir = os.path.dirname(os.path.dirname(start_dir))
+        test_loader = unittest2.TestLoader()
+        run_unittest(test_loader.discover(start_dir, top_level_dir=top_dir))
+    finally:
+        reap_children()
+
+
+if __name__ == '__main__':
+    test_main()
diff --git a/distutils2/tests/fake_dists/babar-0.1.dist-info/INSTALLER b/distutils2/tests/fake_dists/babar-0.1.dist-info/INSTALLER
new file mode 100644
diff --git a/distutils2/tests/fake_dists/babar-0.1.dist-info/METADATA b/distutils2/tests/fake_dists/babar-0.1.dist-info/METADATA
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fake_dists/babar-0.1.dist-info/METADATA
@@ -0,0 +1,4 @@
+Metadata-version: 1.2
+Name: babar
+Version: 0.1
+Author: FELD Boris
\ No newline at end of file
diff --git a/distutils2/tests/fake_dists/babar-0.1.dist-info/RECORD b/distutils2/tests/fake_dists/babar-0.1.dist-info/RECORD
new file mode 100644
diff --git a/distutils2/tests/fake_dists/babar-0.1.dist-info/REQUESTED b/distutils2/tests/fake_dists/babar-0.1.dist-info/REQUESTED
new file mode 100644
diff --git a/distutils2/tests/fake_dists/babar-0.1.dist-info/RESOURCES b/distutils2/tests/fake_dists/babar-0.1.dist-info/RESOURCES
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fake_dists/babar-0.1.dist-info/RESOURCES
@@ -0,0 +1,2 @@
+babar.png,babar.png
+babar.cfg,babar.cfg
\ No newline at end of file
diff --git a/distutils2/tests/fake_dists/babar.cfg b/distutils2/tests/fake_dists/babar.cfg
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fake_dists/babar.cfg
@@ -0,0 +1,1 @@
+Config
\ No newline at end of file
diff --git a/distutils2/tests/fake_dists/babar.png b/distutils2/tests/fake_dists/babar.png
new file mode 100644
diff --git a/distutils2/tests/fake_dists/bacon-0.1.egg-info/PKG-INFO b/distutils2/tests/fake_dists/bacon-0.1.egg-info/PKG-INFO
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fake_dists/bacon-0.1.egg-info/PKG-INFO
@@ -0,0 +1,6 @@
+Metadata-Version: 1.2
+Name: bacon
+Version: 0.1
+Provides-Dist: truffles (2.0)
+Provides-Dist: bacon (0.1)
+Obsoletes-Dist: truffles (>=0.9,<=1.5)
diff --git a/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/PKG-INFO b/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/PKG-INFO
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/PKG-INFO
@@ -0,0 +1,18 @@
+Metadata-Version: 1.0
+Name: banana
+Version: 0.4
+Summary: A yellow fruit
+Home-page: http://en.wikipedia.org/wiki/Banana
+Author: Josip Djolonga
+Author-email: foo at nbar.com
+License: BSD
+Description: A fruit
+Keywords: foo bar
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: Science/Research
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Topic :: Scientific/Engineering :: GIS
diff --git a/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/SOURCES.txt b/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/SOURCES.txt
new file mode 100644
diff --git a/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/dependency_links.txt b/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/dependency_links.txt
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/dependency_links.txt
@@ -0,0 +1,1 @@
+
diff --git a/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/entry_points.txt b/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/entry_points.txt
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/entry_points.txt
@@ -0,0 +1,3 @@
+
+      # -*- Entry points: -*-
+      
\ No newline at end of file
diff --git a/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/not-zip-safe b/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/not-zip-safe
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/not-zip-safe
@@ -0,0 +1,1 @@
+
diff --git a/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/requires.txt b/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/requires.txt
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/requires.txt
@@ -0,0 +1,6 @@
+# this should be ignored
+
+strawberry >=0.5
+
+[section ignored]
+foo ==0.5
diff --git a/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/top_level.txt b/distutils2/tests/fake_dists/banana-0.4.egg/EGG-INFO/top_level.txt
new file mode 100644
diff --git a/distutils2/tests/fake_dists/cheese-2.0.2.egg-info b/distutils2/tests/fake_dists/cheese-2.0.2.egg-info
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fake_dists/cheese-2.0.2.egg-info
@@ -0,0 +1,5 @@
+Metadata-Version: 1.2
+Name: cheese
+Version: 2.0.2
+Provides-Dist: truffles (1.0.2)
+Obsoletes-Dist: truffles (!=1.2,<=2.0)
diff --git a/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/INSTALLER b/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/INSTALLER
new file mode 100644
diff --git a/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/METADATA b/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/METADATA
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/METADATA
@@ -0,0 +1,9 @@
+Metadata-Version: 1.2
+Name: choxie
+Version: 2.0.0.9
+Summary: Chocolate with a kick!
+Requires-Dist: towel-stuff (0.1)
+Requires-Dist: nut
+Provides-Dist: truffles (1.0)
+Obsoletes-Dist: truffles (<=0.8,>=0.5)
+Obsoletes-Dist: truffles (<=0.9,>=0.6)
diff --git a/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/RECORD b/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/RECORD
new file mode 100644
diff --git a/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/REQUESTED b/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/REQUESTED
new file mode 100644
diff --git a/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/__init__.py b/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/__init__.py
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/__init__.py
@@ -0,0 +1,1 @@
+# -*- coding: utf-8 -*-
diff --git a/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/chocolate.py b/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/chocolate.py
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/chocolate.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+from towel_stuff import Towel
+
+class Chocolate(object):
+    """A piece of chocolate."""
+
+    def wrap_with_towel(self):
+        towel = Towel()
+        towel.wrap(self)
+        return towel
diff --git a/distutils2/tests/fake_dists/choxie-2.0.0.9/truffles.py b/distutils2/tests/fake_dists/choxie-2.0.0.9/truffles.py
new file mode 100644
--- /dev/null
+++ b/distutils2/tests/fake_dists/choxie-2.0.0.9/truffles.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+from choxie.chocolate import Chocolate
+
+class Truffle(Chocolate):
+    """A truffle."""
diff --git a/distutils2/tests/fake_dists/coconuts-aster-10.3.egg-info/PKG-INFO b/distutils2/tests/fake_dists/coconuts-aster-10.3.egg-info/PKG-INFO
ne