From be0d2fec4f22991a86bed535c166a6ce89a3e74b Mon Sep 17 00:00:00 2001 From: Vivek Teega Date: Fri, 13 Dec 2019 14:42:18 +0530 Subject: [PATCH] Checkpoint while working on flosight change - lots of changes in this commit - currently right before changing how the system handles smart contract transactions --- .gitignore | 1 + .vscode/settings.json | 3 + config.ini | 4 +- config.pyc | Bin 0 -> 352 bytes cronjob.sh | 2 +- models.py | 70 +- models.pyc | Bin 0 -> 5777 bytes parsing.py | 43 +- parsing.pyc | Bin 0 -> 10323 bytes py3/bin/activate | 2 +- py3/bin/activate.csh | 2 +- py3/bin/activate.fish | 2 +- py3/bin/chardetect | 2 +- py3/bin/easy_install | 2 +- py3/bin/easy_install-3.6 | 2 +- py3/bin/epylint | 11 + py3/bin/isort | 11 + py3/bin/pip | 2 +- py3/bin/pip3 | 2 +- py3/bin/pip3.6 | 2 +- py3/bin/pylint | 11 + py3/bin/pyreverse | 11 + py3/bin/symilar | 11 + .../PKG-INFO | 2 +- .../SOURCES.txt | 3 + .../dependency_links.txt | 0 .../installed-files.txt | 0 .../requires.txt | 0 .../top_level.txt | 0 .../site-packages/_markerlib/__init__.py | 16 - .../site-packages/_markerlib/markers.py | 119 - .../arrow-0.14.6.dist-info/LICENSE | 13 - .../arrow-0.14.6.dist-info/RECORD | 24 - .../INSTALLER | 0 .../arrow-0.15.4.dist-info/LICENSE | 201 + .../METADATA | 6 +- .../arrow-0.15.4.dist-info/RECORD | 26 + .../WHEEL | 0 .../top_level.txt | 0 .../python3.6/site-packages/arrow/__init__.py | 1 + .../python3.6/site-packages/arrow/_version.py | 2 +- .../python3.6/site-packages/arrow/arrow.py | 32 +- .../site-packages/arrow/constants.py | 9 + .../python3.6/site-packages/arrow/factory.py | 77 +- .../site-packages/arrow/formatter.py | 9 +- .../python3.6/site-packages/arrow/locales.py | 24 +- .../python3.6/site-packages/arrow/parser.py | 348 +- py3/lib/python3.6/site-packages/arrow/util.py | 91 +- .../astroid-2.3.3.dist-info/COPYING | 339 + .../astroid-2.3.3.dist-info/COPYING.LESSER | 510 ++ .../INSTALLER | 0 .../astroid-2.3.3.dist-info/METADATA | 117 + .../astroid-2.3.3.dist-info/RECORD | 145 + .../astroid-2.3.3.dist-info/WHEEL | 5 + .../astroid-2.3.3.dist-info/top_level.txt | 1 + .../site-packages/astroid/__init__.py | 166 + .../site-packages/astroid/__pkginfo__.py | 51 + .../python3.6/site-packages/astroid/_ast.py | 49 + .../site-packages/astroid/arguments.py | 285 + .../site-packages/astroid/as_string.py | 633 ++ .../python3.6/site-packages/astroid/bases.py | 542 ++ .../astroid/brain/brain_argparse.py | 33 + .../astroid/brain/brain_attrs.py | 65 + .../astroid/brain/brain_builtin_inference.py | 829 +++ .../astroid/brain/brain_collections.py | 74 + .../astroid/brain/brain_crypt.py | 26 + .../astroid/brain/brain_curses.py | 179 + .../astroid/brain/brain_dataclasses.py | 50 + .../astroid/brain/brain_dateutil.py | 28 + .../astroid/brain/brain_fstrings.py | 51 + .../astroid/brain/brain_functools.py | 158 + .../site-packages/astroid/brain/brain_gi.py | 220 + .../astroid/brain/brain_hashlib.py | 67 + .../site-packages/astroid/brain/brain_http.py | 201 + .../site-packages/astroid/brain/brain_io.py | 45 + .../astroid/brain/brain_mechanize.py | 29 + .../astroid/brain/brain_multiprocessing.py | 106 + .../astroid/brain/brain_namedtuple_enum.py | 449 ++ .../site-packages/astroid/brain/brain_nose.py | 77 + .../brain/brain_numpy_core_fromnumeric.py | 23 + .../brain/brain_numpy_core_function_base.py | 29 + .../brain/brain_numpy_core_multiarray.py | 55 + .../astroid/brain/brain_numpy_core_numeric.py | 43 + .../brain/brain_numpy_core_numerictypes.py | 250 + .../astroid/brain/brain_numpy_core_umath.py | 105 + .../astroid/brain/brain_numpy_ndarray.py | 153 + .../brain/brain_numpy_random_mtrand.py | 70 + .../astroid/brain/brain_numpy_utils.py | 56 + .../astroid/brain/brain_pkg_resources.py | 75 + .../astroid/brain/brain_pytest.py | 88 + .../site-packages/astroid/brain/brain_qt.py | 82 + .../astroid/brain/brain_random.py | 75 + .../site-packages/astroid/brain/brain_re.py | 36 + .../site-packages/astroid/brain/brain_six.py | 200 + .../site-packages/astroid/brain/brain_ssl.py | 74 + .../astroid/brain/brain_subprocess.py | 111 + .../astroid/brain/brain_threading.py | 31 + .../astroid/brain/brain_typing.py | 96 + .../site-packages/astroid/brain/brain_uuid.py | 20 + .../site-packages/astroid/builder.py | 435 ++ .../site-packages/astroid/context.py | 179 + .../site-packages/astroid/decorators.py | 141 + .../site-packages/astroid/exceptions.py | 230 + .../site-packages/astroid/helpers.py | 273 + .../site-packages/astroid/inference.py | 943 +++ .../tests => astroid/interpreter}/__init__.py | 0 .../astroid/interpreter/_import/__init__.py | 0 .../astroid/interpreter/_import/spec.py | 344 + .../astroid/interpreter/_import/util.py | 10 + .../astroid/interpreter/dunder_lookup.py | 66 + .../astroid/interpreter/objectmodel.py | 738 +++ .../site-packages/astroid/manager.py | 337 + .../python3.6/site-packages/astroid/mixins.py | 160 + .../site-packages/astroid/modutils.py | 698 ++ .../site-packages/astroid/node_classes.py | 4775 ++++++++++++++ .../python3.6/site-packages/astroid/nodes.py | 175 + .../site-packages/astroid/objects.py | 282 + .../site-packages/astroid/protocols.py | 766 +++ .../site-packages/astroid/raw_building.py | 468 ++ .../site-packages/astroid/rebuilder.py | 1090 ++++ .../site-packages/astroid/scoped_nodes.py | 2836 ++++++++ .../site-packages/astroid/test_utils.py | 73 + .../site-packages/astroid/transforms.py | 90 + .../python3.6/site-packages/astroid/util.py | 164 + .../certifi-2019.6.16.dist-info/LICENSE.txt | 21 - .../certifi-2019.6.16.dist-info/RECORD | 15 - .../DESCRIPTION.rst | 0 .../INSTALLER | 0 .../METADATA | 2 +- .../certifi-2019.9.11.dist-info/RECORD | 14 + .../WHEEL | 0 .../metadata.json | 2 +- .../top_level.txt | 0 .../site-packages/certifi/__init__.py | 2 +- .../site-packages/certifi/cacert.pem | 60 - .../libffi-ae16d830.so.6.0.4 | Bin 149064 -> 0 bytes ...fi_backend.cpython-36m-x86_64-linux-gnu.so | Bin 849704 -> 0 bytes .../libffi-806b1a9d.so.6.0.4 | Bin 0 -> 46632 bytes .../EGG-INFO/LICENSE.txt | 0 .../EGG-INFO/PKG-INFO | 2 +- .../EGG-INFO/RECORD | 44 +- .../EGG-INFO/WHEEL | 0 .../EGG-INFO/entry_points.txt | 0 .../EGG-INFO/requires.txt | 0 .../EGG-INFO/top_level.txt | 0 ...fi_backend.cpython-36m-x86_64-linux-gnu.so | Bin 0 -> 849704 bytes .../cffi/__init__.py | 4 +- .../cffi/_cffi_errors.h | 0 .../cffi/_cffi_include.h | 0 .../cffi/_embedding.h | 18 +- .../cffi/api.py | 0 .../cffi/backend_ctypes.py | 2 +- .../cffi/cffi_opcode.py | 0 .../cffi/commontypes.py | 0 .../cffi/cparser.py | 60 +- .../cffi/error.py | 0 .../cffi/ffiplatform.py | 0 .../cffi/lock.py | 0 .../cffi/model.py | 0 .../cffi/parse_c_type.h | 0 .../cffi/pkgconfig.py | 0 .../cffi/recompiler.py | 5 +- .../cffi/setuptools_ext.py | 0 .../cffi/vengine_cpy.py | 0 .../cffi/vengine_gen.py | 0 .../cffi/verifier.py | 0 .../chardet-3.0.4.dist-info/RECORD | 2 +- .../site-packages/dateutil/_version.py | 2 +- .../site-packages/dateutil/parser/__init__.py | 3 +- .../site-packages/dateutil/parser/_parser.py | 117 +- .../dateutil/parser/isoparser.py | 4 +- .../site-packages/dateutil/relativedelta.py | 2 +- .../python3.6/site-packages/dateutil/rrule.py | 3 +- .../site-packages/dateutil/tz/__init__.py | 5 - .../site-packages/dateutil/tz/_common.py | 4 +- .../site-packages/dateutil/tz/_factories.py | 29 +- .../python3.6/site-packages/dateutil/tz/tz.py | 25 +- .../python3.6/site-packages/dateutil/utils.py | 2 +- .../zoneinfo/dateutil-zoneinfo.tar.gz | Bin 154405 -> 153315 bytes .../python3.6/site-packages/easy-install.pth | 2 +- .../site-packages/engineio/__init__.py | 2 +- .../site-packages/engineio/asyncio_client.py | 34 +- .../site-packages/engineio/asyncio_server.py | 6 +- .../site-packages/engineio/asyncio_socket.py | 3 +- .../site-packages/engineio/client.py | 38 +- .../site-packages/engineio/payload.py | 55 +- .../site-packages/engineio/server.py | 15 +- .../site-packages/engineio/socket.py | 3 +- .../INSTALLER | 0 .../isort-4.3.21.dist-info/LICENSE | 21 + .../isort-4.3.21.dist-info/METADATA | 697 ++ .../isort-4.3.21.dist-info/RECORD | 30 + .../WHEEL | 0 .../isort-4.3.21.dist-info/entry_points.txt | 9 + .../isort-4.3.21.dist-info/top_level.txt | 1 + .../python3.6/site-packages/isort/__init__.py | 28 + .../python3.6/site-packages/isort/__main__.py | 9 + .../python3.6/site-packages/isort/finders.py | 382 ++ .../python3.6/site-packages/isort/hooks.py | 91 + .../python3.6/site-packages/isort/isort.py | 1060 +++ py3/lib/python3.6/site-packages/isort/main.py | 401 ++ .../python3.6/site-packages/isort/natural.py | 47 + .../site-packages/isort/pie_slice.py | 154 + .../site-packages/isort/pylama_isort.py | 29 + .../python3.6/site-packages/isort/settings.py | 356 ++ .../python3.6/site-packages/isort/utils.py | 53 + .../INSTALLER | 0 .../METADATA | 166 + .../lazy_object_proxy-1.4.3.dist-info/RECORD | 18 + .../lazy_object_proxy-1.4.3.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../lazy_object_proxy/__init__.py | 23 + .../lazy_object_proxy/_version.py | 4 + .../cext.cpython-36m-x86_64-linux-gnu.so | Bin 0 -> 160608 bytes .../site-packages/lazy_object_proxy/compat.py | 9 + .../site-packages/lazy_object_proxy/simple.py | 246 + .../site-packages/lazy_object_proxy/slots.py | 414 ++ .../site-packages/lazy_object_proxy/utils.py | 13 + .../mccabe-0.6.1.dist-info/DESCRIPTION.rst | 152 + .../INSTALLER | 0 .../mccabe-0.6.1.dist-info/METADATA | 178 + .../mccabe-0.6.1.dist-info/RECORD | 10 + .../WHEEL | 2 +- .../mccabe-0.6.1.dist-info/entry_points.txt | 3 + .../mccabe-0.6.1.dist-info/metadata.json | 1 + .../mccabe-0.6.1.dist-info/top_level.txt | 1 + py3/lib/python3.6/site-packages/mccabe.py | 347 + .../netifaces-0.10.6.egg-info/PKG-INFO | 217 - .../netifaces-0.10.6.egg-info/SOURCES.txt | 9 - .../installed-files.txt | 6 - .../netifaces-0.10.6.egg-info/top_level.txt | 1 - .../netifaces.cpython-36m-x86_64-linux-gnu.so | Bin 73704 -> 0 bytes .../site-packages/pip-9.0.1.dist-info/RECORD | 6 +- .../python3.6/site-packages/pkg_resources.py | 2762 -------- .../pylint-2.4.4.dist-info/COPYING | 340 + .../INSTALLER | 0 .../pylint-2.4.4.dist-info/METADATA | 202 + .../pylint-2.4.4.dist-info/RECORD | 161 + .../pylint-2.4.4.dist-info/WHEEL | 5 + .../pylint-2.4.4.dist-info/entry_points.txt | 6 + .../pylint-2.4.4.dist-info/top_level.txt | 1 + .../site-packages/pylint/__init__.py | 43 + .../site-packages/pylint/__main__.py | 7 + .../site-packages/pylint/__pkginfo__.py | 85 + .../site-packages/pylint/checkers/__init__.py | 64 + .../site-packages/pylint/checkers/async.py | 89 + .../site-packages/pylint/checkers/base.py | 2333 +++++++ .../pylint/checkers/base_checker.py | 187 + .../site-packages/pylint/checkers/classes.py | 1844 ++++++ .../pylint/checkers/design_analysis.py | 496 ++ .../pylint/checkers/exceptions.py | 546 ++ .../site-packages/pylint/checkers/format.py | 1332 ++++ .../site-packages/pylint/checkers/imports.py | 981 +++ .../site-packages/pylint/checkers/logging.py | 384 ++ .../site-packages/pylint/checkers/misc.py | 171 + .../site-packages/pylint/checkers/newstyle.py | 127 + .../site-packages/pylint/checkers/python3.py | 1398 ++++ .../pylint/checkers/raw_metrics.py | 119 + .../pylint/checkers/refactoring.py | 1510 +++++ .../site-packages/pylint/checkers/similar.py | 452 ++ .../site-packages/pylint/checkers/spelling.py | 411 ++ .../site-packages/pylint/checkers/stdlib.py | 452 ++ .../site-packages/pylint/checkers/strings.py | 755 +++ .../pylint/checkers/typecheck.py | 1770 +++++ .../site-packages/pylint/checkers/utils.py | 1253 ++++ .../pylint/checkers/variables.py | 1987 ++++++ .../site-packages/pylint/constants.py | 43 + .../python3.6/site-packages/pylint/epylint.py | 197 + .../site-packages/pylint/exceptions.py | 29 + .../pylint/extensions/__init__.py | 0 .../pylint/extensions/_check_docs_utils.py | 792 +++ .../pylint/extensions/bad_builtin.py | 69 + .../pylint/extensions/broad_try_clause.py | 59 + .../pylint/extensions/check_docs.py | 23 + .../pylint/extensions/check_elif.py | 77 + .../pylint/extensions/comparetozero.py | 74 + .../pylint/extensions/docparams.py | 536 ++ .../pylint/extensions/docstyle.py | 89 + .../pylint/extensions/emptystring.py | 74 + .../site-packages/pylint/extensions/mccabe.py | 196 + .../extensions/overlapping_exceptions.py | 88 + .../extensions/redefined_variable_type.py | 116 + .../python3.6/site-packages/pylint/graph.py | 197 + .../site-packages/pylint/interfaces.py | 102 + .../python3.6/site-packages/pylint/lint.py | 1817 ++++++ .../site-packages/pylint/message/__init__.py | 54 + .../site-packages/pylint/message/message.py | 53 + .../pylint/message/message_definition.py | 84 + .../message/message_definition_store.py | 90 + .../pylint/message/message_handler_mix_in.py | 393 ++ .../pylint/message/message_id_store.py | 128 + .../pylint/pyreverse/__init__.py | 8 + .../pylint/pyreverse/diadefslib.py | 238 + .../pylint/pyreverse/diagrams.py | 268 + .../pylint/pyreverse/inspector.py | 357 ++ .../site-packages/pylint/pyreverse/main.py | 214 + .../site-packages/pylint/pyreverse/utils.py | 220 + .../pylint/pyreverse/vcgutils.py | 229 + .../site-packages/pylint/pyreverse/writer.py | 213 + .../pylint/reporters/__init__.py | 34 + .../pylint/reporters/base_reporter.py | 66 + .../pylint/reporters/collecting_reporter.py | 21 + .../pylint/reporters/json_reporter.py | 58 + .../reporters/reports_handler_mix_in.py | 79 + .../site-packages/pylint/reporters/text.py | 247 + .../pylint/reporters/ureports/__init__.py | 96 + .../pylint/reporters/ureports/nodes.py | 188 + .../pylint/reporters/ureports/text_writer.py | 94 + .../site-packages/pylint/testutils.py | 298 + .../site-packages/pylint/utils/__init__.py | 64 + .../site-packages/pylint/utils/ast_walker.py | 79 + .../site-packages/pylint/utils/file_state.py | 138 + .../site-packages/pylint/utils/utils.py | 371 ++ .../INSTALLER | 0 .../LICENSE | 0 .../METADATA | 19 +- .../RECORD | 38 +- .../WHEEL | 2 +- .../top_level.txt | 0 .../zip-safe | 0 .../INSTALLER | 1 + .../LICENSE | 0 .../METADATA | 2 +- .../RECORD | 28 +- .../python_engineio-3.10.0.dist-info/WHEEL | 6 + .../top_level.txt | 0 .../python_socketio-4.4.0.dist-info/INSTALLER | 1 + .../LICENSE | 0 .../METADATA | 2 +- .../RECORD | 24 +- .../python_socketio-4.4.0.dist-info/WHEEL | 6 + .../top_level.txt | 0 ...bsecp256k1.cpython-36m-x86_64-linux-gnu.so | Bin 119296 -> 119296 bytes .../setuptools-3.3.dist-info/DESCRIPTION.rst | 1854 ------ .../setuptools-3.3.dist-info/METADATA | 1885 ------ .../setuptools-3.3.dist-info/RECORD | 154 - .../setuptools-3.3.dist-info/WHEEL | 6 - .../dependency_links.txt | 2 - .../dependency_links.txt.orig | 2 - .../entry_points.txt.orig | 62 - .../setuptools-3.3.dist-info/pydist.json | 1 - .../requires.txt.orig | 7 - .../setuptools-3.3.dist-info/zip-safe | 1 - .../DESCRIPTION.rst | 36 + .../setuptools-39.0.1.dist-info/INSTALLER | 1 + .../setuptools-39.0.1.dist-info/METADATA | 67 + .../setuptools-39.0.1.dist-info/RECORD | 155 + .../setuptools-39.0.1.dist-info/WHEEL | 6 + .../dependency_links.txt | 2 + .../entry_points.txt | 120 +- .../setuptools-39.0.1.dist-info/metadata.json | 1 + .../top_level.txt | 3 +- .../zip-safe | 0 .../site-packages/setuptools/__init__.py | 199 +- .../setuptools/_vendor/__init__.py | 0 .../setuptools/_vendor/packaging/__about__.py | 21 + .../setuptools/_vendor/packaging/__init__.py | 14 + .../setuptools/_vendor/packaging/_compat.py | 30 + .../_vendor/packaging/_structures.py | 68 + .../setuptools/_vendor/packaging/markers.py | 301 + .../_vendor/packaging/requirements.py | 127 + .../_vendor/packaging/specifiers.py | 774 +++ .../setuptools/_vendor/packaging/utils.py | 14 + .../setuptools/_vendor/packaging/version.py | 393 ++ .../setuptools/_vendor/pyparsing.py | 5696 +++++++++++++++++ .../site-packages/setuptools/_vendor/six.py | 868 +++ .../site-packages/setuptools/archive_util.py | 113 +- .../site-packages/setuptools/build_meta.py | 172 + .../site-packages/setuptools/cli-32.exe | Bin .../site-packages/setuptools/cli-64.exe | Bin .../site-packages/setuptools/cli-arm-32.exe | Bin 69120 -> 0 bytes .../site-packages/setuptools/cli.exe | Bin .../setuptools/command/__init__.py | 7 +- .../site-packages/setuptools/command/alias.py | 16 +- .../setuptools/command/bdist_egg.py | 333 +- .../setuptools/command/bdist_rpm.py | 83 +- .../setuptools/command/bdist_wininst.py | 7 +- .../setuptools/command/build_clib.py | 98 + .../setuptools/command/build_ext.py | 248 +- .../setuptools/command/build_py.py | 219 +- .../setuptools/command/develop.py | 129 +- .../setuptools/command/dist_info.py | 36 + .../setuptools/command/easy_install.py | 1754 +++-- .../setuptools/command/egg_info.py | 542 +- .../setuptools/command/install.py | 87 +- .../setuptools/command/install_egg_info.py | 121 +- .../setuptools/command/install_lib.py | 125 +- .../setuptools/command/install_scripts.py | 44 +- .../setuptools/command/launcher manifest.xml | 18 +- .../setuptools/command/py36compat.py | 136 + .../setuptools/command/register.py | 10 +- .../setuptools/command/rotate.py | 32 +- .../setuptools/command/saveopts.py | 14 +- .../site-packages/setuptools/command/sdist.py | 210 +- .../setuptools/command/setopt.py | 48 +- .../site-packages/setuptools/command/test.py | 215 +- .../setuptools/command/upload.py | 42 + .../setuptools/command/upload_docs.py | 145 +- .../site-packages/setuptools/compat.py | 83 - .../site-packages/setuptools/dep_util.py | 23 + .../site-packages/setuptools/depends.py | 164 +- .../site-packages/setuptools/dist.py | 669 +- .../site-packages/setuptools/extension.py | 48 +- .../setuptools/extern/__init__.py | 73 + .../site-packages/setuptools/glibc.py | 86 + .../site-packages/setuptools/glob.py | 176 + .../site-packages/setuptools/gui-32.exe | Bin .../site-packages/setuptools/gui-64.exe | Bin .../site-packages/setuptools/gui-arm-32.exe | Bin 69120 -> 0 bytes .../site-packages/setuptools/gui.exe | Bin .../site-packages/setuptools/launch.py | 35 + .../site-packages/setuptools/lib2to3_ex.py | 10 +- .../site-packages/setuptools/monkey.py | 197 + .../site-packages/setuptools/msvc.py | 1302 ++++ .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/package_index.py | 511 +- .../site-packages/setuptools/pep425tags.py | 316 + .../site-packages/setuptools/py26compat.py | 19 - .../site-packages/setuptools/py27compat.py | 29 +- .../site-packages/setuptools/py31compat.py | 12 +- .../site-packages/setuptools/py33compat.py | 54 + .../site-packages/setuptools/py36compat.py | 82 + .../site-packages/setuptools/sandbox.py | 427 +- .../setuptools/script (dev).tmpl | 5 + .../setuptools/script template (dev).py | 11 - .../setuptools/script template.py | 4 - .../site-packages/setuptools/script.tmpl | 3 + .../site-packages/setuptools/site-patch.py | 30 +- .../site-packages/setuptools/ssl_support.py | 106 +- .../site-packages/setuptools/svn_utils.py | 583 -- .../setuptools/tests/__init__.py | 352 - .../site-packages/setuptools/tests/doctest.py | 2683 -------- .../setuptools/tests/environment.py | 165 - .../setuptools/tests/py26compat.py | 14 - .../setuptools/tests/script-with-bom.py | 3 - .../site-packages/setuptools/tests/server.py | 82 - .../setuptools/tests/test_bdist_egg.py | 72 - .../setuptools/tests/test_build_ext.py | 19 - .../setuptools/tests/test_develop.py | 124 - .../setuptools/tests/test_dist_info.py | 83 - .../setuptools/tests/test_easy_install.py | 457 -- .../setuptools/tests/test_egg_info.py | 173 - .../setuptools/tests/test_find_packages.py | 82 - .../setuptools/tests/test_markerlib.py | 68 - .../setuptools/tests/test_packageindex.py | 203 - .../setuptools/tests/test_resources.py | 620 -- .../setuptools/tests/test_sandbox.py | 79 - .../setuptools/tests/test_sdist.py | 535 -- .../setuptools/tests/test_svn.py | 245 - .../setuptools/tests/test_test.py | 126 - .../setuptools/tests/test_upload_docs.py | 72 - .../site-packages/setuptools/unicode_utils.py | 44 + .../site-packages/setuptools/version.py | 7 +- .../site-packages/setuptools/wheel.py | 163 + .../setuptools/windows_support.py | 29 + .../site-packages/six-1.12.0.dist-info/RECORD | 8 - .../site-packages/six-1.12.0.dist-info/WHEEL | 6 - .../six-1.13.0.dist-info/INSTALLER | 1 + .../LICENSE | 2 +- .../METADATA | 2 +- .../site-packages/six-1.13.0.dist-info/RECORD | 8 + .../site-packages/six-1.13.0.dist-info/WHEEL | 6 + .../top_level.txt | 0 py3/lib/python3.6/site-packages/six.py | 17 +- .../socketio-0.2.1-py3.6.egg-info/PKG-INFO | 14 - .../socketio-0.2.1-py3.6.egg-info/SOURCES.txt | 13 - .../dependency_links.txt | 1 - .../installed-files.txt | 16 - .../requires.txt | 2 - .../top_level.txt | 1 - .../site-packages/socketio/__init__.py | 2 +- .../site-packages/socketio/asyncio_client.py | 15 +- .../site-packages/socketio/asyncio_server.py | 5 +- .../site-packages/socketio/client.py | 15 +- .../site-packages/socketio/exceptions.py | 2 +- .../site-packages/socketio/server.py | 5 +- .../socketio/tests/performance_test.py | 161 - .../site-packages/sqlalchemy/__init__.py | 3 +- ...processors.cpython-36m-x86_64-linux-gnu.so | Bin 52616 -> 52616 bytes ...esultproxy.cpython-36m-x86_64-linux-gnu.so | Bin 62552 -> 62552 bytes .../cutils.cpython-36m-x86_64-linux-gnu.so | Bin 34936 -> 34936 bytes .../sqlalchemy/dialects/firebird/base.py | 37 +- .../dialects/firebird/kinterbasdb.py | 3 +- .../sqlalchemy/dialects/mssql/base.py | 58 +- .../sqlalchemy/dialects/mssql/pyodbc.py | 31 +- .../sqlalchemy/dialects/mysql/base.py | 61 +- .../sqlalchemy/dialects/mysql/pymysql.py | 5 +- .../sqlalchemy/dialects/mysql/pyodbc.py | 12 + .../sqlalchemy/dialects/oracle/base.py | 206 +- .../sqlalchemy/dialects/oracle/cx_oracle.py | 56 +- .../sqlalchemy/dialects/postgresql/base.py | 50 +- .../sqlalchemy/dialects/postgresql/json.py | 7 +- .../sqlalchemy/dialects/sqlite/base.py | 21 +- .../sqlalchemy/dialects/sqlite/pysqlite.py | 163 +- .../sqlalchemy/engine/__init__.py | 25 +- .../site-packages/sqlalchemy/engine/base.py | 45 +- .../sqlalchemy/engine/default.py | 90 +- .../sqlalchemy/engine/reflection.py | 6 +- .../python3.6/site-packages/sqlalchemy/exc.py | 16 +- .../site-packages/sqlalchemy/ext/baked.py | 12 +- .../site-packages/sqlalchemy/orm/events.py | 46 +- .../site-packages/sqlalchemy/orm/identity.py | 8 +- .../site-packages/sqlalchemy/orm/loading.py | 12 +- .../sqlalchemy/orm/persistence.py | 1 - .../site-packages/sqlalchemy/orm/query.py | 102 +- .../sqlalchemy/orm/relationships.py | 30 +- .../site-packages/sqlalchemy/orm/session.py | 15 +- .../sqlalchemy/orm/strategies.py | 30 +- .../site-packages/sqlalchemy/schema.py | 1 + .../site-packages/sqlalchemy/sql/compiler.py | 25 +- .../site-packages/sqlalchemy/sql/elements.py | 91 +- .../site-packages/sqlalchemy/sql/functions.py | 185 +- .../site-packages/sqlalchemy/sql/naming.py | 2 +- .../site-packages/sqlalchemy/sql/operators.py | 6 + .../site-packages/sqlalchemy/sql/schema.py | 122 +- .../site-packages/sqlalchemy/sql/sqltypes.py | 198 +- .../site-packages/sqlalchemy/sql/util.py | 20 +- .../site-packages/sqlalchemy/sql/visitors.py | 168 +- .../sqlalchemy/testing/__init__.py | 4 + .../sqlalchemy/testing/assertions.py | 14 + .../sqlalchemy/testing/assertsql.py | 15 +- .../sqlalchemy/testing/exclusions.py | 75 +- .../sqlalchemy/testing/fixtures.py | 2 +- .../sqlalchemy/testing/plugin/plugin_base.py | 53 +- .../sqlalchemy/testing/plugin/pytestplugin.py | 184 +- .../sqlalchemy/testing/requirements.py | 56 + .../sqlalchemy/testing/suite/test_select.py | 46 + .../sqlalchemy/testing/suite/test_types.py | 418 +- .../site-packages/sqlalchemy/testing/util.py | 24 + .../sqlalchemy/testing/warnings.py | 7 + .../sqlalchemy/util/langhelpers.py | 9 +- .../typed_ast-1.4.0.dist-info/INSTALLER | 1 + .../typed_ast-1.4.0.dist-info/METADATA | 28 + .../typed_ast-1.4.0.dist-info/RECORD | 17 + .../typed_ast-1.4.0.dist-info/WHEEL | 5 + .../typed_ast-1.4.0.dist-info/top_level.txt | 3 + .../site-packages/typed_ast/__init__.py | 1 + .../_ast27.cpython-36m-x86_64-linux-gnu.so | Bin 0 -> 1023657 bytes .../_ast3.cpython-36m-x86_64-linux-gnu.so | Bin 0 -> 1318859 bytes .../site-packages/typed_ast/ast27.py | 324 + .../python3.6/site-packages/typed_ast/ast3.py | 348 + .../site-packages/typed_ast/conversions.py | 232 + .../typed_ast/tests/test_basics.py | 326 + .../urllib3-1.25.3.dist-info/RECORD | 104 - .../urllib3-1.25.3.dist-info/WHEEL | 6 - .../urllib3-1.25.7.dist-info/INSTALLER | 1 + .../LICENSE.txt | 0 .../METADATA | 91 +- .../urllib3-1.25.7.dist-info/RECORD | 78 + .../urllib3-1.25.7.dist-info/WHEEL | 6 + .../top_level.txt | 0 .../site-packages/urllib3/__init__.py | 55 +- .../site-packages/urllib3/_collections.py | 37 +- .../site-packages/urllib3/connection.py | 183 +- .../site-packages/urllib3/connectionpool.py | 412 +- .../urllib3/contrib/_appengine_environ.py | 26 +- .../contrib/_securetransport/bindings.py | 262 +- .../contrib/_securetransport/low_level.py | 52 +- .../urllib3/contrib/appengine.py | 121 +- .../site-packages/urllib3/contrib/ntlmpool.py | 96 +- .../urllib3/contrib/pyopenssl.py | 129 +- .../urllib3/contrib/securetransport.py | 160 +- .../site-packages/urllib3/contrib/socks.py | 101 +- .../site-packages/urllib3/exceptions.py | 29 +- .../python3.6/site-packages/urllib3/fields.py | 93 +- .../site-packages/urllib3/filepost.py | 14 +- .../urllib3/packages/__init__.py | 2 +- .../urllib3/packages/backports/makefile.py | 9 +- .../urllib3/packages/rfc3986/__init__.py | 56 - .../urllib3/packages/rfc3986/_mixin.py | 353 - .../urllib3/packages/rfc3986/abnf_regexp.py | 267 - .../urllib3/packages/rfc3986/api.py | 106 - .../urllib3/packages/rfc3986/builder.py | 298 - .../urllib3/packages/rfc3986/compat.py | 54 - .../urllib3/packages/rfc3986/exceptions.py | 118 - .../urllib3/packages/rfc3986/iri.py | 147 - .../urllib3/packages/rfc3986/misc.py | 124 - .../urllib3/packages/rfc3986/normalizers.py | 167 - .../urllib3/packages/rfc3986/parseresult.py | 385 -- .../urllib3/packages/rfc3986/uri.py | 153 - .../urllib3/packages/rfc3986/validators.py | 450 -- .../site-packages/urllib3/packages/six.py | 323 +- .../packages/ssl_match_hostname/__init__.py | 2 +- .../ssl_match_hostname/_implementation.py | 56 +- .../site-packages/urllib3/poolmanager.py | 183 +- .../site-packages/urllib3/request.py | 79 +- .../site-packages/urllib3/response.py | 195 +- .../site-packages/urllib3/util/__init__.py | 60 +- .../site-packages/urllib3/util/connection.py | 18 +- .../site-packages/urllib3/util/request.py | 52 +- .../site-packages/urllib3/util/response.py | 9 +- .../site-packages/urllib3/util/retry.py | 100 +- .../site-packages/urllib3/util/ssl_.py | 175 +- .../site-packages/urllib3/util/timeout.py | 79 +- .../site-packages/urllib3/util/url.py | 355 +- .../site-packages/urllib3/util/wait.py | 3 + .../wrapt-1.11.2.egg-info/PKG-INFO | 166 + .../wrapt-1.11.2.egg-info/SOURCES.txt | 10 + .../dependency_links.txt | 0 .../wrapt-1.11.2.egg-info/installed-files.txt | 13 + .../wrapt-1.11.2.egg-info/top_level.txt | 1 + .../python3.6/site-packages/wrapt/__init__.py | 16 + .../_wrappers.cpython-36m-x86_64-linux-gnu.so | Bin 0 -> 148384 bytes .../site-packages/wrapt/decorators.py | 514 ++ .../python3.6/site-packages/wrapt/importer.py | 230 + .../python3.6/site-packages/wrapt/wrappers.py | 943 +++ ranchimallflo-api/.gitignore | 6 - ranchimallflo-api/config-example.py | 2 - ranchimallflo-api/parsing.py | 374 -- ranchimallflo-api/ranchimallflo_api.py | 643 -- ranchimallflo-api/static/broadcast.js | 24 - ranchimallflo-api/templates/index.html | 12 - tracktokens-smartcontracts.py | 1027 ++- 613 files changed, 81445 insertions(+), 23815 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 config.pyc create mode 100644 models.pyc create mode 100644 parsing.pyc create mode 100755 py3/bin/epylint create mode 100755 py3/bin/isort create mode 100755 py3/bin/pylint create mode 100755 py3/bin/pyreverse create mode 100755 py3/bin/symilar rename py3/lib/python3.6/site-packages/{SQLAlchemy-1.3.8.egg-info => SQLAlchemy-1.3.11.egg-info}/PKG-INFO (99%) rename py3/lib/python3.6/site-packages/{SQLAlchemy-1.3.8.egg-info => SQLAlchemy-1.3.11.egg-info}/SOURCES.txt (99%) rename py3/lib/python3.6/site-packages/{SQLAlchemy-1.3.8.egg-info => SQLAlchemy-1.3.11.egg-info}/dependency_links.txt (100%) rename py3/lib/python3.6/site-packages/{SQLAlchemy-1.3.8.egg-info => SQLAlchemy-1.3.11.egg-info}/installed-files.txt (100%) rename py3/lib/python3.6/site-packages/{SQLAlchemy-1.3.8.egg-info => SQLAlchemy-1.3.11.egg-info}/requires.txt (100%) rename py3/lib/python3.6/site-packages/{SQLAlchemy-1.3.8.egg-info => SQLAlchemy-1.3.11.egg-info}/top_level.txt (100%) delete mode 100644 py3/lib/python3.6/site-packages/_markerlib/__init__.py delete mode 100644 py3/lib/python3.6/site-packages/_markerlib/markers.py delete mode 100644 py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/LICENSE delete mode 100644 py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/RECORD rename py3/lib/python3.6/site-packages/{arrow-0.14.6.dist-info => arrow-0.15.4.dist-info}/INSTALLER (100%) create mode 100644 py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/LICENSE rename py3/lib/python3.6/site-packages/{arrow-0.14.6.dist-info => arrow-0.15.4.dist-info}/METADATA (98%) create mode 100644 py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/RECORD rename py3/lib/python3.6/site-packages/{arrow-0.14.6.dist-info => arrow-0.15.4.dist-info}/WHEEL (100%) rename py3/lib/python3.6/site-packages/{arrow-0.14.6.dist-info => arrow-0.15.4.dist-info}/top_level.txt (100%) create mode 100644 py3/lib/python3.6/site-packages/arrow/constants.py create mode 100644 py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/COPYING create mode 100644 py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/COPYING.LESSER rename py3/lib/python3.6/site-packages/{certifi-2019.6.16.dist-info => astroid-2.3.3.dist-info}/INSTALLER (100%) create mode 100644 py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/METADATA create mode 100644 py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/RECORD create mode 100644 py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/WHEEL create mode 100644 py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/top_level.txt create mode 100644 py3/lib/python3.6/site-packages/astroid/__init__.py create mode 100644 py3/lib/python3.6/site-packages/astroid/__pkginfo__.py create mode 100644 py3/lib/python3.6/site-packages/astroid/_ast.py create mode 100644 py3/lib/python3.6/site-packages/astroid/arguments.py create mode 100644 py3/lib/python3.6/site-packages/astroid/as_string.py create mode 100644 py3/lib/python3.6/site-packages/astroid/bases.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_argparse.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_attrs.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_builtin_inference.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_collections.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_crypt.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_curses.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_dataclasses.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_dateutil.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_fstrings.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_functools.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_gi.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_hashlib.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_http.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_io.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_mechanize.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_multiprocessing.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_namedtuple_enum.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_nose.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_fromnumeric.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_function_base.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_multiarray.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_numeric.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_numerictypes.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_umath.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_ndarray.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_random_mtrand.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_utils.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_pkg_resources.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_pytest.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_qt.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_random.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_re.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_six.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_ssl.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_subprocess.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_threading.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_typing.py create mode 100644 py3/lib/python3.6/site-packages/astroid/brain/brain_uuid.py create mode 100644 py3/lib/python3.6/site-packages/astroid/builder.py create mode 100644 py3/lib/python3.6/site-packages/astroid/context.py create mode 100644 py3/lib/python3.6/site-packages/astroid/decorators.py create mode 100644 py3/lib/python3.6/site-packages/astroid/exceptions.py create mode 100644 py3/lib/python3.6/site-packages/astroid/helpers.py create mode 100644 py3/lib/python3.6/site-packages/astroid/inference.py rename py3/lib/python3.6/site-packages/{socketio/tests => astroid/interpreter}/__init__.py (100%) create mode 100644 py3/lib/python3.6/site-packages/astroid/interpreter/_import/__init__.py create mode 100644 py3/lib/python3.6/site-packages/astroid/interpreter/_import/spec.py create mode 100644 py3/lib/python3.6/site-packages/astroid/interpreter/_import/util.py create mode 100644 py3/lib/python3.6/site-packages/astroid/interpreter/dunder_lookup.py create mode 100644 py3/lib/python3.6/site-packages/astroid/interpreter/objectmodel.py create mode 100644 py3/lib/python3.6/site-packages/astroid/manager.py create mode 100644 py3/lib/python3.6/site-packages/astroid/mixins.py create mode 100644 py3/lib/python3.6/site-packages/astroid/modutils.py create mode 100644 py3/lib/python3.6/site-packages/astroid/node_classes.py create mode 100644 py3/lib/python3.6/site-packages/astroid/nodes.py create mode 100644 py3/lib/python3.6/site-packages/astroid/objects.py create mode 100644 py3/lib/python3.6/site-packages/astroid/protocols.py create mode 100644 py3/lib/python3.6/site-packages/astroid/raw_building.py create mode 100644 py3/lib/python3.6/site-packages/astroid/rebuilder.py create mode 100644 py3/lib/python3.6/site-packages/astroid/scoped_nodes.py create mode 100644 py3/lib/python3.6/site-packages/astroid/test_utils.py create mode 100644 py3/lib/python3.6/site-packages/astroid/transforms.py create mode 100644 py3/lib/python3.6/site-packages/astroid/util.py delete mode 100644 py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/LICENSE.txt delete mode 100644 py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/RECORD rename py3/lib/python3.6/site-packages/{certifi-2019.6.16.dist-info => certifi-2019.9.11.dist-info}/DESCRIPTION.rst (100%) rename py3/lib/python3.6/site-packages/{python_dateutil-2.8.0.dist-info => certifi-2019.9.11.dist-info}/INSTALLER (100%) rename py3/lib/python3.6/site-packages/{certifi-2019.6.16.dist-info => certifi-2019.9.11.dist-info}/METADATA (99%) create mode 100644 py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/RECORD rename py3/lib/python3.6/site-packages/{certifi-2019.6.16.dist-info => certifi-2019.9.11.dist-info}/WHEEL (100%) rename py3/lib/python3.6/site-packages/{certifi-2019.6.16.dist-info => certifi-2019.9.11.dist-info}/metadata.json (73%) rename py3/lib/python3.6/site-packages/{certifi-2019.6.16.dist-info => certifi-2019.9.11.dist-info}/top_level.txt (100%) delete mode 100644 py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/.libs_cffi_backend/libffi-ae16d830.so.6.0.4 delete mode 100644 py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/_cffi_backend.cpython-36m-x86_64-linux-gnu.so create mode 100644 py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/.libs_cffi_backend/libffi-806b1a9d.so.6.0.4 rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/EGG-INFO/LICENSE.txt (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/EGG-INFO/PKG-INFO (98%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/EGG-INFO/RECORD (55%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/EGG-INFO/WHEEL (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/EGG-INFO/entry_points.txt (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/EGG-INFO/requires.txt (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/EGG-INFO/top_level.txt (100%) create mode 100644 py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/_cffi_backend.cpython-36m-x86_64-linux-gnu.so rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/__init__.py (89%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/_cffi_errors.h (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/_cffi_include.h (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/_embedding.h (97%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/api.py (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/backend_ctypes.py (99%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/cffi_opcode.py (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/commontypes.py (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/cparser.py (95%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/error.py (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/ffiplatform.py (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/lock.py (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/model.py (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/parse_c_type.h (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/pkgconfig.py (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/recompiler.py (99%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/setuptools_ext.py (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/vengine_cpy.py (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/vengine_gen.py (100%) rename py3/lib/python3.6/site-packages/{cffi-1.12.3-py3.6-linux-x86_64.egg => cffi-1.13.2-py3.6-linux-x86_64.egg}/cffi/verifier.py (100%) rename py3/lib/python3.6/site-packages/{python_engineio-3.9.3.dist-info => isort-4.3.21.dist-info}/INSTALLER (100%) create mode 100755 py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/LICENSE create mode 100644 py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/METADATA create mode 100644 py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/RECORD rename py3/lib/python3.6/site-packages/{python_engineio-3.9.3.dist-info => isort-4.3.21.dist-info}/WHEEL (100%) create mode 100644 py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/entry_points.txt create mode 100644 py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/top_level.txt create mode 100644 py3/lib/python3.6/site-packages/isort/__init__.py create mode 100644 py3/lib/python3.6/site-packages/isort/__main__.py create mode 100644 py3/lib/python3.6/site-packages/isort/finders.py create mode 100644 py3/lib/python3.6/site-packages/isort/hooks.py create mode 100644 py3/lib/python3.6/site-packages/isort/isort.py create mode 100644 py3/lib/python3.6/site-packages/isort/main.py create mode 100644 py3/lib/python3.6/site-packages/isort/natural.py create mode 100644 py3/lib/python3.6/site-packages/isort/pie_slice.py create mode 100644 py3/lib/python3.6/site-packages/isort/pylama_isort.py create mode 100644 py3/lib/python3.6/site-packages/isort/settings.py create mode 100644 py3/lib/python3.6/site-packages/isort/utils.py rename py3/lib/python3.6/site-packages/{python_socketio-4.3.1.dist-info => lazy_object_proxy-1.4.3.dist-info}/INSTALLER (100%) create mode 100644 py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/METADATA create mode 100644 py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/RECORD create mode 100644 py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/WHEEL create mode 100644 py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/top_level.txt create mode 100644 py3/lib/python3.6/site-packages/lazy_object_proxy/__init__.py create mode 100644 py3/lib/python3.6/site-packages/lazy_object_proxy/_version.py create mode 100755 py3/lib/python3.6/site-packages/lazy_object_proxy/cext.cpython-36m-x86_64-linux-gnu.so create mode 100644 py3/lib/python3.6/site-packages/lazy_object_proxy/compat.py create mode 100644 py3/lib/python3.6/site-packages/lazy_object_proxy/simple.py create mode 100644 py3/lib/python3.6/site-packages/lazy_object_proxy/slots.py create mode 100644 py3/lib/python3.6/site-packages/lazy_object_proxy/utils.py create mode 100644 py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/DESCRIPTION.rst rename py3/lib/python3.6/site-packages/{setuptools-3.3.dist-info => mccabe-0.6.1.dist-info}/INSTALLER (100%) create mode 100644 py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/METADATA create mode 100644 py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/RECORD rename py3/lib/python3.6/site-packages/{python_socketio-4.3.1.dist-info => mccabe-0.6.1.dist-info}/WHEEL (70%) create mode 100644 py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/entry_points.txt create mode 100644 py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/metadata.json create mode 100644 py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/top_level.txt create mode 100644 py3/lib/python3.6/site-packages/mccabe.py delete mode 100644 py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/PKG-INFO delete mode 100644 py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/SOURCES.txt delete mode 100644 py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/installed-files.txt delete mode 100644 py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/top_level.txt delete mode 100755 py3/lib/python3.6/site-packages/netifaces.cpython-36m-x86_64-linux-gnu.so delete mode 100644 py3/lib/python3.6/site-packages/pkg_resources.py create mode 100644 py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/COPYING rename py3/lib/python3.6/site-packages/{six-1.12.0.dist-info => pylint-2.4.4.dist-info}/INSTALLER (100%) create mode 100644 py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/METADATA create mode 100644 py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/RECORD create mode 100644 py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/WHEEL create mode 100644 py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/entry_points.txt create mode 100644 py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/top_level.txt create mode 100644 py3/lib/python3.6/site-packages/pylint/__init__.py create mode 100644 py3/lib/python3.6/site-packages/pylint/__main__.py create mode 100644 py3/lib/python3.6/site-packages/pylint/__pkginfo__.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/__init__.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/async.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/base.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/base_checker.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/classes.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/design_analysis.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/exceptions.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/format.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/imports.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/logging.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/misc.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/newstyle.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/python3.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/raw_metrics.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/refactoring.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/similar.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/spelling.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/stdlib.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/strings.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/typecheck.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/utils.py create mode 100644 py3/lib/python3.6/site-packages/pylint/checkers/variables.py create mode 100644 py3/lib/python3.6/site-packages/pylint/constants.py create mode 100644 py3/lib/python3.6/site-packages/pylint/epylint.py create mode 100644 py3/lib/python3.6/site-packages/pylint/exceptions.py create mode 100644 py3/lib/python3.6/site-packages/pylint/extensions/__init__.py create mode 100644 py3/lib/python3.6/site-packages/pylint/extensions/_check_docs_utils.py create mode 100644 py3/lib/python3.6/site-packages/pylint/extensions/bad_builtin.py create mode 100644 py3/lib/python3.6/site-packages/pylint/extensions/broad_try_clause.py create mode 100644 py3/lib/python3.6/site-packages/pylint/extensions/check_docs.py create mode 100644 py3/lib/python3.6/site-packages/pylint/extensions/check_elif.py create mode 100644 py3/lib/python3.6/site-packages/pylint/extensions/comparetozero.py create mode 100644 py3/lib/python3.6/site-packages/pylint/extensions/docparams.py create mode 100644 py3/lib/python3.6/site-packages/pylint/extensions/docstyle.py create mode 100644 py3/lib/python3.6/site-packages/pylint/extensions/emptystring.py create mode 100644 py3/lib/python3.6/site-packages/pylint/extensions/mccabe.py create mode 100644 py3/lib/python3.6/site-packages/pylint/extensions/overlapping_exceptions.py create mode 100644 py3/lib/python3.6/site-packages/pylint/extensions/redefined_variable_type.py create mode 100644 py3/lib/python3.6/site-packages/pylint/graph.py create mode 100644 py3/lib/python3.6/site-packages/pylint/interfaces.py create mode 100644 py3/lib/python3.6/site-packages/pylint/lint.py create mode 100644 py3/lib/python3.6/site-packages/pylint/message/__init__.py create mode 100644 py3/lib/python3.6/site-packages/pylint/message/message.py create mode 100644 py3/lib/python3.6/site-packages/pylint/message/message_definition.py create mode 100644 py3/lib/python3.6/site-packages/pylint/message/message_definition_store.py create mode 100644 py3/lib/python3.6/site-packages/pylint/message/message_handler_mix_in.py create mode 100644 py3/lib/python3.6/site-packages/pylint/message/message_id_store.py create mode 100644 py3/lib/python3.6/site-packages/pylint/pyreverse/__init__.py create mode 100644 py3/lib/python3.6/site-packages/pylint/pyreverse/diadefslib.py create mode 100644 py3/lib/python3.6/site-packages/pylint/pyreverse/diagrams.py create mode 100644 py3/lib/python3.6/site-packages/pylint/pyreverse/inspector.py create mode 100644 py3/lib/python3.6/site-packages/pylint/pyreverse/main.py create mode 100644 py3/lib/python3.6/site-packages/pylint/pyreverse/utils.py create mode 100644 py3/lib/python3.6/site-packages/pylint/pyreverse/vcgutils.py create mode 100644 py3/lib/python3.6/site-packages/pylint/pyreverse/writer.py create mode 100644 py3/lib/python3.6/site-packages/pylint/reporters/__init__.py create mode 100644 py3/lib/python3.6/site-packages/pylint/reporters/base_reporter.py create mode 100644 py3/lib/python3.6/site-packages/pylint/reporters/collecting_reporter.py create mode 100644 py3/lib/python3.6/site-packages/pylint/reporters/json_reporter.py create mode 100644 py3/lib/python3.6/site-packages/pylint/reporters/reports_handler_mix_in.py create mode 100644 py3/lib/python3.6/site-packages/pylint/reporters/text.py create mode 100644 py3/lib/python3.6/site-packages/pylint/reporters/ureports/__init__.py create mode 100644 py3/lib/python3.6/site-packages/pylint/reporters/ureports/nodes.py create mode 100644 py3/lib/python3.6/site-packages/pylint/reporters/ureports/text_writer.py create mode 100644 py3/lib/python3.6/site-packages/pylint/testutils.py create mode 100644 py3/lib/python3.6/site-packages/pylint/utils/__init__.py create mode 100644 py3/lib/python3.6/site-packages/pylint/utils/ast_walker.py create mode 100644 py3/lib/python3.6/site-packages/pylint/utils/file_state.py create mode 100644 py3/lib/python3.6/site-packages/pylint/utils/utils.py rename py3/lib/python3.6/site-packages/{urllib3-1.25.3.dist-info => python_dateutil-2.8.1.dist-info}/INSTALLER (100%) rename py3/lib/python3.6/site-packages/{python_dateutil-2.8.0.dist-info => python_dateutil-2.8.1.dist-info}/LICENSE (100%) rename py3/lib/python3.6/site-packages/{python_dateutil-2.8.0.dist-info => python_dateutil-2.8.1.dist-info}/METADATA (92%) rename py3/lib/python3.6/site-packages/{python_dateutil-2.8.0.dist-info => python_dateutil-2.8.1.dist-info}/RECORD (50%) rename py3/lib/python3.6/site-packages/{python_dateutil-2.8.0.dist-info => python_dateutil-2.8.1.dist-info}/WHEEL (70%) rename py3/lib/python3.6/site-packages/{python_dateutil-2.8.0.dist-info => python_dateutil-2.8.1.dist-info}/top_level.txt (100%) rename py3/lib/python3.6/site-packages/{netifaces-0.10.6.egg-info => python_dateutil-2.8.1.dist-info}/zip-safe (100%) create mode 100644 py3/lib/python3.6/site-packages/python_engineio-3.10.0.dist-info/INSTALLER rename py3/lib/python3.6/site-packages/{python_engineio-3.9.3.dist-info => python_engineio-3.10.0.dist-info}/LICENSE (100%) rename py3/lib/python3.6/site-packages/{python_engineio-3.9.3.dist-info => python_engineio-3.10.0.dist-info}/METADATA (99%) rename py3/lib/python3.6/site-packages/{python_engineio-3.9.3.dist-info => python_engineio-3.10.0.dist-info}/RECORD (85%) create mode 100644 py3/lib/python3.6/site-packages/python_engineio-3.10.0.dist-info/WHEEL rename py3/lib/python3.6/site-packages/{python_engineio-3.9.3.dist-info => python_engineio-3.10.0.dist-info}/top_level.txt (100%) create mode 100644 py3/lib/python3.6/site-packages/python_socketio-4.4.0.dist-info/INSTALLER rename py3/lib/python3.6/site-packages/{python_socketio-4.3.1.dist-info => python_socketio-4.4.0.dist-info}/LICENSE (100%) rename py3/lib/python3.6/site-packages/{python_socketio-4.3.1.dist-info => python_socketio-4.4.0.dist-info}/METADATA (99%) rename py3/lib/python3.6/site-packages/{python_socketio-4.3.1.dist-info => python_socketio-4.4.0.dist-info}/RECORD (72%) create mode 100644 py3/lib/python3.6/site-packages/python_socketio-4.4.0.dist-info/WHEEL rename py3/lib/python3.6/site-packages/{python_socketio-4.3.1.dist-info => python_socketio-4.4.0.dist-info}/top_level.txt (100%) delete mode 100644 py3/lib/python3.6/site-packages/setuptools-3.3.dist-info/DESCRIPTION.rst delete mode 100644 py3/lib/python3.6/site-packages/setuptools-3.3.dist-info/METADATA delete mode 100644 py3/lib/python3.6/site-packages/setuptools-3.3.dist-info/RECORD delete mode 100644 py3/lib/python3.6/site-packages/setuptools-3.3.dist-info/WHEEL delete mode 100644 py3/lib/python3.6/site-packages/setuptools-3.3.dist-info/dependency_links.txt delete mode 100644 py3/lib/python3.6/site-packages/setuptools-3.3.dist-info/dependency_links.txt.orig delete mode 100644 py3/lib/python3.6/site-packages/setuptools-3.3.dist-info/entry_points.txt.orig delete mode 100644 py3/lib/python3.6/site-packages/setuptools-3.3.dist-info/pydist.json delete mode 100644 py3/lib/python3.6/site-packages/setuptools-3.3.dist-info/requires.txt.orig delete mode 100644 py3/lib/python3.6/site-packages/setuptools-3.3.dist-info/zip-safe create mode 100644 py3/lib/python3.6/site-packages/setuptools-39.0.1.dist-info/DESCRIPTION.rst create mode 100644 py3/lib/python3.6/site-packages/setuptools-39.0.1.dist-info/INSTALLER create mode 100644 py3/lib/python3.6/site-packages/setuptools-39.0.1.dist-info/METADATA create mode 100644 py3/lib/python3.6/site-packages/setuptools-39.0.1.dist-info/RECORD create mode 100644 py3/lib/python3.6/site-packages/setuptools-39.0.1.dist-info/WHEEL create mode 100644 py3/lib/python3.6/site-packages/setuptools-39.0.1.dist-info/dependency_links.txt rename py3/lib/python3.6/site-packages/{setuptools-3.3.dist-info => setuptools-39.0.1.dist-info}/entry_points.txt (89%) create mode 100644 py3/lib/python3.6/site-packages/setuptools-39.0.1.dist-info/metadata.json rename py3/lib/python3.6/site-packages/{setuptools-3.3.dist-info => setuptools-39.0.1.dist-info}/top_level.txt (77%) rename py3/lib/python3.6/site-packages/{python_dateutil-2.8.0.dist-info => setuptools-39.0.1.dist-info}/zip-safe (100%) create mode 100644 py3/lib/python3.6/site-packages/setuptools/_vendor/__init__.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/_vendor/packaging/_compat.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/_vendor/pyparsing.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/_vendor/six.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/build_meta.py mode change 100755 => 100644 py3/lib/python3.6/site-packages/setuptools/cli-32.exe mode change 100755 => 100644 py3/lib/python3.6/site-packages/setuptools/cli-64.exe delete mode 100755 py3/lib/python3.6/site-packages/setuptools/cli-arm-32.exe mode change 100755 => 100644 py3/lib/python3.6/site-packages/setuptools/cli.exe create mode 100644 py3/lib/python3.6/site-packages/setuptools/command/build_clib.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/command/dist_info.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/command/py36compat.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/command/upload.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/compat.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/dep_util.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/extern/__init__.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/glibc.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/glob.py mode change 100755 => 100644 py3/lib/python3.6/site-packages/setuptools/gui-32.exe mode change 100755 => 100644 py3/lib/python3.6/site-packages/setuptools/gui-64.exe delete mode 100755 py3/lib/python3.6/site-packages/setuptools/gui-arm-32.exe mode change 100755 => 100644 py3/lib/python3.6/site-packages/setuptools/gui.exe create mode 100644 py3/lib/python3.6/site-packages/setuptools/launch.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/monkey.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/msvc.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/namespaces.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/pep425tags.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/py26compat.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/py33compat.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/py36compat.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/script (dev).tmpl delete mode 100644 py3/lib/python3.6/site-packages/setuptools/script template (dev).py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/script template.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/script.tmpl delete mode 100644 py3/lib/python3.6/site-packages/setuptools/svn_utils.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/__init__.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/doctest.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/environment.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/py26compat.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/script-with-bom.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/server.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/test_bdist_egg.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/test_build_ext.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/test_develop.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/test_dist_info.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/test_easy_install.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/test_egg_info.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/test_find_packages.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/test_markerlib.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/test_packageindex.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/test_resources.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/test_sandbox.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/test_sdist.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/test_svn.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/test_test.py delete mode 100644 py3/lib/python3.6/site-packages/setuptools/tests/test_upload_docs.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/unicode_utils.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/wheel.py create mode 100644 py3/lib/python3.6/site-packages/setuptools/windows_support.py delete mode 100644 py3/lib/python3.6/site-packages/six-1.12.0.dist-info/RECORD delete mode 100644 py3/lib/python3.6/site-packages/six-1.12.0.dist-info/WHEEL create mode 100644 py3/lib/python3.6/site-packages/six-1.13.0.dist-info/INSTALLER rename py3/lib/python3.6/site-packages/{six-1.12.0.dist-info => six-1.13.0.dist-info}/LICENSE (96%) rename py3/lib/python3.6/site-packages/{six-1.12.0.dist-info => six-1.13.0.dist-info}/METADATA (99%) create mode 100644 py3/lib/python3.6/site-packages/six-1.13.0.dist-info/RECORD create mode 100644 py3/lib/python3.6/site-packages/six-1.13.0.dist-info/WHEEL rename py3/lib/python3.6/site-packages/{six-1.12.0.dist-info => six-1.13.0.dist-info}/top_level.txt (100%) delete mode 100755 py3/lib/python3.6/site-packages/socketio-0.2.1-py3.6.egg-info/PKG-INFO delete mode 100755 py3/lib/python3.6/site-packages/socketio-0.2.1-py3.6.egg-info/SOURCES.txt delete mode 100755 py3/lib/python3.6/site-packages/socketio-0.2.1-py3.6.egg-info/dependency_links.txt delete mode 100644 py3/lib/python3.6/site-packages/socketio-0.2.1-py3.6.egg-info/installed-files.txt delete mode 100755 py3/lib/python3.6/site-packages/socketio-0.2.1-py3.6.egg-info/requires.txt delete mode 100755 py3/lib/python3.6/site-packages/socketio-0.2.1-py3.6.egg-info/top_level.txt delete mode 100644 py3/lib/python3.6/site-packages/socketio/tests/performance_test.py create mode 100644 py3/lib/python3.6/site-packages/typed_ast-1.4.0.dist-info/INSTALLER create mode 100644 py3/lib/python3.6/site-packages/typed_ast-1.4.0.dist-info/METADATA create mode 100644 py3/lib/python3.6/site-packages/typed_ast-1.4.0.dist-info/RECORD create mode 100644 py3/lib/python3.6/site-packages/typed_ast-1.4.0.dist-info/WHEEL create mode 100644 py3/lib/python3.6/site-packages/typed_ast-1.4.0.dist-info/top_level.txt create mode 100644 py3/lib/python3.6/site-packages/typed_ast/__init__.py create mode 100755 py3/lib/python3.6/site-packages/typed_ast/_ast27.cpython-36m-x86_64-linux-gnu.so create mode 100755 py3/lib/python3.6/site-packages/typed_ast/_ast3.cpython-36m-x86_64-linux-gnu.so create mode 100644 py3/lib/python3.6/site-packages/typed_ast/ast27.py create mode 100644 py3/lib/python3.6/site-packages/typed_ast/ast3.py create mode 100644 py3/lib/python3.6/site-packages/typed_ast/conversions.py create mode 100644 py3/lib/python3.6/site-packages/typed_ast/tests/test_basics.py delete mode 100644 py3/lib/python3.6/site-packages/urllib3-1.25.3.dist-info/RECORD delete mode 100644 py3/lib/python3.6/site-packages/urllib3-1.25.3.dist-info/WHEEL create mode 100644 py3/lib/python3.6/site-packages/urllib3-1.25.7.dist-info/INSTALLER rename py3/lib/python3.6/site-packages/{urllib3-1.25.3.dist-info => urllib3-1.25.7.dist-info}/LICENSE.txt (100%) rename py3/lib/python3.6/site-packages/{urllib3-1.25.3.dist-info => urllib3-1.25.7.dist-info}/METADATA (94%) create mode 100644 py3/lib/python3.6/site-packages/urllib3-1.25.7.dist-info/RECORD create mode 100644 py3/lib/python3.6/site-packages/urllib3-1.25.7.dist-info/WHEEL rename py3/lib/python3.6/site-packages/{urllib3-1.25.3.dist-info => urllib3-1.25.7.dist-info}/top_level.txt (100%) delete mode 100644 py3/lib/python3.6/site-packages/urllib3/packages/rfc3986/__init__.py delete mode 100644 py3/lib/python3.6/site-packages/urllib3/packages/rfc3986/_mixin.py delete mode 100644 py3/lib/python3.6/site-packages/urllib3/packages/rfc3986/abnf_regexp.py delete mode 100644 py3/lib/python3.6/site-packages/urllib3/packages/rfc3986/api.py delete mode 100644 py3/lib/python3.6/site-packages/urllib3/packages/rfc3986/builder.py delete mode 100644 py3/lib/python3.6/site-packages/urllib3/packages/rfc3986/compat.py delete mode 100644 py3/lib/python3.6/site-packages/urllib3/packages/rfc3986/exceptions.py delete mode 100644 py3/lib/python3.6/site-packages/urllib3/packages/rfc3986/iri.py delete mode 100644 py3/lib/python3.6/site-packages/urllib3/packages/rfc3986/misc.py delete mode 100644 py3/lib/python3.6/site-packages/urllib3/packages/rfc3986/normalizers.py delete mode 100644 py3/lib/python3.6/site-packages/urllib3/packages/rfc3986/parseresult.py delete mode 100644 py3/lib/python3.6/site-packages/urllib3/packages/rfc3986/uri.py delete mode 100644 py3/lib/python3.6/site-packages/urllib3/packages/rfc3986/validators.py create mode 100644 py3/lib/python3.6/site-packages/wrapt-1.11.2.egg-info/PKG-INFO create mode 100644 py3/lib/python3.6/site-packages/wrapt-1.11.2.egg-info/SOURCES.txt rename py3/lib/python3.6/site-packages/{netifaces-0.10.6.egg-info => wrapt-1.11.2.egg-info}/dependency_links.txt (100%) create mode 100644 py3/lib/python3.6/site-packages/wrapt-1.11.2.egg-info/installed-files.txt create mode 100644 py3/lib/python3.6/site-packages/wrapt-1.11.2.egg-info/top_level.txt create mode 100644 py3/lib/python3.6/site-packages/wrapt/__init__.py create mode 100755 py3/lib/python3.6/site-packages/wrapt/_wrappers.cpython-36m-x86_64-linux-gnu.so create mode 100644 py3/lib/python3.6/site-packages/wrapt/decorators.py create mode 100644 py3/lib/python3.6/site-packages/wrapt/importer.py create mode 100644 py3/lib/python3.6/site-packages/wrapt/wrappers.py delete mode 100644 ranchimallflo-api/.gitignore delete mode 100644 ranchimallflo-api/config-example.py delete mode 100644 ranchimallflo-api/parsing.py delete mode 100644 ranchimallflo-api/ranchimallflo_api.py delete mode 100644 ranchimallflo-api/static/broadcast.js delete mode 100644 ranchimallflo-api/templates/index.html diff --git a/.gitignore b/.gitignore index 02b3747..1f5196c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ smartContracts/ system.db config.ini config.py +*.log diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9ae7aff --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "py3/bin/python3" +} \ No newline at end of file diff --git a/config.ini b/config.ini index 96b9251..8af0da2 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [DEFAULT] -NET = mainnet +NET = testnet FLO_CLI_PATH = /usr/local/bin/flo-cli -START_BLOCK = 3387900 +START_BLOCK = 868993 diff --git a/config.pyc b/config.pyc new file mode 100644 index 0000000000000000000000000000000000000000..65fb951d9c935dea20c8e8c7e83ae3fa9e5f7005 GIT binary patch literal 352 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 literal 0 HcmV?d00001 diff --git a/py3/bin/activate b/py3/bin/activate index 5f78785..853f1f5 100644 --- a/py3/bin/activate +++ b/py3/bin/activate @@ -37,7 +37,7 @@ deactivate () { # unset irrelevant variables deactivate nondestructive -VIRTUAL_ENV="/home/vivek/Desktop/flo-token-tracking/py3" +VIRTUAL_ENV="/home/vivek/Desktop/ftt/py3" export VIRTUAL_ENV _OLD_VIRTUAL_PATH="$PATH" diff --git a/py3/bin/activate.csh b/py3/bin/activate.csh index 2057b8a..313e059 100644 --- a/py3/bin/activate.csh +++ b/py3/bin/activate.csh @@ -8,7 +8,7 @@ alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PA # Unset irrelevant variables. deactivate nondestructive -setenv VIRTUAL_ENV "/home/vivek/Desktop/flo-token-tracking/py3" +setenv VIRTUAL_ENV "/home/vivek/Desktop/ftt/py3" set _OLD_VIRTUAL_PATH="$PATH" setenv PATH "$VIRTUAL_ENV/bin:$PATH" diff --git a/py3/bin/activate.fish b/py3/bin/activate.fish index 4f208e0..e9cd547 100644 --- a/py3/bin/activate.fish +++ b/py3/bin/activate.fish @@ -29,7 +29,7 @@ end # unset irrelevant variables deactivate nondestructive -set -gx VIRTUAL_ENV "/home/vivek/Desktop/flo-token-tracking/py3" +set -gx VIRTUAL_ENV "/home/vivek/Desktop/ftt/py3" set -gx _OLD_VIRTUAL_PATH $PATH set -gx PATH "$VIRTUAL_ENV/bin" $PATH diff --git a/py3/bin/chardetect b/py3/bin/chardetect index 85dbe63..7d80ce9 100755 --- a/py3/bin/chardetect +++ b/py3/bin/chardetect @@ -1,4 +1,4 @@ -#!/home/vivek/Desktop/flo-token-tracking/py3/bin/python3 +#!/home/vivek/Desktop/ftt/py3/bin/python3 # -*- coding: utf-8 -*- import re diff --git a/py3/bin/easy_install b/py3/bin/easy_install index 95236a4..358eb4c 100755 --- a/py3/bin/easy_install +++ b/py3/bin/easy_install @@ -1,4 +1,4 @@ -#!/home/vivek/Desktop/flo-token-tracking/py3/bin/python3 +#!/home/vivek/Desktop/ftt/py3/bin/python3 # -*- coding: utf-8 -*- import re diff --git a/py3/bin/easy_install-3.6 b/py3/bin/easy_install-3.6 index 95236a4..358eb4c 100755 --- a/py3/bin/easy_install-3.6 +++ b/py3/bin/easy_install-3.6 @@ -1,4 +1,4 @@ -#!/home/vivek/Desktop/flo-token-tracking/py3/bin/python3 +#!/home/vivek/Desktop/ftt/py3/bin/python3 # -*- coding: utf-8 -*- import re diff --git a/py3/bin/epylint b/py3/bin/epylint new file mode 100755 index 0000000..3927181 --- /dev/null +++ b/py3/bin/epylint @@ -0,0 +1,11 @@ +#!/home/vivek/Desktop/ftt/py3/bin/python3 + +# -*- coding: utf-8 -*- +import re +import sys + +from pylint import run_epylint + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(run_epylint()) diff --git a/py3/bin/isort b/py3/bin/isort new file mode 100755 index 0000000..b82c87d --- /dev/null +++ b/py3/bin/isort @@ -0,0 +1,11 @@ +#!/home/vivek/Desktop/ftt/py3/bin/python3 + +# -*- coding: utf-8 -*- +import re +import sys + +from isort.main import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/py3/bin/pip b/py3/bin/pip index af9557b..c911ce5 100755 --- a/py3/bin/pip +++ b/py3/bin/pip @@ -1,4 +1,4 @@ -#!/home/vivek/Desktop/flo-token-tracking/py3/bin/python3 +#!/home/vivek/Desktop/ftt/py3/bin/python3 # -*- coding: utf-8 -*- import re diff --git a/py3/bin/pip3 b/py3/bin/pip3 index af9557b..c911ce5 100755 --- a/py3/bin/pip3 +++ b/py3/bin/pip3 @@ -1,4 +1,4 @@ -#!/home/vivek/Desktop/flo-token-tracking/py3/bin/python3 +#!/home/vivek/Desktop/ftt/py3/bin/python3 # -*- coding: utf-8 -*- import re diff --git a/py3/bin/pip3.6 b/py3/bin/pip3.6 index af9557b..c911ce5 100755 --- a/py3/bin/pip3.6 +++ b/py3/bin/pip3.6 @@ -1,4 +1,4 @@ -#!/home/vivek/Desktop/flo-token-tracking/py3/bin/python3 +#!/home/vivek/Desktop/ftt/py3/bin/python3 # -*- coding: utf-8 -*- import re diff --git a/py3/bin/pylint b/py3/bin/pylint new file mode 100755 index 0000000..28796c8 --- /dev/null +++ b/py3/bin/pylint @@ -0,0 +1,11 @@ +#!/home/vivek/Desktop/ftt/py3/bin/python3 + +# -*- coding: utf-8 -*- +import re +import sys + +from pylint import run_pylint + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(run_pylint()) diff --git a/py3/bin/pyreverse b/py3/bin/pyreverse new file mode 100755 index 0000000..af8efda --- /dev/null +++ b/py3/bin/pyreverse @@ -0,0 +1,11 @@ +#!/home/vivek/Desktop/ftt/py3/bin/python3 + +# -*- coding: utf-8 -*- +import re +import sys + +from pylint import run_pyreverse + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(run_pyreverse()) diff --git a/py3/bin/symilar b/py3/bin/symilar new file mode 100755 index 0000000..2a6f270 --- /dev/null +++ b/py3/bin/symilar @@ -0,0 +1,11 @@ +#!/home/vivek/Desktop/ftt/py3/bin/python3 + +# -*- coding: utf-8 -*- +import re +import sys + +from pylint import run_symilar + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(run_symilar()) diff --git a/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.8.egg-info/PKG-INFO b/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.11.egg-info/PKG-INFO similarity index 99% rename from py3/lib/python3.6/site-packages/SQLAlchemy-1.3.8.egg-info/PKG-INFO rename to py3/lib/python3.6/site-packages/SQLAlchemy-1.3.11.egg-info/PKG-INFO index 2e97d91..2027524 100644 --- a/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.8.egg-info/PKG-INFO +++ b/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.11.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: SQLAlchemy -Version: 1.3.8 +Version: 1.3.11 Summary: Database Abstraction Library Home-page: http://www.sqlalchemy.org Author: Mike Bayer diff --git a/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.8.egg-info/SOURCES.txt b/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.11.egg-info/SOURCES.txt similarity index 99% rename from py3/lib/python3.6/site-packages/SQLAlchemy-1.3.8.egg-info/SOURCES.txt rename to py3/lib/python3.6/site-packages/SQLAlchemy-1.3.11.egg-info/SOURCES.txt index 912fc74..7e5c116 100644 --- a/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.8.egg-info/SOURCES.txt +++ b/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.11.egg-info/SOURCES.txt @@ -160,6 +160,7 @@ doc/build/core/tutorial.rst doc/build/core/type_api.rst doc/build/core/type_basics.rst doc/build/core/types.rst +doc/build/core/visitors.rst doc/build/dialects/firebird.rst doc/build/dialects/index.rst doc/build/dialects/mssql.rst @@ -292,6 +293,7 @@ doc/core/tutorial.html doc/core/type_api.html doc/core/type_basics.html doc/core/types.html +doc/core/visitors.html doc/dialects/firebird.html doc/dialects/index.html doc/dialects/mssql.html @@ -813,6 +815,7 @@ test/perf/orm2010.py test/sql/__init__.py test/sql/test_case_statement.py test/sql/test_compiler.py +test/sql/test_computed.py test/sql/test_constraints.py test/sql/test_cte.py test/sql/test_ddlemit.py diff --git a/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.8.egg-info/dependency_links.txt b/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.11.egg-info/dependency_links.txt similarity index 100% rename from py3/lib/python3.6/site-packages/SQLAlchemy-1.3.8.egg-info/dependency_links.txt rename to py3/lib/python3.6/site-packages/SQLAlchemy-1.3.11.egg-info/dependency_links.txt diff --git a/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.8.egg-info/installed-files.txt b/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.11.egg-info/installed-files.txt similarity index 100% rename from py3/lib/python3.6/site-packages/SQLAlchemy-1.3.8.egg-info/installed-files.txt rename to py3/lib/python3.6/site-packages/SQLAlchemy-1.3.11.egg-info/installed-files.txt diff --git a/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.8.egg-info/requires.txt b/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.11.egg-info/requires.txt similarity index 100% rename from py3/lib/python3.6/site-packages/SQLAlchemy-1.3.8.egg-info/requires.txt rename to py3/lib/python3.6/site-packages/SQLAlchemy-1.3.11.egg-info/requires.txt diff --git a/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.8.egg-info/top_level.txt b/py3/lib/python3.6/site-packages/SQLAlchemy-1.3.11.egg-info/top_level.txt similarity index 100% rename from py3/lib/python3.6/site-packages/SQLAlchemy-1.3.8.egg-info/top_level.txt rename to py3/lib/python3.6/site-packages/SQLAlchemy-1.3.11.egg-info/top_level.txt diff --git a/py3/lib/python3.6/site-packages/_markerlib/__init__.py b/py3/lib/python3.6/site-packages/_markerlib/__init__.py deleted file mode 100644 index e2b237b..0000000 --- a/py3/lib/python3.6/site-packages/_markerlib/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -try: - import ast - from _markerlib.markers import default_environment, compile, interpret -except ImportError: - if 'ast' in globals(): - raise - def default_environment(): - return {} - def compile(marker): - def marker_fn(environment=None, override=None): - # 'empty markers are True' heuristic won't install extra deps. - return not marker.strip() - marker_fn.__doc__ = marker - return marker_fn - def interpret(marker, environment=None, override=None): - return compile(marker)() diff --git a/py3/lib/python3.6/site-packages/_markerlib/markers.py b/py3/lib/python3.6/site-packages/_markerlib/markers.py deleted file mode 100644 index fa83706..0000000 --- a/py3/lib/python3.6/site-packages/_markerlib/markers.py +++ /dev/null @@ -1,119 +0,0 @@ -# -*- coding: utf-8 -*- -"""Interpret PEP 345 environment markers. - -EXPR [in|==|!=|not in] EXPR [or|and] ... - -where EXPR belongs to any of those: - - python_version = '%s.%s' % (sys.version_info[0], sys.version_info[1]) - python_full_version = sys.version.split()[0] - os.name = os.name - sys.platform = sys.platform - platform.version = platform.version() - platform.machine = platform.machine() - platform.python_implementation = platform.python_implementation() - a free string, like '2.6', or 'win32' -""" - -__all__ = ['default_environment', 'compile', 'interpret'] - -import ast -import os -import platform -import sys -import weakref - -_builtin_compile = compile - -try: - from platform import python_implementation -except ImportError: - if os.name == "java": - # Jython 2.5 has ast module, but not platform.python_implementation() function. - def python_implementation(): - return "Jython" - else: - raise - - -# restricted set of variables -_VARS = {'sys.platform': sys.platform, - 'python_version': '%s.%s' % sys.version_info[:2], - # FIXME parsing sys.platform is not reliable, but there is no other - # way to get e.g. 2.7.2+, and the PEP is defined with sys.version - 'python_full_version': sys.version.split(' ', 1)[0], - 'os.name': os.name, - 'platform.version': platform.version(), - 'platform.machine': platform.machine(), - 'platform.python_implementation': python_implementation(), - 'extra': None # wheel extension - } - -for var in list(_VARS.keys()): - if '.' in var: - _VARS[var.replace('.', '_')] = _VARS[var] - -def default_environment(): - """Return copy of default PEP 385 globals dictionary.""" - return dict(_VARS) - -class ASTWhitelist(ast.NodeTransformer): - def __init__(self, statement): - self.statement = statement # for error messages - - ALLOWED = (ast.Compare, ast.BoolOp, ast.Attribute, ast.Name, ast.Load, ast.Str) - # Bool operations - ALLOWED += (ast.And, ast.Or) - # Comparison operations - ALLOWED += (ast.Eq, ast.Gt, ast.GtE, ast.In, ast.Is, ast.IsNot, ast.Lt, ast.LtE, ast.NotEq, ast.NotIn) - - def visit(self, node): - """Ensure statement only contains allowed nodes.""" - if not isinstance(node, self.ALLOWED): - raise SyntaxError('Not allowed in environment markers.\n%s\n%s' % - (self.statement, - (' ' * node.col_offset) + '^')) - return ast.NodeTransformer.visit(self, node) - - def visit_Attribute(self, node): - """Flatten one level of attribute access.""" - new_node = ast.Name("%s.%s" % (node.value.id, node.attr), node.ctx) - return ast.copy_location(new_node, node) - -def parse_marker(marker): - tree = ast.parse(marker, mode='eval') - new_tree = ASTWhitelist(marker).generic_visit(tree) - return new_tree - -def compile_marker(parsed_marker): - return _builtin_compile(parsed_marker, '', 'eval', - dont_inherit=True) - -_cache = weakref.WeakValueDictionary() - -def compile(marker): - """Return compiled marker as a function accepting an environment dict.""" - try: - return _cache[marker] - except KeyError: - pass - if not marker.strip(): - def marker_fn(environment=None, override=None): - """""" - return True - else: - compiled_marker = compile_marker(parse_marker(marker)) - def marker_fn(environment=None, override=None): - """override updates environment""" - if override is None: - override = {} - if environment is None: - environment = default_environment() - environment.update(override) - return eval(compiled_marker, environment) - marker_fn.__doc__ = marker - _cache[marker] = marker_fn - return _cache[marker] - -def interpret(marker, environment=None): - return compile(marker)(environment) diff --git a/py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/LICENSE b/py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/LICENSE deleted file mode 100644 index 727ded8..0000000 --- a/py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2013 Chris Smith - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/RECORD b/py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/RECORD deleted file mode 100644 index 7ed19aa..0000000 --- a/py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/RECORD +++ /dev/null @@ -1,24 +0,0 @@ -arrow/__init__.py,sha256=EDUi1LhVMu-m8T0aXYjKNejJ27OHRPuZIS-BPnNrATw,151 -arrow/_version.py,sha256=8YscPb5efWnULR4pGFhtuY0RRhqCGPpeGi69mc5MYv4,23 -arrow/api.py,sha256=If7DvsjCnVhn9UWqMs49L3v5WhD6Kk279SLjetaym6c,1182 -arrow/arrow.py,sha256=VNYvCHellOePYCCj6Qs58SfWq8s0YvVN_B_qYx-4IWU,44180 -arrow/factory.py,sha256=tb-a895W4K5kUuAcTTYwmWkjpwY7R98HgWWrlVlovtQ,10274 -arrow/formatter.py,sha256=IfGxEDjSxREsPTkH7J9Z16cvyuxOIF-lV2AlPCF9gcM,3495 -arrow/locales.py,sha256=EIYXh0dQlfDt7Eh-Y1kCPjCYkvYb3QT2PEgaM1OZqXM,90227 -arrow/parser.py,sha256=olT_lkMGSA_iUKRRBor63MeEOO2HwENBuNQtEU09JD8,12048 -arrow/util.py,sha256=inZSvSbI4iXWC5uWW716bsXnZGQUCFxy5Dz6AXSL43o,2581 -arrow-0.14.6.dist-info/LICENSE,sha256=pLdgG-UFacLJapgY_ICbAUlBDITJlxTWDJ1PsK6GH6I,579 -arrow-0.14.6.dist-info/METADATA,sha256=1Jw7uPW6FGq0TP3XCogn4kGczT8shZlMp1pnOl_7w5Y,6058 -arrow-0.14.6.dist-info/WHEEL,sha256=8zNYZbwQSXoB9IfXOjPfeNwvAsALAjffgk27FqvCWbo,110 -arrow-0.14.6.dist-info/top_level.txt,sha256=aCBThK2RIB824ctI3l9i6z94l8UYpFF-BC4m3dDzFFo,6 -arrow-0.14.6.dist-info/RECORD,, -arrow-0.14.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -arrow/__pycache__/api.cpython-36.pyc,, -arrow/__pycache__/locales.cpython-36.pyc,, -arrow/__pycache__/formatter.cpython-36.pyc,, -arrow/__pycache__/util.cpython-36.pyc,, -arrow/__pycache__/_version.cpython-36.pyc,, -arrow/__pycache__/__init__.cpython-36.pyc,, -arrow/__pycache__/parser.cpython-36.pyc,, -arrow/__pycache__/factory.cpython-36.pyc,, -arrow/__pycache__/arrow.cpython-36.pyc,, diff --git a/py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/INSTALLER b/py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/INSTALLER similarity index 100% rename from py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/INSTALLER rename to py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/INSTALLER diff --git a/py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/LICENSE b/py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/LICENSE new file mode 100644 index 0000000..2bef500 --- /dev/null +++ b/py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2019 Chris Smith + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/METADATA b/py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/METADATA similarity index 98% rename from py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/METADATA rename to py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/METADATA index fc0e271..5ca7461 100644 --- a/py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/METADATA +++ b/py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: arrow -Version: 0.14.6 +Version: 0.15.4 Summary: Better dates & times for Python Home-page: https://arrow.readthedocs.io Author: Chris Smith @@ -70,7 +70,7 @@ Python's standard library and some other low-level modules have near-complete da - Too many types: date, time, datetime, tzinfo, timedelta, relativedelta, etc. - Timezones and timestamp conversions are verbose and unpleasant - Timezone naivety is the norm -- Gaps in functionality: ISO-8601 parsing, timespans, humanization +- Gaps in functionality: ISO 8601 parsing, timespans, humanization Features -------- @@ -81,7 +81,7 @@ Features - Provides super-simple creation options for many common input scenarios - :code:`shift` method with support for relative offsets, including weeks - Formats and parses strings automatically -- Wide support for ISO-8601 +- Wide support for ISO 8601 - Timezone conversion - Timestamp available as a property - Generates time spans, ranges, floors and ceilings for time frames ranging from microsecond to year diff --git a/py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/RECORD b/py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/RECORD new file mode 100644 index 0000000..8424c39 --- /dev/null +++ b/py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/RECORD @@ -0,0 +1,26 @@ +arrow/__init__.py,sha256=DFmZLzCG5L7PBHzrD8qnJS9KKq3ftGodevaHt_HS3rE,183 +arrow/_version.py,sha256=Ypoj4dM4zqbnGvYnOqiUlHcf_l1wO2M39u5_-ECRTQU,23 +arrow/api.py,sha256=If7DvsjCnVhn9UWqMs49L3v5WhD6Kk279SLjetaym6c,1182 +arrow/arrow.py,sha256=U2nCl5uJ9QuIoet8Dc71J-82n2Xu2_LRnHPZ6kPnbik,44222 +arrow/constants.py,sha256=wEXUA72SrU6wxWfs3CZ_EBWM2Gsqz2sInM1qo2SCHg0,354 +arrow/factory.py,sha256=_-WT8QKaf_FlDySf9r_bIRiKjXJfiAXmLG790qfpD68,9605 +arrow/formatter.py,sha256=653sEFw8B40SuuABZRq4oibHkjhNzUXHZXo97Jum1sI,3922 +arrow/locales.py,sha256=AJfNWqU4qhxBP8cfOYFWeYXyp7JTFZ3ELEwUwTjOr7E,90895 +arrow/parser.py,sha256=4j4dS3RPh22WNHcMMScRAiVPrkpk7-6ZgtCJCQWqFjg,18454 +arrow/util.py,sha256=i-CoHgWQTCfF7ujLD5-PrYqXo4MNYDP2r0E5e9ul3mg,1523 +arrow-0.15.4.dist-info/LICENSE,sha256=Jrd3vlRqj7-mCjGFbHSr-Ad_gXVtGKrzUne52vcS8X0,11341 +arrow-0.15.4.dist-info/METADATA,sha256=EgwNYoMfFGGH1ASXNh-gXCoM0PzrRwYMxgWx0bW9ayY,6058 +arrow-0.15.4.dist-info/WHEEL,sha256=8zNYZbwQSXoB9IfXOjPfeNwvAsALAjffgk27FqvCWbo,110 +arrow-0.15.4.dist-info/top_level.txt,sha256=aCBThK2RIB824ctI3l9i6z94l8UYpFF-BC4m3dDzFFo,6 +arrow-0.15.4.dist-info/RECORD,, +arrow-0.15.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +arrow/__pycache__/api.cpython-36.pyc,, +arrow/__pycache__/locales.cpython-36.pyc,, +arrow/__pycache__/formatter.cpython-36.pyc,, +arrow/__pycache__/util.cpython-36.pyc,, +arrow/__pycache__/_version.cpython-36.pyc,, +arrow/__pycache__/__init__.cpython-36.pyc,, +arrow/__pycache__/parser.cpython-36.pyc,, +arrow/__pycache__/factory.cpython-36.pyc,, +arrow/__pycache__/arrow.cpython-36.pyc,, +arrow/__pycache__/constants.cpython-36.pyc,, diff --git a/py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/WHEEL b/py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/WHEEL similarity index 100% rename from py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/WHEEL rename to py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/WHEEL diff --git a/py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/top_level.txt b/py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/top_level.txt similarity index 100% rename from py3/lib/python3.6/site-packages/arrow-0.14.6.dist-info/top_level.txt rename to py3/lib/python3.6/site-packages/arrow-0.15.4.dist-info/top_level.txt diff --git a/py3/lib/python3.6/site-packages/arrow/__init__.py b/py3/lib/python3.6/site-packages/arrow/__init__.py index 9b5fa68..d99a70a 100644 --- a/py3/lib/python3.6/site-packages/arrow/__init__.py +++ b/py3/lib/python3.6/site-packages/arrow/__init__.py @@ -3,3 +3,4 @@ from ._version import __version__ from .api import get, now, utcnow from .arrow import Arrow from .factory import ArrowFactory +from .parser import ParserError diff --git a/py3/lib/python3.6/site-packages/arrow/_version.py b/py3/lib/python3.6/site-packages/arrow/_version.py index f2c260c..8782a8b 100644 --- a/py3/lib/python3.6/site-packages/arrow/_version.py +++ b/py3/lib/python3.6/site-packages/arrow/_version.py @@ -1 +1 @@ -__version__ = "0.14.6" +__version__ = "0.15.4" diff --git a/py3/lib/python3.6/site-packages/arrow/arrow.py b/py3/lib/python3.6/site-packages/arrow/arrow.py index 5ff96bd..d752e39 100644 --- a/py3/lib/python3.6/site-packages/arrow/arrow.py +++ b/py3/lib/python3.6/site-packages/arrow/arrow.py @@ -40,7 +40,7 @@ class Arrow(object): - A ``tzinfo`` object. - A ``str`` describing a timezone, similar to 'US/Pacific', or 'Europe/Berlin'. - - A ``str`` in ISO-8601 style, as in '+07:00'. + - A ``str`` in ISO 8601 style, as in '+07:00'. - A ``str``, one of the following: 'local', 'utc', 'UTC'. Usage:: @@ -66,6 +66,7 @@ class Arrow(object): elif ( isinstance(tzinfo, dt_tzinfo) and hasattr(tzinfo, "localize") + and hasattr(tzinfo, "zone") and tzinfo.zone ): tzinfo = parser.TzinfoParser.parse(tzinfo.zone) @@ -149,8 +150,13 @@ class Arrow(object): if tzinfo is None: tzinfo = dateutil_tz.tzlocal() - timestamp = cls._get_timestamp_from_input(timestamp) - dt = datetime.fromtimestamp(timestamp, tzinfo) + + if not util.is_timestamp(timestamp): + raise ValueError( + "The provided timestamp '{}' is invalid.".format(timestamp) + ) + + dt = datetime.fromtimestamp(float(timestamp), tzinfo) return cls( dt.year, @@ -171,8 +177,12 @@ class Arrow(object): """ - timestamp = cls._get_timestamp_from_input(timestamp) - dt = datetime.utcfromtimestamp(timestamp) + if not util.is_timestamp(timestamp): + raise ValueError( + "The provided timestamp '{}' is invalid.".format(timestamp) + ) + + dt = datetime.utcfromtimestamp(float(timestamp)) return cls( dt.year, @@ -413,7 +423,7 @@ class Arrow(object): - A ``tzinfo`` object. - A ``str`` describing a timezone, similar to 'US/Pacific', or 'Europe/Berlin'. - - A ``str`` in ISO-8601 style, as in '+07:00'. + - A ``str`` in ISO 8601 style, as in '+07:00'. - A ``str``, one of the following: 'local', 'utc', 'UTC'. Usage: @@ -1372,7 +1382,7 @@ class Arrow(object): if end is None: if limit is None: - raise Exception("one of 'end' or 'limit' is required") + raise ValueError("one of 'end' or 'limit' is required") return cls.max, limit @@ -1381,14 +1391,6 @@ class Arrow(object): return end, sys.maxsize return end, limit - @staticmethod - def _get_timestamp_from_input(timestamp): - - try: - return float(timestamp) - except Exception: - raise ValueError("cannot parse '{}' as a timestamp".format(timestamp)) - Arrow.min = Arrow.fromdatetime(datetime.min) Arrow.max = Arrow.fromdatetime(datetime.max) diff --git a/py3/lib/python3.6/site-packages/arrow/constants.py b/py3/lib/python3.6/site-packages/arrow/constants.py new file mode 100644 index 0000000..81e37b2 --- /dev/null +++ b/py3/lib/python3.6/site-packages/arrow/constants.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- + +# Output of time.mktime(datetime.max.timetuple()) on macOS +# This value must be hardcoded for compatibility with Windows +# Platform-independent max timestamps are hard to form +# https://stackoverflow.com/q/46133223 +MAX_TIMESTAMP = 253402318799.0 +MAX_TIMESTAMP_MS = MAX_TIMESTAMP * 1000 +MAX_TIMESTAMP_US = MAX_TIMESTAMP * 1000000 diff --git a/py3/lib/python3.6/site-packages/arrow/factory.py b/py3/lib/python3.6/site-packages/arrow/factory.py index aed4815..b6d78b6 100644 --- a/py3/lib/python3.6/site-packages/arrow/factory.py +++ b/py3/lib/python3.6/site-packages/arrow/factory.py @@ -9,7 +9,6 @@ construction scenarios. from __future__ import absolute_import import calendar -import warnings from datetime import date, datetime from datetime import tzinfo as dt_tzinfo from time import struct_time @@ -18,22 +17,7 @@ from dateutil import tz as dateutil_tz from arrow import parser from arrow.arrow import Arrow -from arrow.util import is_timestamp, isstr - - -class ArrowParseWarning(DeprecationWarning): - """Raised when arrow.get() is passed a string with no formats and matches incorrectly - on one of the default formats. - - e.g. - arrow.get('blabla2016') -> - arrow.get('13/4/2045') -> - - In version 0.15.0 this warning will become a ParserError. - """ - - -warnings.simplefilter("always", ArrowParseWarning) +from arrow.util import is_timestamp, iso_to_gregorian, isstr class ArrowFactory(object): @@ -76,7 +60,7 @@ class ArrowFactory(object): >>> arrow.get(arw) - **One** ``str``, ``float``, or ``int``, convertible to a floating-point timestamp, to get + **One** ``float`` or ``int``, convertible to a floating-point timestamp, to get that timestamp in UTC:: >>> arrow.get(1367992474.293378) @@ -85,17 +69,16 @@ class ArrowFactory(object): >>> arrow.get(1367992474) - >>> arrow.get('1367992474.293378') - - - >>> arrow.get('1367992474') - - - **One** ISO-8601-formatted ``str``, to parse it:: + **One** ISO 8601-formatted ``str``, to parse it:: >>> arrow.get('2013-09-29T01:26:43.830580') + **One** ISO 8601-formatted ``str``, in basic format, to parse it:: + + >>> arrow.get('20160413T133656.456289') + + **One** ``tzinfo``, to get the current time **converted** to that timezone:: >>> arrow.get(tz.tzlocal()) @@ -116,6 +99,16 @@ class ArrowFactory(object): >>> arrow.get(date(2013, 5, 5)) + **One** time.struct time:: + + >>> arrow.get(gmtime(0)) + + + **One** iso calendar ``tuple``, to get that week date in UTC:: + + >>> arrow.get((2013, 18, 7)) + + **Two** arguments, a naive or aware ``datetime``, and a replacement :ref:`timezone expression `:: @@ -143,11 +136,6 @@ class ArrowFactory(object): >>> arrow.get(2013, 5, 5, 12, 30, 45) - **One** time.struct time:: - - >>> arrow.get(gmtime(0)) - - """ arg_count = len(args) @@ -180,20 +168,20 @@ class ArrowFactory(object): if arg is None: return self.type.utcnow() - # try (int, float, str(int), str(float)) -> utc, from timestamp. - if is_timestamp(arg): + # try (int, float) -> utc, from timestamp. + elif not isstr(arg) and is_timestamp(arg): return self.type.utcfromtimestamp(arg) # (Arrow) -> from the object's datetime. - if isinstance(arg, Arrow): + elif isinstance(arg, Arrow): return self.type.fromdatetime(arg.datetime) # (datetime) -> from datetime. - if isinstance(arg, datetime): + elif isinstance(arg, datetime): return self.type.fromdatetime(arg) # (date) -> from date. - if isinstance(arg, date): + elif isinstance(arg, date): return self.type.fromdate(arg) # (tzinfo) -> now, @ tzinfo. @@ -202,11 +190,6 @@ class ArrowFactory(object): # (str) -> parse. elif isstr(arg): - warnings.warn( - "The .get() parsing method without a format string will parse more strictly in version 0.15.0." - "See https://github.com/crsmithdev/arrow/issues/612 for more details.", - ArrowParseWarning, - ) dt = parser.DateTimeParser(locale).parse_iso(arg) return self.type.fromdatetime(dt, tz) @@ -214,9 +197,14 @@ class ArrowFactory(object): elif isinstance(arg, struct_time): return self.type.utcfromtimestamp(calendar.timegm(arg)) + # (iso calendar) -> convert then from date + elif isinstance(arg, tuple) and len(arg) == 3: + dt = iso_to_gregorian(*arg) + return self.type.fromdate(dt) + else: raise TypeError( - "Can't parse single argument type of '{}'".format(type(arg)) + "Can't parse single argument of type '{}'".format(type(arg)) ) elif arg_count == 2: @@ -249,17 +237,12 @@ class ArrowFactory(object): # (str, format) -> parse. elif isstr(arg_1) and (isstr(arg_2) or isinstance(arg_2, list)): - warnings.warn( - "The .get() parsing method with a format string will parse more strictly in version 0.15.0." - "See https://github.com/crsmithdev/arrow/issues/612 for more details.", - ArrowParseWarning, - ) dt = parser.DateTimeParser(locale).parse(args[0], args[1]) return self.type.fromdatetime(dt, tzinfo=tz) else: raise TypeError( - "Can't parse two arguments of types '{}', '{}'".format( + "Can't parse two arguments of types '{}' and '{}'".format( type(arg_1), type(arg_2) ) ) diff --git a/py3/lib/python3.6/site-packages/arrow/formatter.py b/py3/lib/python3.6/site-packages/arrow/formatter.py index 08c89e0..80dd2c9 100644 --- a/py3/lib/python3.6/site-packages/arrow/formatter.py +++ b/py3/lib/python3.6/site-packages/arrow/formatter.py @@ -11,8 +11,12 @@ from arrow import locales, util class DateTimeFormatter(object): + # This pattern matches characters enclosed in square brackes are matched as + # an atomic group. For more info on atomic groups and how to they are + # emulated in Python's re library, see https://stackoverflow.com/a/13577411/2701578 + # TODO: test against full timezone DB _FORMAT_RE = re.compile( - r"(YYY?Y?|MM?M?M?|Do|DD?D?D?|d?dd?d?|HH?|hh?|mm?|ss?|SS?S?S?S?S?|ZZ?Z?|a|A|X)" + r"(\[(?:(?=(?P[^]]))(?P=literal))*\]|YYY?Y?|MM?M?M?|Do|DD?D?D?|d?dd?d?|HH?|hh?|mm?|ss?|SS?S?S?S?S?|ZZ?Z?|a|A|X)" ) def __init__(self, locale="en_us"): @@ -25,6 +29,9 @@ class DateTimeFormatter(object): def _format_token(self, dt, token): + if token and token.startswith("[") and token.endswith("]"): + return token[1:-1] + if token == "YYYY": return self.locale.year_full(dt.year) if token == "YY": diff --git a/py3/lib/python3.6/site-packages/arrow/locales.py b/py3/lib/python3.6/site-packages/arrow/locales.py index ae4bff7..1a50662 100644 --- a/py3/lib/python3.6/site-packages/arrow/locales.py +++ b/py3/lib/python3.6/site-packages/arrow/locales.py @@ -374,6 +374,8 @@ class SpanishLocale(Locale): "hours": "{0} horas", "day": "un día", "days": "{0} días", + "week": "una semana", + "weeks": "{0} semanas", "month": "un mes", "months": "{0} meses", "year": "un año", @@ -445,6 +447,8 @@ class FrenchLocale(Locale): "hours": "{0} heures", "day": "un jour", "days": "{0} jours", + "week": "une semaine", + "weeks": "{0} semaines", "month": "un mois", "months": "{0} mois", "year": "un an", @@ -586,6 +590,8 @@ class JapaneseLocale(Locale): "hours": "{0}時間", "day": "1日", "days": "{0}日", + "week": "1週間", + "weeks": "{0}週間", "month": "1ヶ月", "months": "{0}ヶ月", "year": "1年", @@ -799,6 +805,8 @@ class ChineseCNLocale(Locale): "hours": "{0}小时", "day": "1天", "days": "{0}天", + "week": "一周", + "weeks": "{0}周", "month": "1个月", "months": "{0}个月", "year": "1年", @@ -1189,6 +1197,8 @@ class RussianLocale(SlavicBaseLocale): "hours": ["{0} час", "{0} часа", "{0} часов"], "day": "день", "days": ["{0} день", "{0} дня", "{0} дней"], + "week": "неделю", + "weeks": ["{0} неделю", "{0} недели", "{0} недель"], "month": "месяц", "months": ["{0} месяц", "{0} месяца", "{0} месяцев"], "year": "год", @@ -1771,13 +1781,16 @@ class PortugueseLocale(Locale): timeframes = { "now": "agora", - "seconds": "segundos", + "second": "um segundo", + "seconds": "{0} segundos", "minute": "um minuto", "minutes": "{0} minutos", "hour": "uma hora", "hours": "{0} horas", "day": "um dia", "days": "{0} dias", + "week": "uma semana", + "weeks": "{0} semanas", "month": "um mês", "months": "{0} meses", "year": "um ano", @@ -1837,13 +1850,16 @@ class BrazilianPortugueseLocale(PortugueseLocale): timeframes = { "now": "agora", - "seconds": "segundos", + "second": "um segundo", + "seconds": "{0} segundos", "minute": "um minuto", "minutes": "{0} minutos", "hour": "uma hora", "hours": "{0} horas", "day": "um dia", "days": "{0} dias", + "week": "uma semana", + "weeks": "{0} semanas", "month": "um mês", "months": "{0} meses", "year": "um ano", @@ -1979,6 +1995,8 @@ class VietnameseLocale(Locale): "hours": "{0} giờ", "day": "một ngày", "days": "{0} ngày", + "week": "một tuần", + "weeks": "{0} tuần", "month": "một tháng", "months": "{0} tháng", "year": "một năm", @@ -3608,6 +3626,8 @@ class SwissLocale(Locale): "hours": "{0} Stunden", "day": "einem Tag", "days": "{0} Tagen", + "week": "einer Woche", + "weeks": "{0} Wochen", "month": "einem Monat", "months": "{0} Monaten", "year": "einem Jahr", diff --git a/py3/lib/python3.6/site-packages/arrow/parser.py b/py3/lib/python3.6/site-packages/arrow/parser.py index 9930ab0..a13b715 100644 --- a/py3/lib/python3.6/site-packages/arrow/parser.py +++ b/py3/lib/python3.6/site-packages/arrow/parser.py @@ -7,6 +7,7 @@ from datetime import datetime, timedelta from dateutil import tz from arrow import locales +from arrow.constants import MAX_TIMESTAMP, MAX_TIMESTAMP_MS, MAX_TIMESTAMP_US try: from functools import lru_cache @@ -14,29 +15,48 @@ except ImportError: # pragma: no cover from backports.functools_lru_cache import lru_cache # pragma: no cover -class ParserError(RuntimeError): +class ParserError(ValueError): + pass + + +# Allows for ParserErrors to be propagated from _build_datetime() +# when day_of_year errors occur. +# Before this, the ParserErrors were caught by the try/except in +# _parse_multiformat() and the appropriate error message was not +# transmitted to the user. +class ParserMatchError(ParserError): pass class DateTimeParser(object): _FORMAT_RE = re.compile( - r"(YYY?Y?|MM?M?M?|Do|DD?D?D?|d?d?d?d|HH?|hh?|mm?|ss?|S+|ZZ?Z?|a|A|X)" + r"(YYY?Y?|MM?M?M?|Do|DD?D?D?|d?d?d?d|HH?|hh?|mm?|ss?|S+|ZZ?Z?|a|A|x|X)" ) _ESCAPE_RE = re.compile(r"\[[^\[\]]*\]") - _ONE_OR_MORE_DIGIT_RE = re.compile(r"\d+") _ONE_OR_TWO_DIGIT_RE = re.compile(r"\d{1,2}") - _FOUR_DIGIT_RE = re.compile(r"\d{4}") + _ONE_OR_TWO_OR_THREE_DIGIT_RE = re.compile(r"\d{1,3}") + _ONE_OR_MORE_DIGIT_RE = re.compile(r"\d+") _TWO_DIGIT_RE = re.compile(r"\d{2}") - _TZ_RE = re.compile(r"[+\-]?\d{2}:?(\d{2})?") + _THREE_DIGIT_RE = re.compile(r"\d{3}") + _FOUR_DIGIT_RE = re.compile(r"\d{4}") + _TZ_Z_RE = re.compile(r"([\+\-])(\d{2})(?:(\d{2}))?|Z") + _TZ_ZZ_RE = re.compile(r"([\+\-])(\d{2})(?:\:(\d{2}))?|Z") _TZ_NAME_RE = re.compile(r"\w[\w+\-/]+") + # NOTE: timestamps cannot be parsed from natural language strings (by removing the ^...$) because it will + # break cases like "15 Jul 2000" and a format list (see issue #447) + _TIMESTAMP_RE = re.compile(r"^\-?\d+\.?\d+$") + _TIMESTAMP_EXPANDED_RE = re.compile(r"^\-?\d+$") + _TIME_RE = re.compile(r"^(\d{2})(?:\:?(\d{2}))?(?:\:?(\d{2}))?(?:([\.\,])(\d+))?$") _BASE_INPUT_RE_MAP = { "YYYY": _FOUR_DIGIT_RE, "YY": _TWO_DIGIT_RE, "MM": _TWO_DIGIT_RE, "M": _ONE_OR_TWO_DIGIT_RE, + "DDDD": _THREE_DIGIT_RE, + "DDD": _ONE_OR_TWO_OR_THREE_DIGIT_RE, "DD": _TWO_DIGIT_RE, "D": _ONE_OR_TWO_DIGIT_RE, "HH": _TWO_DIGIT_RE, @@ -47,14 +67,14 @@ class DateTimeParser(object): "m": _ONE_OR_TWO_DIGIT_RE, "ss": _TWO_DIGIT_RE, "s": _ONE_OR_TWO_DIGIT_RE, - "X": re.compile(r"\d+"), + "X": _TIMESTAMP_RE, + "x": _TIMESTAMP_EXPANDED_RE, "ZZZ": _TZ_NAME_RE, - "ZZ": _TZ_RE, - "Z": _TZ_RE, + "ZZ": _TZ_ZZ_RE, + "Z": _TZ_Z_RE, "S": _ONE_OR_MORE_DIGIT_RE, } - MARKERS = ["YYYY", "MM", "DD"] SEPARATORS = ["-", "/", "."] def __init__(self, locale="en_us", cache_size=0): @@ -90,45 +110,128 @@ class DateTimeParser(object): self._generate_pattern_re ) - def parse_iso(self, string): + # TODO: since we support more than ISO 8601, we should rename this function + # IDEA: break into multiple functions + def parse_iso(self, datetime_string): + # TODO: add a flag to normalize whitespace (useful in logs, ref issue #421) + has_space_divider = " " in datetime_string + has_t_divider = "T" in datetime_string - has_time = "T" in string or " " in string.strip() - space_divider = " " in string.strip() + num_spaces = datetime_string.count(" ") + if has_space_divider and num_spaces != 1 or has_t_divider and num_spaces > 0: + raise ParserError( + "Expected an ISO 8601-like string, but was given '{}'. Try passing in a format string to resolve this.".format( + datetime_string + ) + ) + + has_time = has_space_divider or has_t_divider + has_tz = False + + # date formats (ISO 8601 and others) to test against + # NOTE: YYYYMM is omitted to avoid confusion with YYMMDD (no longer part of ISO 8601, but is still often used) + formats = [ + "YYYY-MM-DD", + "YYYY-M-DD", + "YYYY-M-D", + "YYYY/MM/DD", + "YYYY/M/DD", + "YYYY/M/D", + "YYYY.MM.DD", + "YYYY.M.DD", + "YYYY.M.D", + "YYYYMMDD", + "YYYY-DDDD", + "YYYYDDDD", + "YYYY-MM", + "YYYY/MM", + "YYYY.MM", + "YYYY", + ] if has_time: - if space_divider: - date_string, time_string = string.split(" ", 1) + + if has_space_divider: + date_string, time_string = datetime_string.split(" ", 1) else: - date_string, time_string = string.split("T", 1) - time_parts = re.split("[+-]", time_string, 1) - has_tz = len(time_parts) > 1 - has_seconds = time_parts[0].count(":") > 1 - has_subseconds = re.search("[.,]", time_parts[0]) + date_string, time_string = datetime_string.split("T", 1) + + time_parts = re.split(r"[\+\-Z]", time_string, 1, re.IGNORECASE) + + time_components = self._TIME_RE.match(time_parts[0]) + + if time_components is None: + raise ParserError( + "Invalid time component provided. Please specify a format or provide a valid time component in the basic or extended ISO 8601 time format." + ) + + ( + hours, + minutes, + seconds, + subseconds_sep, + subseconds, + ) = time_components.groups() + + has_tz = len(time_parts) == 2 + has_minutes = minutes is not None + has_seconds = seconds is not None + has_subseconds = subseconds is not None + + is_basic_time_format = ":" not in time_parts[0] + tz_format = "Z" + + # use 'ZZ' token instead since tz offset is present in non-basic format + if has_tz and ":" in time_parts[1]: + tz_format = "ZZ" + + time_sep = "" if is_basic_time_format else ":" if has_subseconds: - formats = ["YYYY-MM-DDTHH:mm:ss%sS" % has_subseconds.group()] + time_string = "HH{time_sep}mm{time_sep}ss{subseconds_sep}S".format( + time_sep=time_sep, subseconds_sep=subseconds_sep + ) elif has_seconds: - formats = ["YYYY-MM-DDTHH:mm:ss"] + time_string = "HH{time_sep}mm{time_sep}ss".format(time_sep=time_sep) + elif has_minutes: + time_string = "HH{time_sep}mm".format(time_sep=time_sep) else: - formats = ["YYYY-MM-DDTHH:mm"] - else: - has_tz = False - # generate required formats: YYYY-MM-DD, YYYY-MM-DD, YYYY - # using various separators: -, /, . - len_markers = len(self.MARKERS) - formats = [ - separator.join(self.MARKERS[: len_markers - i]) - for i in range(len_markers) - for separator in self.SEPARATORS - ] + time_string = "HH" + + if has_space_divider: + formats = ["{} {}".format(f, time_string) for f in formats] + else: + formats = ["{}T{}".format(f, time_string) for f in formats] if has_time and has_tz: - formats = [f + "Z" for f in formats] + # Add "Z" or "ZZ" to the format strings to indicate to + # _parse_token() that a timezone needs to be parsed + formats = ["{}{}".format(f, tz_format) for f in formats] - if space_divider: - formats = [item.replace("T", " ", 1) for item in formats] + return self._parse_multiformat(datetime_string, formats) - return self._parse_multiformat(string, formats) + def parse(self, datetime_string, fmt): + + if isinstance(fmt, list): + return self._parse_multiformat(datetime_string, fmt) + + fmt_tokens, fmt_pattern_re = self._generate_pattern_re(fmt) + + match = fmt_pattern_re.search(datetime_string) + if match is None: + raise ParserMatchError( + "Failed to match '{}' when parsing '{}'".format(fmt, datetime_string) + ) + + parts = {} + for token in fmt_tokens: + if token == "Do": + value = match.group("value") + else: + value = match.group(token) + self._parse_token(token, value, parts) + + return self._build_datetime(parts) def _generate_pattern_re(self, fmt): @@ -144,8 +247,11 @@ class DateTimeParser(object): # Extract the bracketed expressions to be reinserted later. escaped_fmt = re.sub(self._ESCAPE_RE, "#", escaped_fmt) + # Any number of S is the same as one. - escaped_fmt = re.sub("S+", "S", escaped_fmt) + # TODO: allow users to specify the number of digits to parse + escaped_fmt = re.sub(r"S+", "S", escaped_fmt) + escaped_data = re.findall(self._ESCAPE_RE, fmt) fmt_pattern = escaped_fmt @@ -170,44 +276,36 @@ class DateTimeParser(object): offset += len(input_pattern) - (m.end() - m.start()) final_fmt_pattern = "" - a = fmt_pattern.split(r"\#") - b = escaped_data + split_fmt = fmt_pattern.split(r"\#") - # Due to the way Python splits, 'a' will always be longer - for i in range(len(a)): - final_fmt_pattern += a[i] - if i < len(b): - final_fmt_pattern += b[i][1:-1] + # Due to the way Python splits, 'split_fmt' will always be longer + for i in range(len(split_fmt)): + final_fmt_pattern += split_fmt[i] + if i < len(escaped_data): + final_fmt_pattern += escaped_data[i][1:-1] - return tokens, re.compile(final_fmt_pattern, flags=re.IGNORECASE) + # Wrap final_fmt_pattern in a custom word boundary to strictly + # match the formatting pattern and filter out date and time formats + # that include junk such as: blah1998-09-12 blah, blah 1998-09-12blah, + # blah1998-09-12blah. The custom word boundary matches every character + # that is not a whitespace character to allow for searching for a date + # and time string in a natural language sentence. Therefore, searching + # for a string of the form YYYY-MM-DD in "blah 1998-09-12 blah" will + # work properly. + # Reference: https://stackoverflow.com/q/14232931/3820660 + starting_word_boundary = r"(? 68 else 2000 + value @@ -218,6 +316,9 @@ class DateTimeParser(object): elif token in ["MM", "M"]: parts["month"] = int(value) + elif token in ["DDDD", "DDD"]: + parts["day_of_year"] = int(value) + elif token in ["DD", "D"]: parts["day"] = int(value) @@ -236,7 +337,7 @@ class DateTimeParser(object): elif token == "S": # We have the *most significant* digits of an arbitrary-precision integer. # We want the six most significant digits as an integer, rounded. - # FIXME: add nanosecond support somehow? + # IDEA: add nanosecond support somehow? Need datetime support for it first. value = value.ljust(7, str("0")) # floating-point (IEEE-754) defaults to half-to-even rounding @@ -251,7 +352,10 @@ class DateTimeParser(object): parts["microsecond"] = int(value[:6]) + rounding elif token == "X": - parts["timestamp"] = int(value) + parts["timestamp"] = float(value) + + elif token == "x": + parts["expanded_timestamp"] = int(value) elif token in ["ZZZ", "ZZ", "Z"]: parts["tzinfo"] = TzinfoParser.parse(value) @@ -267,9 +371,53 @@ class DateTimeParser(object): timestamp = parts.get("timestamp") - if timestamp: - tz_utc = tz.tzutc() - return datetime.fromtimestamp(timestamp, tz=tz_utc) + if timestamp is not None: + return datetime.fromtimestamp(timestamp, tz=tz.tzutc()) + + expanded_timestamp = parts.get("expanded_timestamp") + + if expanded_timestamp is not None: + + if expanded_timestamp > MAX_TIMESTAMP: + if expanded_timestamp < MAX_TIMESTAMP_MS: + expanded_timestamp /= 1000.0 + elif expanded_timestamp < MAX_TIMESTAMP_US: + expanded_timestamp /= 1000000.0 + else: + raise ValueError( + "The specified timestamp '{}' is too large.".format( + expanded_timestamp + ) + ) + + return datetime.fromtimestamp(expanded_timestamp, tz=tz.tzutc()) + + day_of_year = parts.get("day_of_year") + + if day_of_year is not None: + year = parts.get("year") + month = parts.get("month") + if year is None: + raise ParserError( + "Year component is required with the DDD and DDDD tokens." + ) + + if month is not None: + raise ParserError( + "Month component is not allowed with the DDD and DDDD tokens." + ) + + date_string = "{}-{}".format(year, day_of_year) + try: + dt = datetime.strptime(date_string, "%Y-%j") + except ValueError: + raise ParserError( + "The provided day of year '{}' is invalid.".format(day_of_year) + ) + + parts["year"] = dt.year + parts["month"] = dt.month + parts["day"] = dt.day am_pm = parts.get("am_pm") hour = parts.get("hour", 0) @@ -279,6 +427,21 @@ class DateTimeParser(object): elif am_pm == "am" and hour == 12: hour = 0 + # Support for midnight at the end of day + if hour == 24: + if parts.get("minute", 0) != 0: + raise ParserError("Midnight at the end of day must not contain minutes") + if parts.get("second", 0) != 0: + raise ParserError("Midnight at the end of day must not contain seconds") + if parts.get("microsecond", 0) != 0: + raise ParserError( + "Midnight at the end of day must not contain microseconds" + ) + hour = 0 + day_increment = 1 + else: + day_increment = 0 + # account for rounding up to 1000000 microsecond = parts.get("microsecond", 0) if microsecond == 1000000: @@ -287,7 +450,7 @@ class DateTimeParser(object): else: second_increment = 0 - increment = timedelta(seconds=second_increment) + increment = timedelta(days=day_increment, seconds=second_increment) return ( datetime( @@ -311,32 +474,18 @@ class DateTimeParser(object): try: _datetime = self.parse(string, fmt) break - except ParserError: + except ParserMatchError: pass if _datetime is None: raise ParserError( - "Could not match input to any of {} on '{}'".format(formats, string) + "Could not match input '{}' to any of the following formats: {}".format( + string, ", ".join(formats) + ) ) return _datetime - @staticmethod - def _map_lookup(input_map, key): - - try: - return input_map[key] - except KeyError: - raise ParserError('Could not match "{}" to {}'.format(key, input_map)) - - @staticmethod - def _try_timestamp(string): - - try: - return float(string) - except Exception: - return None - # generates a capture group of choices separated by an OR operator @staticmethod def _generate_choice_re(choices, flags=0): @@ -344,23 +493,22 @@ class DateTimeParser(object): class TzinfoParser(object): - - _TZINFO_RE = re.compile(r"([+\-])?(\d\d):?(\d\d)?") + _TZINFO_RE = re.compile(r"^([\+\-])?(\d{2})(?:\:?(\d{2}))?$") @classmethod - def parse(cls, string): + def parse(cls, tzinfo_string): tzinfo = None - if string == "local": + if tzinfo_string == "local": tzinfo = tz.tzlocal() - elif string in ["utc", "UTC"]: + elif tzinfo_string in ["utc", "UTC", "Z"]: tzinfo = tz.tzutc() else: - iso_match = cls._TZINFO_RE.match(string) + iso_match = cls._TZINFO_RE.match(tzinfo_string) if iso_match: sign, hours, minutes = iso_match.groups() @@ -374,9 +522,11 @@ class TzinfoParser(object): tzinfo = tz.tzoffset(None, seconds) else: - tzinfo = tz.gettz(string) + tzinfo = tz.gettz(tzinfo_string) if tzinfo is None: - raise ParserError('Could not parse timezone expression "{}"'.format(string)) + raise ParserError( + 'Could not parse timezone expression "{}"'.format(tzinfo_string) + ) return tzinfo diff --git a/py3/lib/python3.6/site-packages/arrow/util.py b/py3/lib/python3.6/site-packages/arrow/util.py index 03132f7..62f1a05 100644 --- a/py3/lib/python3.6/site-packages/arrow/util.py +++ b/py3/lib/python3.6/site-packages/arrow/util.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import -import sys -import warnings +import datetime def total_seconds(td): # pragma: no cover @@ -10,15 +9,39 @@ def total_seconds(td): # pragma: no cover def is_timestamp(value): - if type(value) == bool: + """Check if value is a valid timestamp.""" + if isinstance(value, bool): + return False + if not ( + isinstance(value, int) or isinstance(value, float) or isinstance(value, str) + ): return False try: float(value) return True - except Exception: + except ValueError: return False +# Credit to https://stackoverflow.com/a/1700069 +def iso_to_gregorian(iso_year, iso_week, iso_day): + """Converts an ISO week date tuple into a datetime object.""" + + if not 1 <= iso_week <= 53: + raise ValueError("ISO Calendar week value must be between 1-53.") + + if not 1 <= iso_day <= 7: + raise ValueError("ISO Calendar day value must be between 1-7") + + # The first week of the year always contains 4 Jan. + fourth_jan = datetime.date(iso_year, 1, 4) + delta = datetime.timedelta(fourth_jan.isoweekday() - 1) + year_start = fourth_jan - delta + gregorian = year_start + datetime.timedelta(days=iso_day - 1, weeks=iso_week - 1) + + return gregorian + + # Python 2.7 / 3.0+ definitions for isstr function. try: # pragma: no cover @@ -34,62 +57,4 @@ except NameError: # pragma: no cover return isinstance(s, str) -class list_to_iter_shim(list): - """ A temporary shim for functions that currently return a list but that will, after a - deprecation period, return an iteratator. - """ - - def __init__(self, iterable=(), **kwargs): - """ Equivalent to list(iterable). warn_text will be emitted on all non-iterator operations. - """ - self._warn_text = ( - kwargs.pop("warn_text", None) - or "this object will be converted to an iterator in a future release" - ) - self._iter_count = 0 - list.__init__(self, iterable, **kwargs) - - def _warn(self): - warnings.warn(self._warn_text, DeprecationWarning) - - def __iter__(self): - self._iter_count += 1 - if self._iter_count > 1: - self._warn() - return list.__iter__(self) - - def _wrap_method(name): - list_func = getattr(list, name) - - def wrapper(self, *args, **kwargs): - self._warn() - return list_func(self, *args, **kwargs) - - return wrapper - - __contains__ = _wrap_method("__contains__") - __add__ = _wrap_method("__add__") - __mul__ = _wrap_method("__mul__") - __getitem__ = _wrap_method("__getitem__") - # Ideally, we would throw warnings from __len__, but list(x) calls len(x) - index = _wrap_method("index") - count = _wrap_method("count") - __setitem__ = _wrap_method("__setitem__") - __delitem__ = _wrap_method("__delitem__") - append = _wrap_method("append") - if sys.version_info.major >= 3: # pragma: no cover - clear = _wrap_method("clear") - copy = _wrap_method("copy") - extend = _wrap_method("extend") - __iadd__ = _wrap_method("__iadd__") - __imul__ = _wrap_method("__imul__") - insert = _wrap_method("insert") - pop = _wrap_method("pop") - remove = _wrap_method("remove") - reverse = _wrap_method("reverse") - sort = _wrap_method("sort") - - del _wrap_method - - -__all__ = ["total_seconds", "is_timestamp", "isstr", "list_to_iter_shim"] +__all__ = ["total_seconds", "is_timestamp", "isstr", "iso_to_gregorian"] diff --git a/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/COPYING b/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/COPYING new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/COPYING.LESSER b/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/COPYING.LESSER new file mode 100644 index 0000000..2d2d780 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/COPYING.LESSER @@ -0,0 +1,510 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/INSTALLER b/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/INSTALLER similarity index 100% rename from py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/INSTALLER rename to py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/INSTALLER diff --git a/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/METADATA b/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/METADATA new file mode 100644 index 0000000..2805693 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/METADATA @@ -0,0 +1,117 @@ +Metadata-Version: 2.1 +Name: astroid +Version: 2.3.3 +Summary: An abstract syntax tree for Python with inference support. +Home-page: https://github.com/PyCQA/astroid +Author: Python Code Quality Authority +Author-email: code-quality@python.org +License: LGPL +Platform: UNKNOWN +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Software Development :: Quality Assurance +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=3.5.* +Requires-Dist: lazy-object-proxy (==1.4.*) +Requires-Dist: six (~=1.12) +Requires-Dist: wrapt (==1.11.*) +Requires-Dist: typed-ast (<1.5,>=1.4.0) ; implementation_name == "cpython" and python_version < "3.8" + +Astroid +======= + +.. image:: https://travis-ci.org/PyCQA/astroid.svg?branch=master + :target: https://travis-ci.org/PyCQA/astroid + +.. image:: https://ci.appveyor.com/api/projects/status/co3u42kunguhbh6l/branch/master?svg=true + :alt: AppVeyor Build Status + :target: https://ci.appveyor.com/project/PCManticore/astroid + +.. image:: https://coveralls.io/repos/github/PyCQA/astroid/badge.svg?branch=master + :target: https://coveralls.io/github/PyCQA/astroid?branch=master + +.. image:: https://readthedocs.org/projects/astroid/badge/?version=latest + :target: http://astroid.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/ambv/black + +.. |tideliftlogo| image:: doc/media/Tidelift_Logos_RGB_Tidelift_Shorthand_On-White_small.png + :width: 75 + :height: 60 + :alt: Tidelift + +.. list-table:: + :widths: 10 100 + + * - |tideliftlogo| + - Professional support for astroid is available as part of the `Tidelift + Subscription`_. Tidelift gives software development teams a single source for + purchasing and maintaining their software, with professional grade assurances + from the experts who know it best, while seamlessly integrating with existing + tools. + +.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-astroid?utm_source=pypi-astroid&utm_medium=referral&utm_campaign=readme + + + +What's this? +------------ + +The aim of this module is to provide a common base representation of +python source code. It is currently the library powering pylint's capabilities. + +It provides a compatible representation which comes from the `_ast` +module. It rebuilds the tree generated by the builtin _ast module by +recursively walking down the AST and building an extended ast. The new +node classes have additional methods and attributes for different +usages. They include some support for static inference and local name +scopes. Furthermore, astroid can also build partial trees by inspecting living +objects. + + +Installation +------------ + +Extract the tarball, jump into the created directory and run:: + + pip install . + + +If you want to do an editable installation, you can run:: + + pip install -e . + + +If you have any questions, please mail the code-quality@python.org +mailing list for support. See +http://mail.python.org/mailman/listinfo/code-quality for subscription +information and archives. + +Documentation +------------- +http://astroid.readthedocs.io/en/latest/ + + +Python Versions +--------------- + +astroid 2.0 is currently available for Python 3 only. If you want Python 2 +support, older versions of astroid will still supported until 2020. + +Test +---- + +Tests are in the 'test' subdirectory. To launch the whole tests suite, you can use +either `tox` or `pytest`:: + + tox + pytest astroid + + diff --git a/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/RECORD b/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/RECORD new file mode 100644 index 0000000..b657ff4 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/RECORD @@ -0,0 +1,145 @@ +astroid/__init__.py,sha256=tJJMsKzMv8hUgw3y0VQAAMx9BO-nrNUcNy_wI0XBFXo,5538 +astroid/__pkginfo__.py,sha256=vS7X-qu0abKFCIxjA0h9994nl1zj7Ziu3lEz9jniONU,2053 +astroid/_ast.py,sha256=6OGeHGRbK6oLmrsw6-UOpLFlIV1rStrA7BNpKGsu5Lw,1406 +astroid/arguments.py,sha256=cui-UmbEeywSk0eitSrOhi9F0Ci2clS4qYXTi8uXRs4,11783 +astroid/as_string.py,sha256=8SoRjh8UlDRWkbFMTvse9th8flPt6iu9xOcBip1s1f8,22411 +astroid/bases.py,sha256=G2Zs5OEHoshjLJT8e-ApDH9Q3EZtC27cKJ5yKf84_7w,18698 +astroid/builder.py,sha256=0wrC4-ausU_nEEkgI8LJTsrNFN_XCbOkqoG2DsKCsks,16023 +astroid/context.py,sha256=VsyUDVB1J9fk1o8MQoE4ygfC7gdNjVYVUD4Bhgs9JM0,5164 +astroid/decorators.py,sha256=m0v63YRiQKc66-g8ckkYeJ0d5cji8AhkUxFPbTfLVDc,4229 +astroid/exceptions.py,sha256=_IJRdLfyNSPVjxYgEd11Uu9XpdqE7uBCVOEIxt3ua70,7047 +astroid/helpers.py,sha256=3HOFwK0ieIoLu7JhrbM1r0zxPyDtTl2oNSv-tXQ2iRw,9170 +astroid/inference.py,sha256=0diHXE-ZGiWU9y31flQa3YZhg6-v4dZgD4PPFAlHJGc,33023 +astroid/manager.py,sha256=p7YPLYupDzG05OxR8qqF4fWMJExFAGIjTbVunPT3ECQ,12998 +astroid/mixins.py,sha256=F2rv2Ow7AU3YT_2jitVJik95ZWRVK6hpf8BrkkspzUY,5571 +astroid/modutils.py,sha256=1mBU_-rZH5-9K4nXB9hPi4mesi-pdlDltM_A-OU3zec,23425 +astroid/node_classes.py,sha256=FVYqErzW6lEHEZz3x_ZsqpyR1nyNOvnt0_Oi86btwAQ,140093 +astroid/nodes.py,sha256=tzYNu1tTF8bemsDitnSj7RFjQR2hrwlMDTwAmULoU5A,2957 +astroid/objects.py,sha256=q6ffgYLpyHENUY8BtiZAPHhnz91LJbQFkuaQnrNtf7g,9879 +astroid/protocols.py,sha256=Y-Mupe42X_FrdDC6KwnLyUM4yByWicR_tfqaSGWopT0,26828 +astroid/raw_building.py,sha256=HKYGE5Ll3g0WKntVErqCacQFiyTa5OVuVieIhkvckbc,16808 +astroid/rebuilder.py,sha256=q1XtkOYkykbRhk2UXhuMGsnGZFMzCDxdvTaG4VEh6Mw,41835 +astroid/scoped_nodes.py,sha256=C-ZcmS7QNkIBGUb2wc-hbHaUtOvfcOkQxYhD8xPrwjQ,94141 +astroid/test_utils.py,sha256=Q9SsfJDCJqSdRzEkp_5i1xLGcbFDztqqkdRjjLH476o,2314 +astroid/transforms.py,sha256=1npwJWcQUSIjcpcWd1pc-dJhtHOyiboQHsETAIQd5co,3377 +astroid/util.py,sha256=jg5LnqbWSZTZP1KgpxGBuC6Lfwhn9Jb2T2TohXghmC0,4785 +astroid/brain/brain_argparse.py,sha256=VEeMCr3OIjHmCy35uc-kX6nJ5_NUOAimpGJMr6CChoA,1024 +astroid/brain/brain_attrs.py,sha256=k8zJqIXsIbQrncthrzyB5NtdPTktgVi9wG7nyl8xMzs,2208 +astroid/brain/brain_builtin_inference.py,sha256=Ttwr1Ekt1_czEF50uEjY0dA5S89WFqyyBl0sWPUaYnE,27206 +astroid/brain/brain_collections.py,sha256=8Vmsb9I19er3MycZtT6qWDrIMV_SEHtl87gTPC5qQHc,2651 +astroid/brain/brain_crypt.py,sha256=gA7Q4GVuAM4viuTGWM6SNTPQXv5Gr_mFapyKMTRcsJ0,875 +astroid/brain/brain_curses.py,sha256=tDnlCP1bEvleqCMz856yua9mM5um1p_JendFhT4rBFk,3303 +astroid/brain/brain_dataclasses.py,sha256=5WndOYSY0oi2v-Od6KdPte-FKt00LoNRH2riSB4S1os,1647 +astroid/brain/brain_dateutil.py,sha256=q2dyV2907Bw4n7m2W4EEdok3Ndv8NzeIQxAZwXBiS14,795 +astroid/brain/brain_fstrings.py,sha256=VKVMijgLE2pg2dtXM6GGFgONOxOg8qA9D5V6dYzWTbQ,2121 +astroid/brain/brain_functools.py,sha256=gGMs0cEMVXR9pRPeu3LqkMARE6yzymvC7pzmRbJCWIY,5400 +astroid/brain/brain_gi.py,sha256=-EpcKf9z3wT_7v0k0WXIZtgk3-213lkfUX9bxeKOM3Y,6810 +astroid/brain/brain_hashlib.py,sha256=cp30hX5HhWqbWG3zqcNu8N3aHGeQK4DPi4ac8owBonU,2163 +astroid/brain/brain_http.py,sha256=-cQohgE5uQ5eBBjjFg7P5c2OlganAK6yZOKA6EkKd6o,10317 +astroid/brain/brain_io.py,sha256=DJcTFMTexrsHaGg2-kHoXwonddu13ImT7NEjiF1xPiU,1470 +astroid/brain/brain_mechanize.py,sha256=xTBc-u2DMmMPeci7DVFs4L2T98DwwLF_Ob5YZviLPp8,889 +astroid/brain/brain_multiprocessing.py,sha256=4iLBXpB7Bgy_hGVx-xhV7spYKg5tc4OybIiBcuwNL7U,3017 +astroid/brain/brain_namedtuple_enum.py,sha256=JBRVBhPSicUAixPdeEerhnxeEJtVnS7T1FkVhvJcDZU,15722 +astroid/brain/brain_nose.py,sha256=kECw2jHmX0IUPX4Gx3XVGrflKGnlgPB79QHt6WU2cwQ,2211 +astroid/brain/brain_numpy_core_fromnumeric.py,sha256=_mtg-7jySDnDoxhtrNtimVZ_lbsm63jb7U0iqcBjgLY,626 +astroid/brain/brain_numpy_core_function_base.py,sha256=2jtHOa_RCMlig7UZVUWSmICFvotvu7bZKCdLZhbTc0Q,1173 +astroid/brain/brain_numpy_core_multiarray.py,sha256=e-igYgbLP8UhCq3VSlRhykhXyoMcO2M7UOcrbzfuWpQ,1890 +astroid/brain/brain_numpy_core_numeric.py,sha256=RP9L1GfhPBGK3KQeeDoo-OyFUvkVNksw0sc9a6t3NJ8,1389 +astroid/brain/brain_numpy_core_numerictypes.py,sha256=RBRdil8D5qtTj6yquQ6_JwYACKRM7vfh4p7nwy3MYLk,7706 +astroid/brain/brain_numpy_core_umath.py,sha256=GGTCDVNDKEAppXjjToNzawa8lpCFr9GEh0OY3eQulec,5279 +astroid/brain/brain_numpy_ndarray.py,sha256=GMDomYcpCfCoKa1amdtQPsdy_VMPot3QUaG9mxlApBk,8417 +astroid/brain/brain_numpy_random_mtrand.py,sha256=It76Xh4atuxwGtsHiXe4llvEKyKh0R5Wa7MgG5y5vVU,3284 +astroid/brain/brain_numpy_utils.py,sha256=NxY99MzQ-m2Md_nofdAU30DFmse2CjpgqfWvYoMDDOc,1622 +astroid/brain/brain_pkg_resources.py,sha256=S_5UED1Zg8ObEJumRdpYGnjxZzemh_G_NFj3p5NGPfc,2262 +astroid/brain/brain_pytest.py,sha256=RXaNUVqy2R0et0Upn4GJkVgq5SG8Pl7zLlhqQg8Xx3Q,2384 +astroid/brain/brain_qt.py,sha256=FXdziZGGzFRzukhZguFoMY4q6PSsp6ZhNJovpzDG_Kc,2464 +astroid/brain/brain_random.py,sha256=2RZY-QEXMNWp7E6h0l0-ke-DtjKTOFlTdjiQZi3XdQc,2432 +astroid/brain/brain_re.py,sha256=le7VJHUAf80HyE_aQCh7_8FyDVK6JwNWA--c9RaMVQ8,1128 +astroid/brain/brain_six.py,sha256=6QHcKXoYf8yMMXWkx3g3lK0kqB5OFeYcXwjUTdgWTMw,6146 +astroid/brain/brain_ssl.py,sha256=2quiZVA_BW8PWmkAsOuYanq9Hvb93LT7c9YVslw3r14,3634 +astroid/brain/brain_subprocess.py,sha256=iXuKDWsUJhJDdKLDm6N8EiBw78Pjn-Xw-UJFk5gvup0,3668 +astroid/brain/brain_threading.py,sha256=73Inb3j7Tps5LQDJDGZOgR-bawttS1rk1l0LUL1WR1o,818 +astroid/brain/brain_typing.py,sha256=iFw33beNCitCJjJNvccIY6SsFJcdKVDdl-56DxDioh0,2780 +astroid/brain/brain_uuid.py,sha256=flWrk1Ve7oqYrO8GTZ3To8RBYteRfYwvash-s9KiU9o,564 +astroid/interpreter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +astroid/interpreter/dunder_lookup.py,sha256=dP-AZU_aGPNt03b1ttrMglxzeU3NtgnG0MfpSLPH6sg,2155 +astroid/interpreter/objectmodel.py,sha256=7wQbTJhoUwH89x3tBfaA9WLaudBjwKcNpsBPWBQM_7U,23935 +astroid/interpreter/_import/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +astroid/interpreter/_import/spec.py,sha256=L48FismdLnk6wjyAzIzJocKVdkBmbQlJgxwzeJ2_luA,11318 +astroid/interpreter/_import/util.py,sha256=inubUz6F3_kaMFaeleKUW6E6wCMIPrhU882zvwEZ02I,255 +astroid-2.3.3.dist-info/COPYING,sha256=qxX9UmvY3Rip5368E5ZWv00z6X_HI4zRG_YOK5uGZsY,17987 +astroid-2.3.3.dist-info/COPYING.LESSER,sha256=qb3eVhbs3R6YC0TzYGAO6Hg7H5m4zIOivrFjoKOQ6GE,26527 +astroid-2.3.3.dist-info/METADATA,sha256=i0Ut5kY28jjA7pIT7o-_UbHKI5HbTXA0xQubIxcHO8w,3869 +astroid-2.3.3.dist-info/WHEEL,sha256=p46_5Uhzqz6AzeSosiOnxK-zmFja1i22CrQCjmYe8ec,92 +astroid-2.3.3.dist-info/top_level.txt,sha256=HsdW4O2x7ZXRj6k-agi3RaQybGLobI3VSE-jt4vQUXM,8 +astroid-2.3.3.dist-info/RECORD,, +astroid-2.3.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +astroid/interpreter/_import/__pycache__/spec.cpython-36.pyc,, +astroid/interpreter/_import/__pycache__/util.cpython-36.pyc,, +astroid/interpreter/_import/__pycache__/__init__.cpython-36.pyc,, +astroid/interpreter/__pycache__/objectmodel.cpython-36.pyc,, +astroid/interpreter/__pycache__/__init__.cpython-36.pyc,, +astroid/interpreter/__pycache__/dunder_lookup.cpython-36.pyc,, +astroid/__pycache__/test_utils.cpython-36.pyc,, +astroid/__pycache__/context.cpython-36.pyc,, +astroid/__pycache__/__pkginfo__.cpython-36.pyc,, +astroid/__pycache__/_ast.cpython-36.pyc,, +astroid/__pycache__/protocols.cpython-36.pyc,, +astroid/__pycache__/bases.cpython-36.pyc,, +astroid/__pycache__/node_classes.cpython-36.pyc,, +astroid/__pycache__/raw_building.cpython-36.pyc,, +astroid/__pycache__/nodes.cpython-36.pyc,, +astroid/__pycache__/modutils.cpython-36.pyc,, +astroid/__pycache__/objects.cpython-36.pyc,, +astroid/__pycache__/mixins.cpython-36.pyc,, +astroid/__pycache__/helpers.cpython-36.pyc,, +astroid/__pycache__/scoped_nodes.cpython-36.pyc,, +astroid/__pycache__/util.cpython-36.pyc,, +astroid/__pycache__/arguments.cpython-36.pyc,, +astroid/__pycache__/as_string.cpython-36.pyc,, +astroid/__pycache__/inference.cpython-36.pyc,, +astroid/__pycache__/__init__.cpython-36.pyc,, +astroid/__pycache__/builder.cpython-36.pyc,, +astroid/__pycache__/exceptions.cpython-36.pyc,, +astroid/__pycache__/manager.cpython-36.pyc,, +astroid/__pycache__/decorators.cpython-36.pyc,, +astroid/__pycache__/transforms.cpython-36.pyc,, +astroid/__pycache__/rebuilder.cpython-36.pyc,, +astroid/brain/__pycache__/brain_functools.cpython-36.pyc,, +astroid/brain/__pycache__/brain_numpy_core_multiarray.cpython-36.pyc,, +astroid/brain/__pycache__/brain_subprocess.cpython-36.pyc,, +astroid/brain/__pycache__/brain_gi.cpython-36.pyc,, +astroid/brain/__pycache__/brain_numpy_random_mtrand.cpython-36.pyc,, +astroid/brain/__pycache__/brain_dataclasses.cpython-36.pyc,, +astroid/brain/__pycache__/brain_numpy_core_numerictypes.cpython-36.pyc,, +astroid/brain/__pycache__/brain_typing.cpython-36.pyc,, +astroid/brain/__pycache__/brain_builtin_inference.cpython-36.pyc,, +astroid/brain/__pycache__/brain_namedtuple_enum.cpython-36.pyc,, +astroid/brain/__pycache__/brain_re.cpython-36.pyc,, +astroid/brain/__pycache__/brain_uuid.cpython-36.pyc,, +astroid/brain/__pycache__/brain_crypt.cpython-36.pyc,, +astroid/brain/__pycache__/brain_collections.cpython-36.pyc,, +astroid/brain/__pycache__/brain_io.cpython-36.pyc,, +astroid/brain/__pycache__/brain_nose.cpython-36.pyc,, +astroid/brain/__pycache__/brain_dateutil.cpython-36.pyc,, +astroid/brain/__pycache__/brain_numpy_core_numeric.cpython-36.pyc,, +astroid/brain/__pycache__/brain_numpy_utils.cpython-36.pyc,, +astroid/brain/__pycache__/brain_numpy_core_umath.cpython-36.pyc,, +astroid/brain/__pycache__/brain_hashlib.cpython-36.pyc,, +astroid/brain/__pycache__/brain_six.cpython-36.pyc,, +astroid/brain/__pycache__/brain_qt.cpython-36.pyc,, +astroid/brain/__pycache__/brain_argparse.cpython-36.pyc,, +astroid/brain/__pycache__/brain_http.cpython-36.pyc,, +astroid/brain/__pycache__/brain_random.cpython-36.pyc,, +astroid/brain/__pycache__/brain_curses.cpython-36.pyc,, +astroid/brain/__pycache__/brain_pkg_resources.cpython-36.pyc,, +astroid/brain/__pycache__/brain_numpy_core_fromnumeric.cpython-36.pyc,, +astroid/brain/__pycache__/brain_ssl.cpython-36.pyc,, +astroid/brain/__pycache__/brain_threading.cpython-36.pyc,, +astroid/brain/__pycache__/brain_attrs.cpython-36.pyc,, +astroid/brain/__pycache__/brain_pytest.cpython-36.pyc,, +astroid/brain/__pycache__/brain_numpy_ndarray.cpython-36.pyc,, +astroid/brain/__pycache__/brain_mechanize.cpython-36.pyc,, +astroid/brain/__pycache__/brain_fstrings.cpython-36.pyc,, +astroid/brain/__pycache__/brain_multiprocessing.cpython-36.pyc,, +astroid/brain/__pycache__/brain_numpy_core_function_base.cpython-36.pyc,, diff --git a/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/WHEEL b/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/WHEEL new file mode 100644 index 0000000..3b5c403 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.33.6) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/top_level.txt b/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/top_level.txt new file mode 100644 index 0000000..450d4fe --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid-2.3.3.dist-info/top_level.txt @@ -0,0 +1 @@ +astroid diff --git a/py3/lib/python3.6/site-packages/astroid/__init__.py b/py3/lib/python3.6/site-packages/astroid/__init__.py new file mode 100644 index 0000000..d36a5b4 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/__init__.py @@ -0,0 +1,166 @@ +# Copyright (c) 2006-2013, 2015 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2016 Moises Lopez +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Python Abstract Syntax Tree New Generation + +The aim of this module is to provide a common base representation of +python source code for projects such as pychecker, pyreverse, +pylint... Well, actually the development of this library is essentially +governed by pylint's needs. + +It extends class defined in the python's _ast module with some +additional methods and attributes. Instance attributes are added by a +builder object, which can either generate extended ast (let's call +them astroid ;) by visiting an existent ast tree or by inspecting living +object. Methods are added by monkey patching ast classes. + +Main modules are: + +* nodes and scoped_nodes for more information about methods and + attributes added to different node classes + +* the manager contains a high level object to get astroid trees from + source files and living objects. It maintains a cache of previously + constructed tree for quick access + +* builder contains the class responsible to build astroid trees +""" + +import enum +import itertools +import os +import sys + +import wrapt + + +_Context = enum.Enum("Context", "Load Store Del") +Load = _Context.Load +Store = _Context.Store +Del = _Context.Del +del _Context + + +from .__pkginfo__ import version as __version__ + +# WARNING: internal imports order matters ! + +# pylint: disable=redefined-builtin + +# make all exception classes accessible from astroid package +from astroid.exceptions import * + +# make all node classes accessible from astroid package +from astroid.nodes import * + +# trigger extra monkey-patching +from astroid import inference + +# more stuff available +from astroid import raw_building +from astroid.bases import BaseInstance, Instance, BoundMethod, UnboundMethod +from astroid.node_classes import are_exclusive, unpack_infer +from astroid.scoped_nodes import builtin_lookup +from astroid.builder import parse, extract_node +from astroid.util import Uninferable + +# make a manager instance (borg) accessible from astroid package +from astroid.manager import AstroidManager + +MANAGER = AstroidManager() +del AstroidManager + +# transform utilities (filters and decorator) + + +# pylint: disable=dangerous-default-value +@wrapt.decorator +def _inference_tip_cached(func, instance, args, kwargs, _cache={}): + """Cache decorator used for inference tips""" + node = args[0] + try: + return iter(_cache[func, node]) + except KeyError: + result = func(*args, **kwargs) + # Need to keep an iterator around + original, copy = itertools.tee(result) + _cache[func, node] = list(copy) + return original + + +# pylint: enable=dangerous-default-value + + +def inference_tip(infer_function, raise_on_overwrite=False): + """Given an instance specific inference function, return a function to be + given to MANAGER.register_transform to set this inference function. + + :param bool raise_on_overwrite: Raise an `InferenceOverwriteError` + if the inference tip will overwrite another. Used for debugging + + Typical usage + + .. sourcecode:: python + + MANAGER.register_transform(Call, inference_tip(infer_named_tuple), + predicate) + + .. Note:: + + Using an inference tip will override + any previously set inference tip for the given + node. Use a predicate in the transform to prevent + excess overwrites. + """ + + def transform(node, infer_function=infer_function): + if ( + raise_on_overwrite + and node._explicit_inference is not None + and node._explicit_inference is not infer_function + ): + raise InferenceOverwriteError( + "Inference already set to {existing_inference}. " + "Trying to overwrite with {new_inference} for {node}".format( + existing_inference=infer_function, + new_inference=node._explicit_inference, + node=node, + ) + ) + # pylint: disable=no-value-for-parameter + node._explicit_inference = _inference_tip_cached(infer_function) + return node + + return transform + + +def register_module_extender(manager, module_name, get_extension_mod): + def transform(node): + extension_module = get_extension_mod() + for name, objs in extension_module.locals.items(): + node.locals[name] = objs + for obj in objs: + if obj.parent is extension_module: + obj.parent = node + + manager.register_transform(Module, transform, lambda n: n.name == module_name) + + +# load brain plugins +BRAIN_MODULES_DIR = os.path.join(os.path.dirname(__file__), "brain") +if BRAIN_MODULES_DIR not in sys.path: + # add it to the end of the list so user path take precedence + sys.path.append(BRAIN_MODULES_DIR) +# load modules in this directory +for module in os.listdir(BRAIN_MODULES_DIR): + if module.endswith(".py"): + __import__(module[:-3]) diff --git a/py3/lib/python3.6/site-packages/astroid/__pkginfo__.py b/py3/lib/python3.6/site-packages/astroid/__pkginfo__.py new file mode 100644 index 0000000..4a17b5d --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/__pkginfo__.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015-2017 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2015 Radosław Ganczarek +# Copyright (c) 2016 Moises Lopez +# Copyright (c) 2017 Hugo +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2017 Calen Pennington +# Copyright (c) 2018 Ashley Whetter +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""astroid packaging information""" + +version = "2.3.3" +numversion = tuple(int(elem) for elem in version.split(".") if elem.isdigit()) + +extras_require = {} +install_requires = [ + "lazy_object_proxy==1.4.*", + "six~=1.12", + "wrapt==1.11.*", + 'typed-ast>=1.4.0,<1.5;implementation_name== "cpython" and python_version<"3.8"', +] + +# pylint: disable=redefined-builtin; why license is a builtin anyway? +license = "LGPL" + +author = "Python Code Quality Authority" +author_email = "code-quality@python.org" +mailinglist = "mailto://%s" % author_email +web = "https://github.com/PyCQA/astroid" + +description = "An abstract syntax tree for Python with inference support." + +classifiers = [ + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Software Development :: Quality Assurance", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] diff --git a/py3/lib/python3.6/site-packages/astroid/_ast.py b/py3/lib/python3.6/site-packages/astroid/_ast.py new file mode 100644 index 0000000..2e44c1f --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/_ast.py @@ -0,0 +1,49 @@ +import ast +from collections import namedtuple +from functools import partial +from typing import Optional +import sys + +_ast_py2 = _ast_py3 = None +try: + import typed_ast.ast3 as _ast_py3 + import typed_ast.ast27 as _ast_py2 +except ImportError: + pass + + +PY38 = sys.version_info[:2] >= (3, 8) +if PY38: + # On Python 3.8, typed_ast was merged back into `ast` + _ast_py3 = ast + + +FunctionType = namedtuple("FunctionType", ["argtypes", "returns"]) + + +def _get_parser_module(parse_python_two: bool = False): + if parse_python_two: + parser_module = _ast_py2 + else: + parser_module = _ast_py3 + return parser_module or ast + + +def _parse(string: str, parse_python_two: bool = False): + parse_module = _get_parser_module(parse_python_two=parse_python_two) + parse_func = parse_module.parse + if _ast_py3: + if PY38: + parse_func = partial(parse_func, type_comments=True) + if not parse_python_two: + parse_func = partial(parse_func, feature_version=sys.version_info.minor) + return parse_func(string) + + +def parse_function_type_comment(type_comment: str) -> Optional[FunctionType]: + """Given a correct type comment, obtain a FunctionType object""" + if _ast_py3 is None: + return None + + func_type = _ast_py3.parse(type_comment, "", "func_type") + return FunctionType(argtypes=func_type.argtypes, returns=func_type.returns) diff --git a/py3/lib/python3.6/site-packages/astroid/arguments.py b/py3/lib/python3.6/site-packages/astroid/arguments.py new file mode 100644 index 0000000..c4bdc6d --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/arguments.py @@ -0,0 +1,285 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Anthony Sottile + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +from astroid import bases +from astroid import context as contextmod +from astroid import exceptions +from astroid import nodes +from astroid import util + + +class CallSite: + """Class for understanding arguments passed into a call site + + It needs a call context, which contains the arguments and the + keyword arguments that were passed into a given call site. + In order to infer what an argument represents, call + :meth:`infer_argument` with the corresponding function node + and the argument name. + """ + + def __init__(self, callcontext, argument_context_map=None): + if argument_context_map is None: + argument_context_map = {} + self.argument_context_map = argument_context_map + args = callcontext.args + keywords = callcontext.keywords + self.duplicated_keywords = set() + self._unpacked_args = self._unpack_args(args) + self._unpacked_kwargs = self._unpack_keywords(keywords) + + self.positional_arguments = [ + arg for arg in self._unpacked_args if arg is not util.Uninferable + ] + self.keyword_arguments = { + key: value + for key, value in self._unpacked_kwargs.items() + if value is not util.Uninferable + } + + @classmethod + def from_call(cls, call_node): + """Get a CallSite object from the given Call node.""" + callcontext = contextmod.CallContext(call_node.args, call_node.keywords) + return cls(callcontext) + + def has_invalid_arguments(self): + """Check if in the current CallSite were passed *invalid* arguments + + This can mean multiple things. For instance, if an unpacking + of an invalid object was passed, then this method will return True. + Other cases can be when the arguments can't be inferred by astroid, + for example, by passing objects which aren't known statically. + """ + return len(self.positional_arguments) != len(self._unpacked_args) + + def has_invalid_keywords(self): + """Check if in the current CallSite were passed *invalid* keyword arguments + + For instance, unpacking a dictionary with integer keys is invalid + (**{1:2}), because the keys must be strings, which will make this + method to return True. Other cases where this might return True if + objects which can't be inferred were passed. + """ + return len(self.keyword_arguments) != len(self._unpacked_kwargs) + + def _unpack_keywords(self, keywords): + values = {} + context = contextmod.InferenceContext() + context.extra_context = self.argument_context_map + for name, value in keywords: + if name is None: + # Then it's an unpacking operation (**) + try: + inferred = next(value.infer(context=context)) + except exceptions.InferenceError: + values[name] = util.Uninferable + continue + + if not isinstance(inferred, nodes.Dict): + # Not something we can work with. + values[name] = util.Uninferable + continue + + for dict_key, dict_value in inferred.items: + try: + dict_key = next(dict_key.infer(context=context)) + except exceptions.InferenceError: + values[name] = util.Uninferable + continue + if not isinstance(dict_key, nodes.Const): + values[name] = util.Uninferable + continue + if not isinstance(dict_key.value, str): + values[name] = util.Uninferable + continue + if dict_key.value in values: + # The name is already in the dictionary + values[dict_key.value] = util.Uninferable + self.duplicated_keywords.add(dict_key.value) + continue + values[dict_key.value] = dict_value + else: + values[name] = value + return values + + def _unpack_args(self, args): + values = [] + context = contextmod.InferenceContext() + context.extra_context = self.argument_context_map + for arg in args: + if isinstance(arg, nodes.Starred): + try: + inferred = next(arg.value.infer(context=context)) + except exceptions.InferenceError: + values.append(util.Uninferable) + continue + + if inferred is util.Uninferable: + values.append(util.Uninferable) + continue + if not hasattr(inferred, "elts"): + values.append(util.Uninferable) + continue + values.extend(inferred.elts) + else: + values.append(arg) + return values + + def infer_argument(self, funcnode, name, context): + """infer a function argument value according to the call context + + Arguments: + funcnode: The function being called. + name: The name of the argument whose value is being inferred. + context: Inference context object + """ + if name in self.duplicated_keywords: + raise exceptions.InferenceError( + "The arguments passed to {func!r} " " have duplicate keywords.", + call_site=self, + func=funcnode, + arg=name, + context=context, + ) + + # Look into the keywords first, maybe it's already there. + try: + return self.keyword_arguments[name].infer(context) + except KeyError: + pass + + # Too many arguments given and no variable arguments. + if len(self.positional_arguments) > len(funcnode.args.args): + if not funcnode.args.vararg: + raise exceptions.InferenceError( + "Too many positional arguments " + "passed to {func!r} that does " + "not have *args.", + call_site=self, + func=funcnode, + arg=name, + context=context, + ) + + positional = self.positional_arguments[: len(funcnode.args.args)] + vararg = self.positional_arguments[len(funcnode.args.args) :] + argindex = funcnode.args.find_argname(name)[0] + kwonlyargs = {arg.name for arg in funcnode.args.kwonlyargs} + kwargs = { + key: value + for key, value in self.keyword_arguments.items() + if key not in kwonlyargs + } + # If there are too few positionals compared to + # what the function expects to receive, check to see + # if the missing positional arguments were passed + # as keyword arguments and if so, place them into the + # positional args list. + if len(positional) < len(funcnode.args.args): + for func_arg in funcnode.args.args: + if func_arg.name in kwargs: + arg = kwargs.pop(func_arg.name) + positional.append(arg) + + if argindex is not None: + # 2. first argument of instance/class method + if argindex == 0 and funcnode.type in ("method", "classmethod"): + if context.boundnode is not None: + boundnode = context.boundnode + else: + # XXX can do better ? + boundnode = funcnode.parent.frame() + + if isinstance(boundnode, nodes.ClassDef): + # Verify that we're accessing a method + # of the metaclass through a class, as in + # `cls.metaclass_method`. In this case, the + # first argument is always the class. + method_scope = funcnode.parent.scope() + if method_scope is boundnode.metaclass(): + return iter((boundnode,)) + + if funcnode.type == "method": + if not isinstance(boundnode, bases.Instance): + boundnode = bases.Instance(boundnode) + return iter((boundnode,)) + if funcnode.type == "classmethod": + return iter((boundnode,)) + # if we have a method, extract one position + # from the index, so we'll take in account + # the extra parameter represented by `self` or `cls` + if funcnode.type in ("method", "classmethod"): + argindex -= 1 + # 2. search arg index + try: + return self.positional_arguments[argindex].infer(context) + except IndexError: + pass + + if funcnode.args.kwarg == name: + # It wants all the keywords that were passed into + # the call site. + if self.has_invalid_keywords(): + raise exceptions.InferenceError( + "Inference failed to find values for all keyword arguments " + "to {func!r}: {unpacked_kwargs!r} doesn't correspond to " + "{keyword_arguments!r}.", + keyword_arguments=self.keyword_arguments, + unpacked_kwargs=self._unpacked_kwargs, + call_site=self, + func=funcnode, + arg=name, + context=context, + ) + kwarg = nodes.Dict( + lineno=funcnode.args.lineno, + col_offset=funcnode.args.col_offset, + parent=funcnode.args, + ) + kwarg.postinit( + [(nodes.const_factory(key), value) for key, value in kwargs.items()] + ) + return iter((kwarg,)) + if funcnode.args.vararg == name: + # It wants all the args that were passed into + # the call site. + if self.has_invalid_arguments(): + raise exceptions.InferenceError( + "Inference failed to find values for all positional " + "arguments to {func!r}: {unpacked_args!r} doesn't " + "correspond to {positional_arguments!r}.", + positional_arguments=self.positional_arguments, + unpacked_args=self._unpacked_args, + call_site=self, + func=funcnode, + arg=name, + context=context, + ) + args = nodes.Tuple( + lineno=funcnode.args.lineno, + col_offset=funcnode.args.col_offset, + parent=funcnode.args, + ) + args.postinit(vararg) + return iter((args,)) + + # Check if it's a default parameter. + try: + return funcnode.args.default_value(name).infer(context) + except exceptions.NoDefault: + pass + raise exceptions.InferenceError( + "No value found for argument {name} to " "{func!r}", + call_site=self, + func=funcnode, + arg=name, + context=context, + ) diff --git a/py3/lib/python3.6/site-packages/astroid/as_string.py b/py3/lib/python3.6/site-packages/astroid/as_string.py new file mode 100644 index 0000000..3cd6e0d --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/as_string.py @@ -0,0 +1,633 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2010 Daniel Harding +# Copyright (c) 2013-2016, 2018 Claudiu Popa +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Jared Garst +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2017 rr- +# Copyright (c) 2018 brendanator +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""This module renders Astroid nodes as string: + +* :func:`to_code` function return equivalent (hopefully valid) python string + +* :func:`dump` function return an internal representation of nodes found + in the tree, useful for debugging or understanding the tree structure +""" + +# pylint: disable=unused-argument + +DOC_NEWLINE = "\0" + + +class AsStringVisitor: + """Visitor to render an Astroid node as a valid python code string""" + + def __init__(self, indent): + self.indent = indent + + def __call__(self, node): + """Makes this visitor behave as a simple function""" + return node.accept(self).replace(DOC_NEWLINE, "\n") + + def _docs_dedent(self, doc): + """Stop newlines in docs being indented by self._stmt_list""" + return '\n%s"""%s"""' % (self.indent, doc.replace("\n", DOC_NEWLINE)) + + def _stmt_list(self, stmts, indent=True): + """return a list of nodes to string""" + stmts = "\n".join(nstr for nstr in [n.accept(self) for n in stmts] if nstr) + if indent: + return self.indent + stmts.replace("\n", "\n" + self.indent) + + return stmts + + def _precedence_parens(self, node, child, is_left=True): + """Wrap child in parens only if required to keep same semantics""" + if self._should_wrap(node, child, is_left): + return "(%s)" % child.accept(self) + + return child.accept(self) + + def _should_wrap(self, node, child, is_left): + """Wrap child if: + - it has lower precedence + - same precedence with position opposite to associativity direction + """ + node_precedence = node.op_precedence() + child_precedence = child.op_precedence() + + if node_precedence > child_precedence: + # 3 * (4 + 5) + return True + + if ( + node_precedence == child_precedence + and is_left != node.op_left_associative() + ): + # 3 - (4 - 5) + # (2**3)**4 + return True + + return False + + ## visit_ methods ########################################### + + def visit_arguments(self, node): + """return an astroid.Function node as string""" + return node.format_args() + + def visit_assignattr(self, node): + """return an astroid.AssAttr node as string""" + return self.visit_attribute(node) + + def visit_assert(self, node): + """return an astroid.Assert node as string""" + if node.fail: + return "assert %s, %s" % (node.test.accept(self), node.fail.accept(self)) + return "assert %s" % node.test.accept(self) + + def visit_assignname(self, node): + """return an astroid.AssName node as string""" + return node.name + + def visit_assign(self, node): + """return an astroid.Assign node as string""" + lhs = " = ".join(n.accept(self) for n in node.targets) + return "%s = %s" % (lhs, node.value.accept(self)) + + def visit_augassign(self, node): + """return an astroid.AugAssign node as string""" + return "%s %s %s" % (node.target.accept(self), node.op, node.value.accept(self)) + + def visit_annassign(self, node): + """Return an astroid.AugAssign node as string""" + + target = node.target.accept(self) + annotation = node.annotation.accept(self) + if node.value is None: + return "%s: %s" % (target, annotation) + return "%s: %s = %s" % (target, annotation, node.value.accept(self)) + + def visit_repr(self, node): + """return an astroid.Repr node as string""" + return "`%s`" % node.value.accept(self) + + def visit_binop(self, node): + """return an astroid.BinOp node as string""" + left = self._precedence_parens(node, node.left) + right = self._precedence_parens(node, node.right, is_left=False) + if node.op == "**": + return "%s%s%s" % (left, node.op, right) + + return "%s %s %s" % (left, node.op, right) + + def visit_boolop(self, node): + """return an astroid.BoolOp node as string""" + values = ["%s" % self._precedence_parens(node, n) for n in node.values] + return (" %s " % node.op).join(values) + + def visit_break(self, node): + """return an astroid.Break node as string""" + return "break" + + def visit_call(self, node): + """return an astroid.Call node as string""" + expr_str = self._precedence_parens(node, node.func) + args = [arg.accept(self) for arg in node.args] + if node.keywords: + keywords = [kwarg.accept(self) for kwarg in node.keywords] + else: + keywords = [] + + args.extend(keywords) + return "%s(%s)" % (expr_str, ", ".join(args)) + + def visit_classdef(self, node): + """return an astroid.ClassDef node as string""" + decorate = node.decorators.accept(self) if node.decorators else "" + bases = ", ".join(n.accept(self) for n in node.bases) + metaclass = node.metaclass() + if metaclass and not node.has_metaclass_hack(): + if bases: + bases = "(%s, metaclass=%s)" % (bases, metaclass.name) + else: + bases = "(metaclass=%s)" % metaclass.name + else: + bases = "(%s)" % bases if bases else "" + docs = self._docs_dedent(node.doc) if node.doc else "" + return "\n\n%sclass %s%s:%s\n%s\n" % ( + decorate, + node.name, + bases, + docs, + self._stmt_list(node.body), + ) + + def visit_compare(self, node): + """return an astroid.Compare node as string""" + rhs_str = " ".join( + [ + "%s %s" % (op, self._precedence_parens(node, expr, is_left=False)) + for op, expr in node.ops + ] + ) + return "%s %s" % (self._precedence_parens(node, node.left), rhs_str) + + def visit_comprehension(self, node): + """return an astroid.Comprehension node as string""" + ifs = "".join(" if %s" % n.accept(self) for n in node.ifs) + return "for %s in %s%s" % ( + node.target.accept(self), + node.iter.accept(self), + ifs, + ) + + def visit_const(self, node): + """return an astroid.Const node as string""" + if node.value is Ellipsis: + return "..." + return repr(node.value) + + def visit_continue(self, node): + """return an astroid.Continue node as string""" + return "continue" + + def visit_delete(self, node): # XXX check if correct + """return an astroid.Delete node as string""" + return "del %s" % ", ".join(child.accept(self) for child in node.targets) + + def visit_delattr(self, node): + """return an astroid.DelAttr node as string""" + return self.visit_attribute(node) + + def visit_delname(self, node): + """return an astroid.DelName node as string""" + return node.name + + def visit_decorators(self, node): + """return an astroid.Decorators node as string""" + return "@%s\n" % "\n@".join(item.accept(self) for item in node.nodes) + + def visit_dict(self, node): + """return an astroid.Dict node as string""" + return "{%s}" % ", ".join(self._visit_dict(node)) + + def _visit_dict(self, node): + for key, value in node.items: + key = key.accept(self) + value = value.accept(self) + if key == "**": + # It can only be a DictUnpack node. + yield key + value + else: + yield "%s: %s" % (key, value) + + def visit_dictunpack(self, node): + return "**" + + def visit_dictcomp(self, node): + """return an astroid.DictComp node as string""" + return "{%s: %s %s}" % ( + node.key.accept(self), + node.value.accept(self), + " ".join(n.accept(self) for n in node.generators), + ) + + def visit_expr(self, node): + """return an astroid.Discard node as string""" + return node.value.accept(self) + + def visit_emptynode(self, node): + """dummy method for visiting an Empty node""" + return "" + + def visit_excepthandler(self, node): + if node.type: + if node.name: + excs = "except %s, %s" % ( + node.type.accept(self), + node.name.accept(self), + ) + else: + excs = "except %s" % node.type.accept(self) + else: + excs = "except" + return "%s:\n%s" % (excs, self._stmt_list(node.body)) + + def visit_ellipsis(self, node): + """return an astroid.Ellipsis node as string""" + return "..." + + def visit_empty(self, node): + """return an Empty node as string""" + return "" + + def visit_exec(self, node): + """return an astroid.Exec node as string""" + if node.locals: + return "exec %s in %s, %s" % ( + node.expr.accept(self), + node.locals.accept(self), + node.globals.accept(self), + ) + if node.globals: + return "exec %s in %s" % (node.expr.accept(self), node.globals.accept(self)) + return "exec %s" % node.expr.accept(self) + + def visit_extslice(self, node): + """return an astroid.ExtSlice node as string""" + return ", ".join(dim.accept(self) for dim in node.dims) + + def visit_for(self, node): + """return an astroid.For node as string""" + fors = "for %s in %s:\n%s" % ( + node.target.accept(self), + node.iter.accept(self), + self._stmt_list(node.body), + ) + if node.orelse: + fors = "%s\nelse:\n%s" % (fors, self._stmt_list(node.orelse)) + return fors + + def visit_importfrom(self, node): + """return an astroid.ImportFrom node as string""" + return "from %s import %s" % ( + "." * (node.level or 0) + node.modname, + _import_string(node.names), + ) + + def visit_functiondef(self, node): + """return an astroid.Function node as string""" + decorate = node.decorators.accept(self) if node.decorators else "" + docs = self._docs_dedent(node.doc) if node.doc else "" + trailer = ":" + if node.returns: + return_annotation = " -> " + node.returns.as_string() + trailer = return_annotation + ":" + def_format = "\n%sdef %s(%s)%s%s\n%s" + return def_format % ( + decorate, + node.name, + node.args.accept(self), + trailer, + docs, + self._stmt_list(node.body), + ) + + def visit_generatorexp(self, node): + """return an astroid.GeneratorExp node as string""" + return "(%s %s)" % ( + node.elt.accept(self), + " ".join(n.accept(self) for n in node.generators), + ) + + def visit_attribute(self, node): + """return an astroid.Getattr node as string""" + return "%s.%s" % (self._precedence_parens(node, node.expr), node.attrname) + + def visit_global(self, node): + """return an astroid.Global node as string""" + return "global %s" % ", ".join(node.names) + + def visit_if(self, node): + """return an astroid.If node as string""" + ifs = ["if %s:\n%s" % (node.test.accept(self), self._stmt_list(node.body))] + if node.has_elif_block(): + ifs.append("el%s" % self._stmt_list(node.orelse, indent=False)) + elif node.orelse: + ifs.append("else:\n%s" % self._stmt_list(node.orelse)) + return "\n".join(ifs) + + def visit_ifexp(self, node): + """return an astroid.IfExp node as string""" + return "%s if %s else %s" % ( + self._precedence_parens(node, node.body, is_left=True), + self._precedence_parens(node, node.test, is_left=True), + self._precedence_parens(node, node.orelse, is_left=False), + ) + + def visit_import(self, node): + """return an astroid.Import node as string""" + return "import %s" % _import_string(node.names) + + def visit_keyword(self, node): + """return an astroid.Keyword node as string""" + if node.arg is None: + return "**%s" % node.value.accept(self) + return "%s=%s" % (node.arg, node.value.accept(self)) + + def visit_lambda(self, node): + """return an astroid.Lambda node as string""" + args = node.args.accept(self) + body = node.body.accept(self) + if args: + return "lambda %s: %s" % (args, body) + + return "lambda: %s" % body + + def visit_list(self, node): + """return an astroid.List node as string""" + return "[%s]" % ", ".join(child.accept(self) for child in node.elts) + + def visit_listcomp(self, node): + """return an astroid.ListComp node as string""" + return "[%s %s]" % ( + node.elt.accept(self), + " ".join(n.accept(self) for n in node.generators), + ) + + def visit_module(self, node): + """return an astroid.Module node as string""" + docs = '"""%s"""\n\n' % node.doc if node.doc else "" + return docs + "\n".join(n.accept(self) for n in node.body) + "\n\n" + + def visit_name(self, node): + """return an astroid.Name node as string""" + return node.name + + def visit_pass(self, node): + """return an astroid.Pass node as string""" + return "pass" + + def visit_print(self, node): + """return an astroid.Print node as string""" + nodes = ", ".join(n.accept(self) for n in node.values) + if not node.nl: + nodes = "%s," % nodes + if node.dest: + return "print >> %s, %s" % (node.dest.accept(self), nodes) + return "print %s" % nodes + + def visit_raise(self, node): + """return an astroid.Raise node as string""" + if node.exc: + if node.inst: + if node.tback: + return "raise %s, %s, %s" % ( + node.exc.accept(self), + node.inst.accept(self), + node.tback.accept(self), + ) + return "raise %s, %s" % (node.exc.accept(self), node.inst.accept(self)) + return "raise %s" % node.exc.accept(self) + return "raise" + + def visit_return(self, node): + """return an astroid.Return node as string""" + if node.is_tuple_return() and len(node.value.elts) > 1: + elts = [child.accept(self) for child in node.value.elts] + return "return %s" % ", ".join(elts) + + if node.value: + return "return %s" % node.value.accept(self) + + return "return" + + def visit_index(self, node): + """return an astroid.Index node as string""" + return node.value.accept(self) + + def visit_set(self, node): + """return an astroid.Set node as string""" + return "{%s}" % ", ".join(child.accept(self) for child in node.elts) + + def visit_setcomp(self, node): + """return an astroid.SetComp node as string""" + return "{%s %s}" % ( + node.elt.accept(self), + " ".join(n.accept(self) for n in node.generators), + ) + + def visit_slice(self, node): + """return an astroid.Slice node as string""" + lower = node.lower.accept(self) if node.lower else "" + upper = node.upper.accept(self) if node.upper else "" + step = node.step.accept(self) if node.step else "" + if step: + return "%s:%s:%s" % (lower, upper, step) + return "%s:%s" % (lower, upper) + + def visit_subscript(self, node): + """return an astroid.Subscript node as string""" + idx = node.slice + if idx.__class__.__name__.lower() == "index": + idx = idx.value + idxstr = idx.accept(self) + if idx.__class__.__name__.lower() == "tuple" and idx.elts: + # Remove parenthesis in tuple and extended slice. + # a[(::1, 1:)] is not valid syntax. + idxstr = idxstr[1:-1] + return "%s[%s]" % (self._precedence_parens(node, node.value), idxstr) + + def visit_tryexcept(self, node): + """return an astroid.TryExcept node as string""" + trys = ["try:\n%s" % self._stmt_list(node.body)] + for handler in node.handlers: + trys.append(handler.accept(self)) + if node.orelse: + trys.append("else:\n%s" % self._stmt_list(node.orelse)) + return "\n".join(trys) + + def visit_tryfinally(self, node): + """return an astroid.TryFinally node as string""" + return "try:\n%s\nfinally:\n%s" % ( + self._stmt_list(node.body), + self._stmt_list(node.finalbody), + ) + + def visit_tuple(self, node): + """return an astroid.Tuple node as string""" + if len(node.elts) == 1: + return "(%s, )" % node.elts[0].accept(self) + return "(%s)" % ", ".join(child.accept(self) for child in node.elts) + + def visit_unaryop(self, node): + """return an astroid.UnaryOp node as string""" + if node.op == "not": + operator = "not " + else: + operator = node.op + return "%s%s" % (operator, self._precedence_parens(node, node.operand)) + + def visit_while(self, node): + """return an astroid.While node as string""" + whiles = "while %s:\n%s" % (node.test.accept(self), self._stmt_list(node.body)) + if node.orelse: + whiles = "%s\nelse:\n%s" % (whiles, self._stmt_list(node.orelse)) + return whiles + + def visit_with(self, node): # 'with' without 'as' is possible + """return an astroid.With node as string""" + items = ", ".join( + ("%s" % expr.accept(self)) + (vars and " as %s" % (vars.accept(self)) or "") + for expr, vars in node.items + ) + return "with %s:\n%s" % (items, self._stmt_list(node.body)) + + def visit_yield(self, node): + """yield an ast.Yield node as string""" + yi_val = (" " + node.value.accept(self)) if node.value else "" + expr = "yield" + yi_val + if node.parent.is_statement: + return expr + + return "(%s)" % (expr,) + + def visit_starred(self, node): + """return Starred node as string""" + return "*" + node.value.accept(self) + + # These aren't for real AST nodes, but for inference objects. + + def visit_frozenset(self, node): + return node.parent.accept(self) + + def visit_super(self, node): + return node.parent.accept(self) + + def visit_uninferable(self, node): + return str(node) + + +class AsStringVisitor3(AsStringVisitor): + """AsStringVisitor3 overwrites some AsStringVisitor methods""" + + def visit_excepthandler(self, node): + if node.type: + if node.name: + excs = "except %s as %s" % ( + node.type.accept(self), + node.name.accept(self), + ) + else: + excs = "except %s" % node.type.accept(self) + else: + excs = "except" + return "%s:\n%s" % (excs, self._stmt_list(node.body)) + + def visit_nonlocal(self, node): + """return an astroid.Nonlocal node as string""" + return "nonlocal %s" % ", ".join(node.names) + + def visit_raise(self, node): + """return an astroid.Raise node as string""" + if node.exc: + if node.cause: + return "raise %s from %s" % ( + node.exc.accept(self), + node.cause.accept(self), + ) + return "raise %s" % node.exc.accept(self) + return "raise" + + def visit_yieldfrom(self, node): + """ Return an astroid.YieldFrom node as string. """ + yi_val = (" " + node.value.accept(self)) if node.value else "" + expr = "yield from" + yi_val + if node.parent.is_statement: + return expr + + return "(%s)" % (expr,) + + def visit_asyncfunctiondef(self, node): + function = super(AsStringVisitor3, self).visit_functiondef(node) + return "async " + function.strip() + + def visit_await(self, node): + return "await %s" % node.value.accept(self) + + def visit_asyncwith(self, node): + return "async %s" % self.visit_with(node) + + def visit_asyncfor(self, node): + return "async %s" % self.visit_for(node) + + def visit_joinedstr(self, node): + # Special treatment for constants, + # as we want to join literals not reprs + string = "".join( + value.value if type(value).__name__ == "Const" else value.accept(self) + for value in node.values + ) + return "f'%s'" % string + + def visit_formattedvalue(self, node): + return "{%s}" % node.value.accept(self) + + def visit_comprehension(self, node): + """return an astroid.Comprehension node as string""" + return "%s%s" % ( + "async " if node.is_async else "", + super(AsStringVisitor3, self).visit_comprehension(node), + ) + + def visit_namedexpr(self, node): + """Return an assignment expression node as string""" + target = node.target.accept(self) + value = node.value.accept(self) + return "%s := %s" % (target, value) + + +def _import_string(names): + """return a list of (name, asname) formatted as a string""" + _names = [] + for name, asname in names: + if asname is not None: + _names.append("%s as %s" % (name, asname)) + else: + _names.append(name) + return ", ".join(_names) + + +AsStringVisitor = AsStringVisitor3 + +# This sets the default indent to 4 spaces. +to_code = AsStringVisitor(" ") diff --git a/py3/lib/python3.6/site-packages/astroid/bases.py b/py3/lib/python3.6/site-packages/astroid/bases.py new file mode 100644 index 0000000..d5b042a --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/bases.py @@ -0,0 +1,542 @@ +# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2012 FELD Boris +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2016-2017 Derek Gustafson +# Copyright (c) 2017 Calen Pennington +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Daniel Colascione + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""This module contains base classes and functions for the nodes and some +inference utils. +""" + +import builtins +import collections + +from astroid import context as contextmod +from astroid import exceptions +from astroid import util + +objectmodel = util.lazy_import("interpreter.objectmodel") +helpers = util.lazy_import("helpers") +BUILTINS = builtins.__name__ +manager = util.lazy_import("manager") +MANAGER = manager.AstroidManager() + +# TODO: check if needs special treatment +BUILTINS = "builtins" +BOOL_SPECIAL_METHOD = "__bool__" + +PROPERTIES = {BUILTINS + ".property", "abc.abstractproperty"} +# List of possible property names. We use this list in order +# to see if a method is a property or not. This should be +# pretty reliable and fast, the alternative being to check each +# decorator to see if its a real property-like descriptor, which +# can be too complicated. +# Also, these aren't qualified, because each project can +# define them, we shouldn't expect to know every possible +# property-like decorator! +POSSIBLE_PROPERTIES = { + "cached_property", + "cachedproperty", + "lazyproperty", + "lazy_property", + "reify", + "lazyattribute", + "lazy_attribute", + "LazyProperty", + "lazy", + "cache_readonly", +} + + +def _is_property(meth): + if PROPERTIES.intersection(meth.decoratornames()): + return True + stripped = { + name.split(".")[-1] + for name in meth.decoratornames() + if name is not util.Uninferable + } + if any(name in stripped for name in POSSIBLE_PROPERTIES): + return True + + # Lookup for subclasses of *property* + if not meth.decorators: + return False + for decorator in meth.decorators.nodes or (): + inferred = helpers.safe_infer(decorator) + if inferred is None or inferred is util.Uninferable: + continue + if inferred.__class__.__name__ == "ClassDef": + for base_class in inferred.bases: + if base_class.__class__.__name__ != "Name": + continue + module, _ = base_class.lookup(base_class.name) + if module.name == BUILTINS and base_class.name == "property": + return True + + return False + + +class Proxy: + """a simple proxy object + + Note: + + Subclasses of this object will need a custom __getattr__ + if new instance attributes are created. See the Const class + """ + + _proxied = None # proxied object may be set by class or by instance + + def __init__(self, proxied=None): + if proxied is not None: + self._proxied = proxied + + def __getattr__(self, name): + if name == "_proxied": + return getattr(self.__class__, "_proxied") + if name in self.__dict__: + return self.__dict__[name] + return getattr(self._proxied, name) + + def infer(self, context=None): + yield self + + +def _infer_stmts(stmts, context, frame=None): + """Return an iterator on statements inferred by each statement in *stmts*.""" + inferred = False + if context is not None: + name = context.lookupname + context = context.clone() + else: + name = None + context = contextmod.InferenceContext() + + for stmt in stmts: + if stmt is util.Uninferable: + yield stmt + inferred = True + continue + context.lookupname = stmt._infer_name(frame, name) + try: + for inferred in stmt.infer(context=context): + yield inferred + inferred = True + except exceptions.NameInferenceError: + continue + except exceptions.InferenceError: + yield util.Uninferable + inferred = True + if not inferred: + raise exceptions.InferenceError( + "Inference failed for all members of {stmts!r}.", + stmts=stmts, + frame=frame, + context=context, + ) + + +def _infer_method_result_truth(instance, method_name, context): + # Get the method from the instance and try to infer + # its return's truth value. + meth = next(instance.igetattr(method_name, context=context), None) + if meth and hasattr(meth, "infer_call_result"): + if not meth.callable(): + return util.Uninferable + try: + for value in meth.infer_call_result(instance, context=context): + if value is util.Uninferable: + return value + + inferred = next(value.infer(context=context)) + return inferred.bool_value() + except exceptions.InferenceError: + pass + return util.Uninferable + + +class BaseInstance(Proxy): + """An instance base class, which provides lookup methods for potential instances.""" + + special_attributes = None + + def display_type(self): + return "Instance of" + + def getattr(self, name, context=None, lookupclass=True): + try: + values = self._proxied.instance_attr(name, context) + except exceptions.AttributeInferenceError as exc: + if self.special_attributes and name in self.special_attributes: + return [self.special_attributes.lookup(name)] + + if lookupclass: + # Class attributes not available through the instance + # unless they are explicitly defined. + return self._proxied.getattr(name, context, class_context=False) + + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) from exc + # since we've no context information, return matching class members as + # well + if lookupclass: + try: + return values + self._proxied.getattr( + name, context, class_context=False + ) + except exceptions.AttributeInferenceError: + pass + return values + + def igetattr(self, name, context=None): + """inferred getattr""" + if not context: + context = contextmod.InferenceContext() + try: + # avoid recursively inferring the same attr on the same class + if context.push((self._proxied, name)): + raise exceptions.InferenceError( + message="Cannot infer the same attribute again", + node=self, + context=context, + ) + + # XXX frame should be self._proxied, or not ? + get_attr = self.getattr(name, context, lookupclass=False) + yield from _infer_stmts( + self._wrap_attr(get_attr, context), context, frame=self + ) + except exceptions.AttributeInferenceError as error: + try: + # fallback to class.igetattr since it has some logic to handle + # descriptors + # But only if the _proxied is the Class. + if self._proxied.__class__.__name__ != "ClassDef": + raise + attrs = self._proxied.igetattr(name, context, class_context=False) + yield from self._wrap_attr(attrs, context) + except exceptions.AttributeInferenceError as error: + raise exceptions.InferenceError(**vars(error)) from error + + def _wrap_attr(self, attrs, context=None): + """wrap bound methods of attrs in a InstanceMethod proxies""" + for attr in attrs: + if isinstance(attr, UnboundMethod): + if _is_property(attr): + yield from attr.infer_call_result(self, context) + else: + yield BoundMethod(attr, self) + elif hasattr(attr, "name") and attr.name == "": + if attr.args.args and attr.args.args[0].name == "self": + yield BoundMethod(attr, self) + continue + yield attr + else: + yield attr + + def infer_call_result(self, caller, context=None): + """infer what a class instance is returning when called""" + context = contextmod.bind_context_to_node(context, self) + inferred = False + for node in self._proxied.igetattr("__call__", context): + if node is util.Uninferable or not node.callable(): + continue + for res in node.infer_call_result(caller, context): + inferred = True + yield res + if not inferred: + raise exceptions.InferenceError(node=self, caller=caller, context=context) + + +class Instance(BaseInstance): + """A special node representing a class instance.""" + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.InstanceModel()) + + def __repr__(self): + return "" % ( + self._proxied.root().name, + self._proxied.name, + id(self), + ) + + def __str__(self): + return "Instance of %s.%s" % (self._proxied.root().name, self._proxied.name) + + def callable(self): + try: + self._proxied.getattr("__call__", class_context=False) + return True + except exceptions.AttributeInferenceError: + return False + + def pytype(self): + return self._proxied.qname() + + def display_type(self): + return "Instance of" + + def bool_value(self): + """Infer the truth value for an Instance + + The truth value of an instance is determined by these conditions: + + * if it implements __bool__ on Python 3 or __nonzero__ + on Python 2, then its bool value will be determined by + calling this special method and checking its result. + * when this method is not defined, __len__() is called, if it + is defined, and the object is considered true if its result is + nonzero. If a class defines neither __len__() nor __bool__(), + all its instances are considered true. + """ + context = contextmod.InferenceContext() + context.callcontext = contextmod.CallContext(args=[]) + context.boundnode = self + + try: + result = _infer_method_result_truth(self, BOOL_SPECIAL_METHOD, context) + except (exceptions.InferenceError, exceptions.AttributeInferenceError): + # Fallback to __len__. + try: + result = _infer_method_result_truth(self, "__len__", context) + except (exceptions.AttributeInferenceError, exceptions.InferenceError): + return True + return result + + # This is set in inference.py. + def getitem(self, index, context=None): + pass + + +class UnboundMethod(Proxy): + """a special node representing a method not bound to an instance""" + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.UnboundMethodModel()) + + def __repr__(self): + frame = self._proxied.parent.frame() + return "<%s %s of %s at 0x%s" % ( + self.__class__.__name__, + self._proxied.name, + frame.qname(), + id(self), + ) + + def implicit_parameters(self): + return 0 + + def is_bound(self): + return False + + def getattr(self, name, context=None): + if name in self.special_attributes: + return [self.special_attributes.lookup(name)] + return self._proxied.getattr(name, context) + + def igetattr(self, name, context=None): + if name in self.special_attributes: + return iter((self.special_attributes.lookup(name),)) + return self._proxied.igetattr(name, context) + + def infer_call_result(self, caller, context): + """ + The boundnode of the regular context with a function called + on ``object.__new__`` will be of type ``object``, + which is incorrect for the argument in general. + If no context is given the ``object.__new__`` call argument will + correctly inferred except when inside a call that requires + the additional context (such as a classmethod) of the boundnode + to determine which class the method was called from + """ + + # If we're unbound method __new__ of builtin object, the result is an + # instance of the class given as first argument. + if ( + self._proxied.name == "__new__" + and self._proxied.parent.frame().qname() == "%s.object" % BUILTINS + ): + if caller.args: + node_context = context.extra_context.get(caller.args[0]) + infer = caller.args[0].infer(context=node_context) + else: + infer = [] + return (Instance(x) if x is not util.Uninferable else x for x in infer) + return self._proxied.infer_call_result(caller, context) + + def bool_value(self): + return True + + +class BoundMethod(UnboundMethod): + """a special node representing a method bound to an instance""" + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.BoundMethodModel()) + + def __init__(self, proxy, bound): + UnboundMethod.__init__(self, proxy) + self.bound = bound + + def implicit_parameters(self): + return 1 + + def is_bound(self): + return True + + def _infer_type_new_call(self, caller, context): + """Try to infer what type.__new__(mcs, name, bases, attrs) returns. + + In order for such call to be valid, the metaclass needs to be + a subtype of ``type``, the name needs to be a string, the bases + needs to be a tuple of classes + """ + # pylint: disable=import-outside-toplevel; circular import + from astroid import node_classes + + # Verify the metaclass + mcs = next(caller.args[0].infer(context=context)) + if mcs.__class__.__name__ != "ClassDef": + # Not a valid first argument. + return None + if not mcs.is_subtype_of("%s.type" % BUILTINS): + # Not a valid metaclass. + return None + + # Verify the name + name = next(caller.args[1].infer(context=context)) + if name.__class__.__name__ != "Const": + # Not a valid name, needs to be a const. + return None + if not isinstance(name.value, str): + # Needs to be a string. + return None + + # Verify the bases + bases = next(caller.args[2].infer(context=context)) + if bases.__class__.__name__ != "Tuple": + # Needs to be a tuple. + return None + inferred_bases = [next(elt.infer(context=context)) for elt in bases.elts] + if any(base.__class__.__name__ != "ClassDef" for base in inferred_bases): + # All the bases needs to be Classes + return None + + # Verify the attributes. + attrs = next(caller.args[3].infer(context=context)) + if attrs.__class__.__name__ != "Dict": + # Needs to be a dictionary. + return None + cls_locals = collections.defaultdict(list) + for key, value in attrs.items: + key = next(key.infer(context=context)) + value = next(value.infer(context=context)) + # Ignore non string keys + if key.__class__.__name__ == "Const" and isinstance(key.value, str): + cls_locals[key.value].append(value) + + # Build the class from now. + cls = mcs.__class__( + name=name.value, + lineno=caller.lineno, + col_offset=caller.col_offset, + parent=caller, + ) + empty = node_classes.Pass() + cls.postinit( + bases=bases.elts, + body=[empty], + decorators=[], + newstyle=True, + metaclass=mcs, + keywords=[], + ) + cls.locals = cls_locals + return cls + + def infer_call_result(self, caller, context=None): + context = contextmod.bind_context_to_node(context, self.bound) + if ( + self.bound.__class__.__name__ == "ClassDef" + and self.bound.name == "type" + and self.name == "__new__" + and len(caller.args) == 4 + ): + # Check if we have a ``type.__new__(mcs, name, bases, attrs)`` call. + new_cls = self._infer_type_new_call(caller, context) + if new_cls: + return iter((new_cls,)) + + return super(BoundMethod, self).infer_call_result(caller, context) + + def bool_value(self): + return True + + +class Generator(BaseInstance): + """a special node representing a generator. + + Proxied class is set once for all in raw_building. + """ + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.GeneratorModel()) + + # pylint: disable=super-init-not-called + def __init__(self, parent=None): + self.parent = parent + + def callable(self): + return False + + def pytype(self): + return "%s.generator" % BUILTINS + + def display_type(self): + return "Generator" + + def bool_value(self): + return True + + def __repr__(self): + return "" % ( + self._proxied.name, + self.lineno, + id(self), + ) + + def __str__(self): + return "Generator(%s)" % (self._proxied.name) + + +class AsyncGenerator(Generator): + """Special node representing an async generator""" + + def pytype(self): + return "%s.async_generator" % BUILTINS + + def display_type(self): + return "AsyncGenerator" + + def __repr__(self): + return "" % ( + self._proxied.name, + self.lineno, + id(self), + ) + + def __str__(self): + return "AsyncGenerator(%s)" % (self._proxied.name) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_argparse.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_argparse.py new file mode 100644 index 0000000..d489911 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_argparse.py @@ -0,0 +1,33 @@ +from astroid import MANAGER, arguments, nodes, inference_tip, UseInferenceDefault + + +def infer_namespace(node, context=None): + callsite = arguments.CallSite.from_call(node) + if not callsite.keyword_arguments: + # Cannot make sense of it. + raise UseInferenceDefault() + + class_node = nodes.ClassDef("Namespace", "docstring") + class_node.parent = node.parent + for attr in set(callsite.keyword_arguments): + fake_node = nodes.EmptyNode() + fake_node.parent = class_node + fake_node.attrname = attr + class_node.instance_attrs[attr] = [fake_node] + return iter((class_node.instantiate_class(),)) + + +def _looks_like_namespace(node): + func = node.func + if isinstance(func, nodes.Attribute): + return ( + func.attrname == "Namespace" + and isinstance(func.expr, nodes.Name) + and func.expr.name == "argparse" + ) + return False + + +MANAGER.register_transform( + nodes.Call, inference_tip(infer_namespace), _looks_like_namespace +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_attrs.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_attrs.py new file mode 100644 index 0000000..670736f --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_attrs.py @@ -0,0 +1,65 @@ +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +""" +Astroid hook for the attrs library + +Without this hook pylint reports unsupported-assignment-operation +for attrs classes +""" + +import astroid +from astroid import MANAGER + + +ATTRIB_NAMES = frozenset(("attr.ib", "attrib", "attr.attrib")) +ATTRS_NAMES = frozenset(("attr.s", "attrs", "attr.attrs", "attr.attributes")) + + +def is_decorated_with_attrs(node, decorator_names=ATTRS_NAMES): + """Return True if a decorated node has + an attr decorator applied.""" + if not node.decorators: + return False + for decorator_attribute in node.decorators.nodes: + if isinstance(decorator_attribute, astroid.Call): # decorator with arguments + decorator_attribute = decorator_attribute.func + if decorator_attribute.as_string() in decorator_names: + return True + return False + + +def attr_attributes_transform(node): + """Given that the ClassNode has an attr decorator, + rewrite class attributes as instance attributes + """ + # Astroid can't infer this attribute properly + # Prevents https://github.com/PyCQA/pylint/issues/1884 + node.locals["__attrs_attrs__"] = [astroid.Unknown(parent=node)] + + for cdefbodynode in node.body: + if not isinstance(cdefbodynode, (astroid.Assign, astroid.AnnAssign)): + continue + if isinstance(cdefbodynode.value, astroid.Call): + if cdefbodynode.value.func.as_string() not in ATTRIB_NAMES: + continue + else: + continue + targets = ( + cdefbodynode.targets + if hasattr(cdefbodynode, "targets") + else [cdefbodynode.target] + ) + for target in targets: + + rhs_node = astroid.Unknown( + lineno=cdefbodynode.lineno, + col_offset=cdefbodynode.col_offset, + parent=cdefbodynode, + ) + node.locals[target.name] = [rhs_node] + node.instance_attrs[target.name] = [rhs_node] + + +MANAGER.register_transform( + astroid.ClassDef, attr_attributes_transform, is_decorated_with_attrs +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_builtin_inference.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_builtin_inference.py new file mode 100644 index 0000000..2dd7cc5 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_builtin_inference.py @@ -0,0 +1,829 @@ +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014-2015 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Rene Zhang +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for various builtins.""" + +from functools import partial +from textwrap import dedent + +import six +from astroid import ( + MANAGER, + UseInferenceDefault, + AttributeInferenceError, + inference_tip, + InferenceError, + NameInferenceError, + AstroidTypeError, + MroError, +) +from astroid import arguments +from astroid.builder import AstroidBuilder +from astroid import helpers +from astroid import nodes +from astroid import objects +from astroid import scoped_nodes +from astroid import util + + +OBJECT_DUNDER_NEW = "object.__new__" + + +def _extend_str(class_node, rvalue): + """function to extend builtin str/unicode class""" + code = dedent( + """ + class whatever(object): + def join(self, iterable): + return {rvalue} + def replace(self, old, new, count=None): + return {rvalue} + def format(self, *args, **kwargs): + return {rvalue} + def encode(self, encoding='ascii', errors=None): + return '' + def decode(self, encoding='ascii', errors=None): + return u'' + def capitalize(self): + return {rvalue} + def title(self): + return {rvalue} + def lower(self): + return {rvalue} + def upper(self): + return {rvalue} + def swapcase(self): + return {rvalue} + def index(self, sub, start=None, end=None): + return 0 + def find(self, sub, start=None, end=None): + return 0 + def count(self, sub, start=None, end=None): + return 0 + def strip(self, chars=None): + return {rvalue} + def lstrip(self, chars=None): + return {rvalue} + def rstrip(self, chars=None): + return {rvalue} + def rjust(self, width, fillchar=None): + return {rvalue} + def center(self, width, fillchar=None): + return {rvalue} + def ljust(self, width, fillchar=None): + return {rvalue} + """ + ) + code = code.format(rvalue=rvalue) + fake = AstroidBuilder(MANAGER).string_build(code)["whatever"] + for method in fake.mymethods(): + method.parent = class_node + method.lineno = None + method.col_offset = None + if "__class__" in method.locals: + method.locals["__class__"] = [class_node] + class_node.locals[method.name] = [method] + method.parent = class_node + + +def _extend_builtins(class_transforms): + builtin_ast = MANAGER.builtins_module + for class_name, transform in class_transforms.items(): + transform(builtin_ast[class_name]) + + +_extend_builtins( + { + "bytes": partial(_extend_str, rvalue="b''"), + "str": partial(_extend_str, rvalue="''"), + } +) + + +def _builtin_filter_predicate(node, builtin_name): + if isinstance(node.func, nodes.Name) and node.func.name == builtin_name: + return True + if isinstance(node.func, nodes.Attribute): + return ( + node.func.attrname == "fromkeys" + and isinstance(node.func.expr, nodes.Name) + and node.func.expr.name == "dict" + ) + return False + + +def register_builtin_transform(transform, builtin_name): + """Register a new transform function for the given *builtin_name*. + + The transform function must accept two parameters, a node and + an optional context. + """ + + def _transform_wrapper(node, context=None): + result = transform(node, context=context) + if result: + if not result.parent: + # Let the transformation function determine + # the parent for its result. Otherwise, + # we set it to be the node we transformed from. + result.parent = node + + if result.lineno is None: + result.lineno = node.lineno + if result.col_offset is None: + result.col_offset = node.col_offset + return iter([result]) + + MANAGER.register_transform( + nodes.Call, + inference_tip(_transform_wrapper), + partial(_builtin_filter_predicate, builtin_name=builtin_name), + ) + + +def _container_generic_inference(node, context, node_type, transform): + args = node.args + if not args: + return node_type() + if len(node.args) > 1: + raise UseInferenceDefault() + + arg, = args + transformed = transform(arg) + if not transformed: + try: + inferred = next(arg.infer(context=context)) + except (InferenceError, StopIteration): + raise UseInferenceDefault() + if inferred is util.Uninferable: + raise UseInferenceDefault() + transformed = transform(inferred) + if not transformed or transformed is util.Uninferable: + raise UseInferenceDefault() + return transformed + + +def _container_generic_transform(arg, klass, iterables, build_elts): + if isinstance(arg, klass): + return arg + elif isinstance(arg, iterables): + if all(isinstance(elt, nodes.Const) for elt in arg.elts): + elts = [elt.value for elt in arg.elts] + else: + # TODO: Does not handle deduplication for sets. + elts = filter(None, map(helpers.safe_infer, arg.elts)) + elif isinstance(arg, nodes.Dict): + # Dicts need to have consts as strings already. + if not all(isinstance(elt[0], nodes.Const) for elt in arg.items): + raise UseInferenceDefault() + elts = [item[0].value for item in arg.items] + elif isinstance(arg, nodes.Const) and isinstance( + arg.value, (six.string_types, six.binary_type) + ): + elts = arg.value + else: + return + return klass.from_elements(elts=build_elts(elts)) + + +def _infer_builtin_container( + node, context, klass=None, iterables=None, build_elts=None +): + transform_func = partial( + _container_generic_transform, + klass=klass, + iterables=iterables, + build_elts=build_elts, + ) + + return _container_generic_inference(node, context, klass, transform_func) + + +# pylint: disable=invalid-name +infer_tuple = partial( + _infer_builtin_container, + klass=nodes.Tuple, + iterables=( + nodes.List, + nodes.Set, + objects.FrozenSet, + objects.DictItems, + objects.DictKeys, + objects.DictValues, + ), + build_elts=tuple, +) + +infer_list = partial( + _infer_builtin_container, + klass=nodes.List, + iterables=( + nodes.Tuple, + nodes.Set, + objects.FrozenSet, + objects.DictItems, + objects.DictKeys, + objects.DictValues, + ), + build_elts=list, +) + +infer_set = partial( + _infer_builtin_container, + klass=nodes.Set, + iterables=(nodes.List, nodes.Tuple, objects.FrozenSet, objects.DictKeys), + build_elts=set, +) + +infer_frozenset = partial( + _infer_builtin_container, + klass=objects.FrozenSet, + iterables=(nodes.List, nodes.Tuple, nodes.Set, objects.FrozenSet, objects.DictKeys), + build_elts=frozenset, +) + + +def _get_elts(arg, context): + is_iterable = lambda n: isinstance(n, (nodes.List, nodes.Tuple, nodes.Set)) + try: + inferred = next(arg.infer(context)) + except (InferenceError, NameInferenceError): + raise UseInferenceDefault() + if isinstance(inferred, nodes.Dict): + items = inferred.items + elif is_iterable(inferred): + items = [] + for elt in inferred.elts: + # If an item is not a pair of two items, + # then fallback to the default inference. + # Also, take in consideration only hashable items, + # tuples and consts. We are choosing Names as well. + if not is_iterable(elt): + raise UseInferenceDefault() + if len(elt.elts) != 2: + raise UseInferenceDefault() + if not isinstance(elt.elts[0], (nodes.Tuple, nodes.Const, nodes.Name)): + raise UseInferenceDefault() + items.append(tuple(elt.elts)) + else: + raise UseInferenceDefault() + return items + + +def infer_dict(node, context=None): + """Try to infer a dict call to a Dict node. + + The function treats the following cases: + + * dict() + * dict(mapping) + * dict(iterable) + * dict(iterable, **kwargs) + * dict(mapping, **kwargs) + * dict(**kwargs) + + If a case can't be inferred, we'll fallback to default inference. + """ + call = arguments.CallSite.from_call(node) + if call.has_invalid_arguments() or call.has_invalid_keywords(): + raise UseInferenceDefault + + args = call.positional_arguments + kwargs = list(call.keyword_arguments.items()) + + if not args and not kwargs: + # dict() + return nodes.Dict() + elif kwargs and not args: + # dict(a=1, b=2, c=4) + items = [(nodes.Const(key), value) for key, value in kwargs] + elif len(args) == 1 and kwargs: + # dict(some_iterable, b=2, c=4) + elts = _get_elts(args[0], context) + keys = [(nodes.Const(key), value) for key, value in kwargs] + items = elts + keys + elif len(args) == 1: + items = _get_elts(args[0], context) + else: + raise UseInferenceDefault() + + value = nodes.Dict( + col_offset=node.col_offset, lineno=node.lineno, parent=node.parent + ) + value.postinit(items) + return value + + +def infer_super(node, context=None): + """Understand super calls. + + There are some restrictions for what can be understood: + + * unbounded super (one argument form) is not understood. + + * if the super call is not inside a function (classmethod or method), + then the default inference will be used. + + * if the super arguments can't be inferred, the default inference + will be used. + """ + if len(node.args) == 1: + # Ignore unbounded super. + raise UseInferenceDefault + + scope = node.scope() + if not isinstance(scope, nodes.FunctionDef): + # Ignore non-method uses of super. + raise UseInferenceDefault + if scope.type not in ("classmethod", "method"): + # Not interested in staticmethods. + raise UseInferenceDefault + + cls = scoped_nodes.get_wrapping_class(scope) + if not len(node.args): + mro_pointer = cls + # In we are in a classmethod, the interpreter will fill + # automatically the class as the second argument, not an instance. + if scope.type == "classmethod": + mro_type = cls + else: + mro_type = cls.instantiate_class() + else: + try: + mro_pointer = next(node.args[0].infer(context=context)) + except InferenceError: + raise UseInferenceDefault + try: + mro_type = next(node.args[1].infer(context=context)) + except InferenceError: + raise UseInferenceDefault + + if mro_pointer is util.Uninferable or mro_type is util.Uninferable: + # No way we could understand this. + raise UseInferenceDefault + + super_obj = objects.Super( + mro_pointer=mro_pointer, mro_type=mro_type, self_class=cls, scope=scope + ) + super_obj.parent = node + return super_obj + + +def _infer_getattr_args(node, context): + if len(node.args) not in (2, 3): + # Not a valid getattr call. + raise UseInferenceDefault + + try: + obj = next(node.args[0].infer(context=context)) + attr = next(node.args[1].infer(context=context)) + except InferenceError: + raise UseInferenceDefault + + if obj is util.Uninferable or attr is util.Uninferable: + # If one of the arguments is something we can't infer, + # then also make the result of the getattr call something + # which is unknown. + return util.Uninferable, util.Uninferable + + is_string = isinstance(attr, nodes.Const) and isinstance( + attr.value, six.string_types + ) + if not is_string: + raise UseInferenceDefault + + return obj, attr.value + + +def infer_getattr(node, context=None): + """Understand getattr calls + + If one of the arguments is an Uninferable object, then the + result will be an Uninferable object. Otherwise, the normal attribute + lookup will be done. + """ + obj, attr = _infer_getattr_args(node, context) + if ( + obj is util.Uninferable + or attr is util.Uninferable + or not hasattr(obj, "igetattr") + ): + return util.Uninferable + + try: + return next(obj.igetattr(attr, context=context)) + except (StopIteration, InferenceError, AttributeInferenceError): + if len(node.args) == 3: + # Try to infer the default and return it instead. + try: + return next(node.args[2].infer(context=context)) + except InferenceError: + raise UseInferenceDefault + + raise UseInferenceDefault + + +def infer_hasattr(node, context=None): + """Understand hasattr calls + + This always guarantees three possible outcomes for calling + hasattr: Const(False) when we are sure that the object + doesn't have the intended attribute, Const(True) when + we know that the object has the attribute and Uninferable + when we are unsure of the outcome of the function call. + """ + try: + obj, attr = _infer_getattr_args(node, context) + if ( + obj is util.Uninferable + or attr is util.Uninferable + or not hasattr(obj, "getattr") + ): + return util.Uninferable + obj.getattr(attr, context=context) + except UseInferenceDefault: + # Can't infer something from this function call. + return util.Uninferable + except AttributeInferenceError: + # Doesn't have it. + return nodes.Const(False) + return nodes.Const(True) + + +def infer_callable(node, context=None): + """Understand callable calls + + This follows Python's semantics, where an object + is callable if it provides an attribute __call__, + even though that attribute is something which can't be + called. + """ + if len(node.args) != 1: + # Invalid callable call. + raise UseInferenceDefault + + argument = node.args[0] + try: + inferred = next(argument.infer(context=context)) + except InferenceError: + return util.Uninferable + if inferred is util.Uninferable: + return util.Uninferable + return nodes.Const(inferred.callable()) + + +def infer_bool(node, context=None): + """Understand bool calls.""" + if len(node.args) > 1: + # Invalid bool call. + raise UseInferenceDefault + + if not node.args: + return nodes.Const(False) + + argument = node.args[0] + try: + inferred = next(argument.infer(context=context)) + except InferenceError: + return util.Uninferable + if inferred is util.Uninferable: + return util.Uninferable + + bool_value = inferred.bool_value() + if bool_value is util.Uninferable: + return util.Uninferable + return nodes.Const(bool_value) + + +def infer_type(node, context=None): + """Understand the one-argument form of *type*.""" + if len(node.args) != 1: + raise UseInferenceDefault + + return helpers.object_type(node.args[0], context) + + +def infer_slice(node, context=None): + """Understand `slice` calls.""" + args = node.args + if not 0 < len(args) <= 3: + raise UseInferenceDefault + + infer_func = partial(helpers.safe_infer, context=context) + args = [infer_func(arg) for arg in args] + for arg in args: + if not arg or arg is util.Uninferable: + raise UseInferenceDefault + if not isinstance(arg, nodes.Const): + raise UseInferenceDefault + if not isinstance(arg.value, (type(None), int)): + raise UseInferenceDefault + + if len(args) < 3: + # Make sure we have 3 arguments. + args.extend([None] * (3 - len(args))) + + slice_node = nodes.Slice( + lineno=node.lineno, col_offset=node.col_offset, parent=node.parent + ) + slice_node.postinit(*args) + return slice_node + + +def _infer_object__new__decorator(node, context=None): + # Instantiate class immediately + # since that's what @object.__new__ does + return iter((node.instantiate_class(),)) + + +def _infer_object__new__decorator_check(node): + """Predicate before inference_tip + + Check if the given ClassDef has an @object.__new__ decorator + """ + if not node.decorators: + return False + + for decorator in node.decorators.nodes: + if isinstance(decorator, nodes.Attribute): + if decorator.as_string() == OBJECT_DUNDER_NEW: + return True + return False + + +def infer_issubclass(callnode, context=None): + """Infer issubclass() calls + + :param nodes.Call callnode: an `issubclass` call + :param InferenceContext: the context for the inference + :rtype nodes.Const: Boolean Const value of the `issubclass` call + :raises UseInferenceDefault: If the node cannot be inferred + """ + call = arguments.CallSite.from_call(callnode) + if call.keyword_arguments: + # issubclass doesn't support keyword arguments + raise UseInferenceDefault("TypeError: issubclass() takes no keyword arguments") + if len(call.positional_arguments) != 2: + raise UseInferenceDefault( + "Expected two arguments, got {count}".format( + count=len(call.positional_arguments) + ) + ) + # The left hand argument is the obj to be checked + obj_node, class_or_tuple_node = call.positional_arguments + + try: + obj_type = next(obj_node.infer(context=context)) + except InferenceError as exc: + raise UseInferenceDefault from exc + if not isinstance(obj_type, nodes.ClassDef): + raise UseInferenceDefault("TypeError: arg 1 must be class") + + # The right hand argument is the class(es) that the given + # object is to be checked against. + try: + class_container = _class_or_tuple_to_container( + class_or_tuple_node, context=context + ) + except InferenceError as exc: + raise UseInferenceDefault from exc + try: + issubclass_bool = helpers.object_issubclass(obj_type, class_container, context) + except AstroidTypeError as exc: + raise UseInferenceDefault("TypeError: " + str(exc)) from exc + except MroError as exc: + raise UseInferenceDefault from exc + return nodes.Const(issubclass_bool) + + +def infer_isinstance(callnode, context=None): + """Infer isinstance calls + + :param nodes.Call callnode: an isinstance call + :param InferenceContext: context for call + (currently unused but is a common interface for inference) + :rtype nodes.Const: Boolean Const value of isinstance call + + :raises UseInferenceDefault: If the node cannot be inferred + """ + call = arguments.CallSite.from_call(callnode) + if call.keyword_arguments: + # isinstance doesn't support keyword arguments + raise UseInferenceDefault("TypeError: isinstance() takes no keyword arguments") + if len(call.positional_arguments) != 2: + raise UseInferenceDefault( + "Expected two arguments, got {count}".format( + count=len(call.positional_arguments) + ) + ) + # The left hand argument is the obj to be checked + obj_node, class_or_tuple_node = call.positional_arguments + # The right hand argument is the class(es) that the given + # obj is to be check is an instance of + try: + class_container = _class_or_tuple_to_container( + class_or_tuple_node, context=context + ) + except InferenceError: + raise UseInferenceDefault + try: + isinstance_bool = helpers.object_isinstance(obj_node, class_container, context) + except AstroidTypeError as exc: + raise UseInferenceDefault("TypeError: " + str(exc)) + except MroError as exc: + raise UseInferenceDefault from exc + if isinstance_bool is util.Uninferable: + raise UseInferenceDefault + return nodes.Const(isinstance_bool) + + +def _class_or_tuple_to_container(node, context=None): + # Move inferences results into container + # to simplify later logic + # raises InferenceError if any of the inferences fall through + node_infer = next(node.infer(context=context)) + # arg2 MUST be a type or a TUPLE of types + # for isinstance + if isinstance(node_infer, nodes.Tuple): + class_container = [ + next(node.infer(context=context)) for node in node_infer.elts + ] + class_container = [ + klass_node for klass_node in class_container if klass_node is not None + ] + else: + class_container = [node_infer] + return class_container + + +def infer_len(node, context=None): + """Infer length calls + + :param nodes.Call node: len call to infer + :param context.InferenceContext: node context + :rtype nodes.Const: a Const node with the inferred length, if possible + """ + call = arguments.CallSite.from_call(node) + if call.keyword_arguments: + raise UseInferenceDefault("TypeError: len() must take no keyword arguments") + if len(call.positional_arguments) != 1: + raise UseInferenceDefault( + "TypeError: len() must take exactly one argument " + "({len}) given".format(len=len(call.positional_arguments)) + ) + [argument_node] = call.positional_arguments + try: + return nodes.Const(helpers.object_len(argument_node, context=context)) + except (AstroidTypeError, InferenceError) as exc: + raise UseInferenceDefault(str(exc)) from exc + + +def infer_str(node, context=None): + """Infer str() calls + + :param nodes.Call node: str() call to infer + :param context.InferenceContext: node context + :rtype nodes.Const: a Const containing an empty string + """ + call = arguments.CallSite.from_call(node) + if call.keyword_arguments: + raise UseInferenceDefault("TypeError: str() must take no keyword arguments") + try: + return nodes.Const("") + except (AstroidTypeError, InferenceError) as exc: + raise UseInferenceDefault(str(exc)) from exc + + +def infer_int(node, context=None): + """Infer int() calls + + :param nodes.Call node: int() call to infer + :param context.InferenceContext: node context + :rtype nodes.Const: a Const containing the integer value of the int() call + """ + call = arguments.CallSite.from_call(node) + if call.keyword_arguments: + raise UseInferenceDefault("TypeError: int() must take no keyword arguments") + + if call.positional_arguments: + try: + first_value = next(call.positional_arguments[0].infer(context=context)) + except InferenceError as exc: + raise UseInferenceDefault(str(exc)) from exc + + if first_value is util.Uninferable: + raise UseInferenceDefault + + if isinstance(first_value, nodes.Const) and isinstance( + first_value.value, (int, str) + ): + try: + actual_value = int(first_value.value) + except ValueError: + return nodes.Const(0) + return nodes.Const(actual_value) + + return nodes.Const(0) + + +def infer_dict_fromkeys(node, context=None): + """Infer dict.fromkeys + + :param nodes.Call node: dict.fromkeys() call to infer + :param context.InferenceContext: node context + :rtype nodes.Dict: + a Dictionary containing the values that astroid was able to infer. + In case the inference failed for any reason, an empty dictionary + will be inferred instead. + """ + + def _build_dict_with_elements(elements): + new_node = nodes.Dict( + col_offset=node.col_offset, lineno=node.lineno, parent=node.parent + ) + new_node.postinit(elements) + return new_node + + call = arguments.CallSite.from_call(node) + if call.keyword_arguments: + raise UseInferenceDefault("TypeError: int() must take no keyword arguments") + if len(call.positional_arguments) not in {1, 2}: + raise UseInferenceDefault( + "TypeError: Needs between 1 and 2 positional arguments" + ) + + default = nodes.Const(None) + values = call.positional_arguments[0] + try: + inferred_values = next(values.infer(context=context)) + except InferenceError: + return _build_dict_with_elements([]) + if inferred_values is util.Uninferable: + return _build_dict_with_elements([]) + + # Limit to a couple of potential values, as this can become pretty complicated + accepted_iterable_elements = (nodes.Const,) + if isinstance(inferred_values, (nodes.List, nodes.Set, nodes.Tuple)): + elements = inferred_values.elts + for element in elements: + if not isinstance(element, accepted_iterable_elements): + # Fallback to an empty dict + return _build_dict_with_elements([]) + + elements_with_value = [(element, default) for element in elements] + return _build_dict_with_elements(elements_with_value) + + elif isinstance(inferred_values, nodes.Const) and isinstance( + inferred_values.value, (str, bytes) + ): + elements = [ + (nodes.Const(element), default) for element in inferred_values.value + ] + return _build_dict_with_elements(elements) + elif isinstance(inferred_values, nodes.Dict): + keys = inferred_values.itered() + for key in keys: + if not isinstance(key, accepted_iterable_elements): + # Fallback to an empty dict + return _build_dict_with_elements([]) + + elements_with_value = [(element, default) for element in keys] + return _build_dict_with_elements(elements_with_value) + + # Fallback to an empty dictionary + return _build_dict_with_elements([]) + + +# Builtins inference +register_builtin_transform(infer_bool, "bool") +register_builtin_transform(infer_super, "super") +register_builtin_transform(infer_callable, "callable") +register_builtin_transform(infer_getattr, "getattr") +register_builtin_transform(infer_hasattr, "hasattr") +register_builtin_transform(infer_tuple, "tuple") +register_builtin_transform(infer_set, "set") +register_builtin_transform(infer_list, "list") +register_builtin_transform(infer_dict, "dict") +register_builtin_transform(infer_frozenset, "frozenset") +register_builtin_transform(infer_type, "type") +register_builtin_transform(infer_slice, "slice") +register_builtin_transform(infer_isinstance, "isinstance") +register_builtin_transform(infer_issubclass, "issubclass") +register_builtin_transform(infer_len, "len") +register_builtin_transform(infer_str, "str") +register_builtin_transform(infer_int, "int") +register_builtin_transform(infer_dict_fromkeys, "dict.fromkeys") + + +# Infer object.__new__ calls +MANAGER.register_transform( + nodes.ClassDef, + inference_tip(_infer_object__new__decorator), + _infer_object__new__decorator_check, +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_collections.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_collections.py new file mode 100644 index 0000000..e5b09ec --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_collections.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016, 2018 Claudiu Popa +# Copyright (c) 2016-2017 Łukasz Rogalski +# Copyright (c) 2017 Derek Gustafson +# Copyright (c) 2018 Ioana Tagirta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import sys + +import astroid + + +def _collections_transform(): + return astroid.parse( + """ + class defaultdict(dict): + default_factory = None + def __missing__(self, key): pass + def __getitem__(self, key): return default_factory + + """ + + _deque_mock() + + _ordered_dict_mock() + ) + + +def _deque_mock(): + base_deque_class = """ + class deque(object): + maxlen = 0 + def __init__(self, iterable=None, maxlen=None): + self.iterable = iterable or [] + def append(self, x): pass + def appendleft(self, x): pass + def clear(self): pass + def count(self, x): return 0 + def extend(self, iterable): pass + def extendleft(self, iterable): pass + def pop(self): return self.iterable[0] + def popleft(self): return self.iterable[0] + def remove(self, value): pass + def reverse(self): return reversed(self.iterable) + def rotate(self, n=1): return self + def __iter__(self): return self + def __reversed__(self): return self.iterable[::-1] + def __getitem__(self, index): return self.iterable[index] + def __setitem__(self, index, value): pass + def __delitem__(self, index): pass + def __bool__(self): return bool(self.iterable) + def __nonzero__(self): return bool(self.iterable) + def __contains__(self, o): return o in self.iterable + def __len__(self): return len(self.iterable) + def __copy__(self): return deque(self.iterable) + def copy(self): return deque(self.iterable) + def index(self, x, start=0, end=0): return 0 + def insert(self, x, i): pass + def __add__(self, other): pass + def __iadd__(self, other): pass + def __mul__(self, other): pass + def __imul__(self, other): pass + def __rmul__(self, other): pass""" + return base_deque_class + + +def _ordered_dict_mock(): + base_ordered_dict_class = """ + class OrderedDict(dict): + def __reversed__(self): return self[::-1] + def move_to_end(self, key, last=False): pass""" + return base_ordered_dict_class + + +astroid.register_module_extender(astroid.MANAGER, "collections", _collections_transform) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_crypt.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_crypt.py new file mode 100644 index 0000000..491ee23 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_crypt.py @@ -0,0 +1,26 @@ +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import sys +import astroid + +PY37 = sys.version_info >= (3, 7) + +if PY37: + # Since Python 3.7 Hashing Methods are added + # dynamically to globals() + + def _re_transform(): + return astroid.parse( + """ + from collections import namedtuple + _Method = namedtuple('_Method', 'name ident salt_chars total_size') + + METHOD_SHA512 = _Method('SHA512', '6', 16, 106) + METHOD_SHA256 = _Method('SHA256', '5', 16, 63) + METHOD_BLOWFISH = _Method('BLOWFISH', 2, 'b', 22) + METHOD_MD5 = _Method('MD5', '1', 8, 34) + METHOD_CRYPT = _Method('CRYPT', None, 2, 13) + """ + ) + + astroid.register_module_extender(astroid.MANAGER, "crypt", _re_transform) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_curses.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_curses.py new file mode 100644 index 0000000..68e88b9 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_curses.py @@ -0,0 +1,179 @@ +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import astroid + + +def _curses_transform(): + return astroid.parse( + """ + A_ALTCHARSET = 1 + A_BLINK = 1 + A_BOLD = 1 + A_DIM = 1 + A_INVIS = 1 + A_ITALIC = 1 + A_NORMAL = 1 + A_PROTECT = 1 + A_REVERSE = 1 + A_STANDOUT = 1 + A_UNDERLINE = 1 + A_HORIZONTAL = 1 + A_LEFT = 1 + A_LOW = 1 + A_RIGHT = 1 + A_TOP = 1 + A_VERTICAL = 1 + A_CHARTEXT = 1 + A_ATTRIBUTES = 1 + A_CHARTEXT = 1 + A_COLOR = 1 + KEY_MIN = 1 + KEY_BREAK = 1 + KEY_DOWN = 1 + KEY_UP = 1 + KEY_LEFT = 1 + KEY_RIGHT = 1 + KEY_HOME = 1 + KEY_BACKSPACE = 1 + KEY_F0 = 1 + KEY_Fn = 1 + KEY_DL = 1 + KEY_IL = 1 + KEY_DC = 1 + KEY_IC = 1 + KEY_EIC = 1 + KEY_CLEAR = 1 + KEY_EOS = 1 + KEY_EOL = 1 + KEY_SF = 1 + KEY_SR = 1 + KEY_NPAGE = 1 + KEY_PPAGE = 1 + KEY_STAB = 1 + KEY_CTAB = 1 + KEY_CATAB = 1 + KEY_ENTER = 1 + KEY_SRESET = 1 + KEY_RESET = 1 + KEY_PRINT = 1 + KEY_LL = 1 + KEY_A1 = 1 + KEY_A3 = 1 + KEY_B2 = 1 + KEY_C1 = 1 + KEY_C3 = 1 + KEY_BTAB = 1 + KEY_BEG = 1 + KEY_CANCEL = 1 + KEY_CLOSE = 1 + KEY_COMMAND = 1 + KEY_COPY = 1 + KEY_CREATE = 1 + KEY_END = 1 + KEY_EXIT = 1 + KEY_FIND = 1 + KEY_HELP = 1 + KEY_MARK = 1 + KEY_MESSAGE = 1 + KEY_MOVE = 1 + KEY_NEXT = 1 + KEY_OPEN = 1 + KEY_OPTIONS = 1 + KEY_PREVIOUS = 1 + KEY_REDO = 1 + KEY_REFERENCE = 1 + KEY_REFRESH = 1 + KEY_REPLACE = 1 + KEY_RESTART = 1 + KEY_RESUME = 1 + KEY_SAVE = 1 + KEY_SBEG = 1 + KEY_SCANCEL = 1 + KEY_SCOMMAND = 1 + KEY_SCOPY = 1 + KEY_SCREATE = 1 + KEY_SDC = 1 + KEY_SDL = 1 + KEY_SELECT = 1 + KEY_SEND = 1 + KEY_SEOL = 1 + KEY_SEXIT = 1 + KEY_SFIND = 1 + KEY_SHELP = 1 + KEY_SHOME = 1 + KEY_SIC = 1 + KEY_SLEFT = 1 + KEY_SMESSAGE = 1 + KEY_SMOVE = 1 + KEY_SNEXT = 1 + KEY_SOPTIONS = 1 + KEY_SPREVIOUS = 1 + KEY_SPRINT = 1 + KEY_SREDO = 1 + KEY_SREPLACE = 1 + KEY_SRIGHT = 1 + KEY_SRSUME = 1 + KEY_SSAVE = 1 + KEY_SSUSPEND = 1 + KEY_SUNDO = 1 + KEY_SUSPEND = 1 + KEY_UNDO = 1 + KEY_MOUSE = 1 + KEY_RESIZE = 1 + KEY_MAX = 1 + ACS_BBSS = 1 + ACS_BLOCK = 1 + ACS_BOARD = 1 + ACS_BSBS = 1 + ACS_BSSB = 1 + ACS_BSSS = 1 + ACS_BTEE = 1 + ACS_BULLET = 1 + ACS_CKBOARD = 1 + ACS_DARROW = 1 + ACS_DEGREE = 1 + ACS_DIAMOND = 1 + ACS_GEQUAL = 1 + ACS_HLINE = 1 + ACS_LANTERN = 1 + ACS_LARROW = 1 + ACS_LEQUAL = 1 + ACS_LLCORNER = 1 + ACS_LRCORNER = 1 + ACS_LTEE = 1 + ACS_NEQUAL = 1 + ACS_PI = 1 + ACS_PLMINUS = 1 + ACS_PLUS = 1 + ACS_RARROW = 1 + ACS_RTEE = 1 + ACS_S1 = 1 + ACS_S3 = 1 + ACS_S7 = 1 + ACS_S9 = 1 + ACS_SBBS = 1 + ACS_SBSB = 1 + ACS_SBSS = 1 + ACS_SSBB = 1 + ACS_SSBS = 1 + ACS_SSSB = 1 + ACS_SSSS = 1 + ACS_STERLING = 1 + ACS_TTEE = 1 + ACS_UARROW = 1 + ACS_ULCORNER = 1 + ACS_URCORNER = 1 + ACS_VLINE = 1 + COLOR_BLACK = 1 + COLOR_BLUE = 1 + COLOR_CYAN = 1 + COLOR_GREEN = 1 + COLOR_MAGENTA = 1 + COLOR_RED = 1 + COLOR_WHITE = 1 + COLOR_YELLOW = 1 + """ + ) + + +astroid.register_module_extender(astroid.MANAGER, "curses", _curses_transform) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_dataclasses.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_dataclasses.py new file mode 100644 index 0000000..7a25e0c --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_dataclasses.py @@ -0,0 +1,50 @@ +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +""" +Astroid hook for the dataclasses library +""" + +import astroid +from astroid import MANAGER + + +DATACLASSES_DECORATORS = frozenset(("dataclasses.dataclass", "dataclass")) + + +def is_decorated_with_dataclass(node, decorator_names=DATACLASSES_DECORATORS): + """Return True if a decorated node has a `dataclass` decorator applied.""" + if not node.decorators: + return False + for decorator_attribute in node.decorators.nodes: + if isinstance(decorator_attribute, astroid.Call): # decorator with arguments + decorator_attribute = decorator_attribute.func + if decorator_attribute.as_string() in decorator_names: + return True + return False + + +def dataclass_transform(node): + """Rewrite a dataclass to be easily understood by pylint""" + + for assign_node in node.body: + if not isinstance(assign_node, (astroid.AnnAssign, astroid.Assign)): + continue + + targets = ( + assign_node.targets + if hasattr(assign_node, "targets") + else [assign_node.target] + ) + for target in targets: + rhs_node = astroid.Unknown( + lineno=assign_node.lineno, + col_offset=assign_node.col_offset, + parent=assign_node, + ) + node.instance_attrs[target.name] = [rhs_node] + node.locals[target.name] = [rhs_node] + + +MANAGER.register_transform( + astroid.ClassDef, dataclass_transform, is_decorated_with_dataclass +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_dateutil.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_dateutil.py new file mode 100644 index 0000000..a1c270f --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_dateutil.py @@ -0,0 +1,28 @@ +# Copyright (c) 2015-2016 Claudiu Popa +# Copyright (c) 2015 raylu +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for dateutil""" + +import textwrap + +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder + + +def dateutil_transform(): + return AstroidBuilder(MANAGER).string_build( + textwrap.dedent( + """ + import datetime + def parse(timestr, parserinfo=None, **kwargs): + return datetime.datetime() + """ + ) + ) + + +register_module_extender(MANAGER, "dateutil.parser", dateutil_transform) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_fstrings.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_fstrings.py new file mode 100644 index 0000000..7d8c7b6 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_fstrings.py @@ -0,0 +1,51 @@ +# Copyright (c) 2017 Claudiu Popa + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import collections +import sys + +import astroid + + +def _clone_node_with_lineno(node, parent, lineno): + cls = node.__class__ + other_fields = node._other_fields + _astroid_fields = node._astroid_fields + init_params = {"lineno": lineno, "col_offset": node.col_offset, "parent": parent} + postinit_params = {param: getattr(node, param) for param in _astroid_fields} + if other_fields: + init_params.update({param: getattr(node, param) for param in other_fields}) + new_node = cls(**init_params) + if hasattr(node, "postinit") and _astroid_fields: + for param, child in postinit_params.items(): + if child and not isinstance(child, collections.Sequence): + cloned_child = _clone_node_with_lineno( + node=child, lineno=new_node.lineno, parent=new_node + ) + postinit_params[param] = cloned_child + new_node.postinit(**postinit_params) + return new_node + + +def _transform_formatted_value(node): + if node.value and node.value.lineno == 1: + if node.lineno != node.value.lineno: + new_node = astroid.FormattedValue( + lineno=node.lineno, col_offset=node.col_offset, parent=node.parent + ) + new_value = _clone_node_with_lineno( + node=node.value, lineno=node.lineno, parent=new_node + ) + new_node.postinit(value=new_value, format_spec=node.format_spec) + return new_node + + +if sys.version_info[:2] >= (3, 6): + # TODO: this fix tries to *patch* http://bugs.python.org/issue29051 + # The problem is that FormattedValue.value, which is a Name node, + # has wrong line numbers, usually 1. This creates problems for pylint, + # which expects correct line numbers for things such as message control. + astroid.MANAGER.register_transform( + astroid.FormattedValue, _transform_formatted_value + ) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_functools.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_functools.py new file mode 100644 index 0000000..8b594ef --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_functools.py @@ -0,0 +1,158 @@ +# Copyright (c) 2016, 2018 Claudiu Popa +# Copyright (c) 2018 Bryce Guinta + +"""Astroid hooks for understanding functools library module.""" +from functools import partial +from itertools import chain + +import astroid +from astroid import arguments +from astroid import BoundMethod +from astroid import extract_node +from astroid import helpers +from astroid.interpreter import objectmodel +from astroid import MANAGER +from astroid import objects + + +LRU_CACHE = "functools.lru_cache" + + +class LruWrappedModel(objectmodel.FunctionModel): + """Special attribute model for functions decorated with functools.lru_cache. + + The said decorators patches at decoration time some functions onto + the decorated function. + """ + + @property + def attr___wrapped__(self): + return self._instance + + @property + def attr_cache_info(self): + cache_info = extract_node( + """ + from functools import _CacheInfo + _CacheInfo(0, 0, 0, 0) + """ + ) + + class CacheInfoBoundMethod(BoundMethod): + def infer_call_result(self, caller, context=None): + yield helpers.safe_infer(cache_info) + + return CacheInfoBoundMethod(proxy=self._instance, bound=self._instance) + + @property + def attr_cache_clear(self): + node = extract_node("""def cache_clear(self): pass""") + return BoundMethod(proxy=node, bound=self._instance.parent.scope()) + + +def _transform_lru_cache(node, context=None): + # TODO: this is not ideal, since the node should be immutable, + # but due to https://github.com/PyCQA/astroid/issues/354, + # there's not much we can do now. + # Replacing the node would work partially, because, + # in pylint, the old node would still be available, leading + # to spurious false positives. + node.special_attributes = LruWrappedModel()(node) + return + + +def _functools_partial_inference(node, context=None): + call = arguments.CallSite.from_call(node) + number_of_positional = len(call.positional_arguments) + if number_of_positional < 1: + raise astroid.UseInferenceDefault( + "functools.partial takes at least one argument" + ) + if number_of_positional == 1 and not call.keyword_arguments: + raise astroid.UseInferenceDefault( + "functools.partial needs at least to have some filled arguments" + ) + + partial_function = call.positional_arguments[0] + try: + inferred_wrapped_function = next(partial_function.infer(context=context)) + except astroid.InferenceError as exc: + raise astroid.UseInferenceDefault from exc + if inferred_wrapped_function is astroid.Uninferable: + raise astroid.UseInferenceDefault("Cannot infer the wrapped function") + if not isinstance(inferred_wrapped_function, astroid.FunctionDef): + raise astroid.UseInferenceDefault("The wrapped function is not a function") + + # Determine if the passed keywords into the callsite are supported + # by the wrapped function. + function_parameters = chain( + inferred_wrapped_function.args.args or (), + inferred_wrapped_function.args.posonlyargs or (), + inferred_wrapped_function.args.kwonlyargs or (), + ) + parameter_names = set( + param.name + for param in function_parameters + if isinstance(param, astroid.AssignName) + ) + if set(call.keyword_arguments) - parameter_names: + raise astroid.UseInferenceDefault( + "wrapped function received unknown parameters" + ) + + partial_function = objects.PartialFunction( + call, + name=inferred_wrapped_function.name, + doc=inferred_wrapped_function.doc, + lineno=inferred_wrapped_function.lineno, + col_offset=inferred_wrapped_function.col_offset, + parent=inferred_wrapped_function.parent, + ) + partial_function.postinit( + args=inferred_wrapped_function.args, + body=inferred_wrapped_function.body, + decorators=inferred_wrapped_function.decorators, + returns=inferred_wrapped_function.returns, + type_comment_returns=inferred_wrapped_function.type_comment_returns, + type_comment_args=inferred_wrapped_function.type_comment_args, + ) + return iter((partial_function,)) + + +def _looks_like_lru_cache(node): + """Check if the given function node is decorated with lru_cache.""" + if not node.decorators: + return False + for decorator in node.decorators.nodes: + if not isinstance(decorator, astroid.Call): + continue + if _looks_like_functools_member(decorator, "lru_cache"): + return True + return False + + +def _looks_like_functools_member(node, member): + """Check if the given Call node is a functools.partial call""" + if isinstance(node.func, astroid.Name): + return node.func.name == member + elif isinstance(node.func, astroid.Attribute): + return ( + node.func.attrname == member + and isinstance(node.func.expr, astroid.Name) + and node.func.expr.name == "functools" + ) + + +_looks_like_partial = partial(_looks_like_functools_member, member="partial") + + +MANAGER.register_transform( + astroid.FunctionDef, _transform_lru_cache, _looks_like_lru_cache +) + + +MANAGER.register_transform( + astroid.Call, + astroid.inference_tip(_functools_partial_inference), + _looks_like_partial, +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_gi.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_gi.py new file mode 100644 index 0000000..0970610 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_gi.py @@ -0,0 +1,220 @@ +# Copyright (c) 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Cole Robinson +# Copyright (c) 2015-2016 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 David Shea +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2016 Giuseppe Scrivano + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for the Python 2 GObject introspection bindings. + +Helps with understanding everything imported from 'gi.repository' +""" + +import inspect +import itertools +import sys +import re +import warnings + +from astroid import MANAGER, AstroidBuildingError, nodes +from astroid.builder import AstroidBuilder + + +_inspected_modules = {} + +_identifier_re = r"^[A-Za-z_]\w*$" + + +def _gi_build_stub(parent): + """ + Inspect the passed module recursively and build stubs for functions, + classes, etc. + """ + classes = {} + functions = {} + constants = {} + methods = {} + for name in dir(parent): + if name.startswith("__"): + continue + + # Check if this is a valid name in python + if not re.match(_identifier_re, name): + continue + + try: + obj = getattr(parent, name) + except: + continue + + if inspect.isclass(obj): + classes[name] = obj + elif inspect.isfunction(obj) or inspect.isbuiltin(obj): + functions[name] = obj + elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj): + methods[name] = obj + elif ( + str(obj).startswith(", ) + # Only accept function calls with two constant arguments + if len(node.args) != 2: + return False + + if not all(isinstance(arg, nodes.Const) for arg in node.args): + return False + + func = node.func + if isinstance(func, nodes.Attribute): + if func.attrname != "require_version": + return False + if isinstance(func.expr, nodes.Name) and func.expr.name == "gi": + return True + + return False + + if isinstance(func, nodes.Name): + return func.name == "require_version" + + return False + + +def _register_require_version(node): + # Load the gi.require_version locally + try: + import gi + + gi.require_version(node.args[0].value, node.args[1].value) + except Exception: + pass + + return node + + +MANAGER.register_failed_import_hook(_import_gi_module) +MANAGER.register_transform( + nodes.Call, _register_require_version, _looks_like_require_version +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_hashlib.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_hashlib.py new file mode 100644 index 0000000..98ae774 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_hashlib.py @@ -0,0 +1,67 @@ +# Copyright (c) 2016, 2018 Claudiu Popa +# Copyright (c) 2018 Ioana Tagirta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import sys + +import six + +import astroid + +PY36 = sys.version_info >= (3, 6) + + +def _hashlib_transform(): + signature = "value=''" + template = """ + class %(name)s(object): + def __init__(self, %(signature)s): pass + def digest(self): + return %(digest)s + def copy(self): + return self + def update(self, value): pass + def hexdigest(self): + return '' + @property + def name(self): + return %(name)r + @property + def block_size(self): + return 1 + @property + def digest_size(self): + return 1 + """ + algorithms_with_signature = dict.fromkeys( + ["md5", "sha1", "sha224", "sha256", "sha384", "sha512"], signature + ) + if PY36: + blake2b_signature = "data=b'', *, digest_size=64, key=b'', salt=b'', \ + person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \ + node_depth=0, inner_size=0, last_node=False" + blake2s_signature = "data=b'', *, digest_size=32, key=b'', salt=b'', \ + person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \ + node_depth=0, inner_size=0, last_node=False" + new_algorithms = dict.fromkeys( + ["sha3_224", "sha3_256", "sha3_384", "sha3_512", "shake_128", "shake_256"], + signature, + ) + algorithms_with_signature.update(new_algorithms) + algorithms_with_signature.update( + {"blake2b": blake2b_signature, "blake2s": blake2s_signature} + ) + classes = "".join( + template + % { + "name": hashfunc, + "digest": 'b""' if six.PY3 else '""', + "signature": signature, + } + for hashfunc, signature in algorithms_with_signature.items() + ) + return astroid.parse(classes) + + +astroid.register_module_extender(astroid.MANAGER, "hashlib", _hashlib_transform) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_http.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_http.py new file mode 100644 index 0000000..a3aa814 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_http.py @@ -0,0 +1,201 @@ +# Copyright (c) 2018 Claudiu Popa + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid brain hints for some of the `http` module.""" +import textwrap + +import astroid +from astroid.builder import AstroidBuilder + + +def _http_transform(): + code = textwrap.dedent( + """ + from collections import namedtuple + _HTTPStatus = namedtuple('_HTTPStatus', 'value phrase description') + + class HTTPStatus: + + # informational + CONTINUE = _HTTPStatus(100, 'Continue', 'Request received, please continue') + SWITCHING_PROTOCOLS = _HTTPStatus(101, 'Switching Protocols', + 'Switching to new protocol; obey Upgrade header') + PROCESSING = _HTTPStatus(102, 'Processing', '') + OK = _HTTPStatus(200, 'OK', 'Request fulfilled, document follows') + CREATED = _HTTPStatus(201, 'Created', 'Document created, URL follows') + ACCEPTED = _HTTPStatus(202, 'Accepted', + 'Request accepted, processing continues off-line') + NON_AUTHORITATIVE_INFORMATION = _HTTPStatus(203, + 'Non-Authoritative Information', 'Request fulfilled from cache') + NO_CONTENT = _HTTPStatus(204, 'No Content', 'Request fulfilled, nothing follows') + RESET_CONTENT =_HTTPStatus(205, 'Reset Content', 'Clear input form for further input') + PARTIAL_CONTENT = _HTTPStatus(206, 'Partial Content', 'Partial content follows') + MULTI_STATUS = _HTTPStatus(207, 'Multi-Status', '') + ALREADY_REPORTED = _HTTPStatus(208, 'Already Reported', '') + IM_USED = _HTTPStatus(226, 'IM Used', '') + MULTIPLE_CHOICES = _HTTPStatus(300, 'Multiple Choices', + 'Object has several resources -- see URI list') + MOVED_PERMANENTLY = _HTTPStatus(301, 'Moved Permanently', + 'Object moved permanently -- see URI list') + FOUND = _HTTPStatus(302, 'Found', 'Object moved temporarily -- see URI list') + SEE_OTHER = _HTTPStatus(303, 'See Other', 'Object moved -- see Method and URL list') + NOT_MODIFIED = _HTTPStatus(304, 'Not Modified', + 'Document has not changed since given time') + USE_PROXY = _HTTPStatus(305, 'Use Proxy', + 'You must use proxy specified in Location to access this resource') + TEMPORARY_REDIRECT = _HTTPStatus(307, 'Temporary Redirect', + 'Object moved temporarily -- see URI list') + PERMANENT_REDIRECT = _HTTPStatus(308, 'Permanent Redirect', + 'Object moved permanently -- see URI list') + BAD_REQUEST = _HTTPStatus(400, 'Bad Request', + 'Bad request syntax or unsupported method') + UNAUTHORIZED = _HTTPStatus(401, 'Unauthorized', + 'No permission -- see authorization schemes') + PAYMENT_REQUIRED = _HTTPStatus(402, 'Payment Required', + 'No payment -- see charging schemes') + FORBIDDEN = _HTTPStatus(403, 'Forbidden', + 'Request forbidden -- authorization will not help') + NOT_FOUND = _HTTPStatus(404, 'Not Found', + 'Nothing matches the given URI') + METHOD_NOT_ALLOWED = _HTTPStatus(405, 'Method Not Allowed', + 'Specified method is invalid for this resource') + NOT_ACCEPTABLE = _HTTPStatus(406, 'Not Acceptable', + 'URI not available in preferred format') + PROXY_AUTHENTICATION_REQUIRED = _HTTPStatus(407, + 'Proxy Authentication Required', + 'You must authenticate with this proxy before proceeding') + REQUEST_TIMEOUT = _HTTPStatus(408, 'Request Timeout', + 'Request timed out; try again later') + CONFLICT = _HTTPStatus(409, 'Conflict', 'Request conflict') + GONE = _HTTPStatus(410, 'Gone', + 'URI no longer exists and has been permanently removed') + LENGTH_REQUIRED = _HTTPStatus(411, 'Length Required', + 'Client must specify Content-Length') + PRECONDITION_FAILED = _HTTPStatus(412, 'Precondition Failed', + 'Precondition in headers is false') + REQUEST_ENTITY_TOO_LARGE = _HTTPStatus(413, 'Request Entity Too Large', + 'Entity is too large') + REQUEST_URI_TOO_LONG = _HTTPStatus(414, 'Request-URI Too Long', + 'URI is too long') + UNSUPPORTED_MEDIA_TYPE = _HTTPStatus(415, 'Unsupported Media Type', + 'Entity body in unsupported format') + REQUESTED_RANGE_NOT_SATISFIABLE = _HTTPStatus(416, + 'Requested Range Not Satisfiable', + 'Cannot satisfy request range') + EXPECTATION_FAILED = _HTTPStatus(417, 'Expectation Failed', + 'Expect condition could not be satisfied') + MISDIRECTED_REQUEST = _HTTPStatus(421, 'Misdirected Request', + 'Server is not able to produce a response') + UNPROCESSABLE_ENTITY = _HTTPStatus(422, 'Unprocessable Entity') + LOCKED = _HTTPStatus(423, 'Locked') + FAILED_DEPENDENCY = _HTTPStatus(424, 'Failed Dependency') + UPGRADE_REQUIRED = _HTTPStatus(426, 'Upgrade Required') + PRECONDITION_REQUIRED = _HTTPStatus(428, 'Precondition Required', + 'The origin server requires the request to be conditional') + TOO_MANY_REQUESTS = _HTTPStatus(429, 'Too Many Requests', + 'The user has sent too many requests in ' + 'a given amount of time ("rate limiting")') + REQUEST_HEADER_FIELDS_TOO_LARGE = _HTTPStatus(431, + 'Request Header Fields Too Large', + 'The server is unwilling to process the request because its header ' + 'fields are too large') + UNAVAILABLE_FOR_LEGAL_REASONS = _HTTPStatus(451, + 'Unavailable For Legal Reasons', + 'The server is denying access to the ' + 'resource as a consequence of a legal demand') + INTERNAL_SERVER_ERROR = _HTTPStatus(500, 'Internal Server Error', + 'Server got itself in trouble') + NOT_IMPLEMENTED = _HTTPStatus(501, 'Not Implemented', + 'Server does not support this operation') + BAD_GATEWAY = _HTTPStatus(502, 'Bad Gateway', + 'Invalid responses from another server/proxy') + SERVICE_UNAVAILABLE = _HTTPStatus(503, 'Service Unavailable', + 'The server cannot process the request due to a high load') + GATEWAY_TIMEOUT = _HTTPStatus(504, 'Gateway Timeout', + 'The gateway server did not receive a timely response') + HTTP_VERSION_NOT_SUPPORTED = _HTTPStatus(505, 'HTTP Version Not Supported', + 'Cannot fulfill request') + VARIANT_ALSO_NEGOTIATES = _HTTPStatus(506, 'Variant Also Negotiates') + INSUFFICIENT_STORAGE = _HTTPStatus(507, 'Insufficient Storage') + LOOP_DETECTED = _HTTPStatus(508, 'Loop Detected') + NOT_EXTENDED = _HTTPStatus(510, 'Not Extended') + NETWORK_AUTHENTICATION_REQUIRED = _HTTPStatus(511, + 'Network Authentication Required', + 'The client needs to authenticate to gain network access') + """ + ) + return AstroidBuilder(astroid.MANAGER).string_build(code) + + +def _http_client_transform(): + return AstroidBuilder(astroid.MANAGER).string_build( + textwrap.dedent( + """ + from http import HTTPStatus + + CONTINUE = HTTPStatus.CONTINUE + SWITCHING_PROTOCOLS = HTTPStatus.SWITCHING_PROTOCOLS + PROCESSING = HTTPStatus.PROCESSING + OK = HTTPStatus.OK + CREATED = HTTPStatus.CREATED + ACCEPTED = HTTPStatus.ACCEPTED + NON_AUTHORITATIVE_INFORMATION = HTTPStatus.NON_AUTHORITATIVE_INFORMATION + NO_CONTENT = HTTPStatus.NO_CONTENT + RESET_CONTENT = HTTPStatus.RESET_CONTENT + PARTIAL_CONTENT = HTTPStatus.PARTIAL_CONTENT + MULTI_STATUS = HTTPStatus.MULTI_STATUS + ALREADY_REPORTED = HTTPStatus.ALREADY_REPORTED + IM_USED = HTTPStatus.IM_USED + MULTIPLE_CHOICES = HTTPStatus.MULTIPLE_CHOICES + MOVED_PERMANENTLY = HTTPStatus.MOVED_PERMANENTLY + FOUND = HTTPStatus.FOUND + SEE_OTHER = HTTPStatus.SEE_OTHER + NOT_MODIFIED = HTTPStatus.NOT_MODIFIED + USE_PROXY = HTTPStatus.USE_PROXY + TEMPORARY_REDIRECT = HTTPStatus.TEMPORARY_REDIRECT + PERMANENT_REDIRECT = HTTPStatus.PERMANENT_REDIRECT + BAD_REQUEST = HTTPStatus.BAD_REQUEST + UNAUTHORIZED = HTTPStatus.UNAUTHORIZED + PAYMENT_REQUIRED = HTTPStatus.PAYMENT_REQUIRED + FORBIDDEN = HTTPStatus.FORBIDDEN + NOT_FOUND = HTTPStatus.NOT_FOUND + METHOD_NOT_ALLOWED = HTTPStatus.METHOD_NOT_ALLOWED + NOT_ACCEPTABLE = HTTPStatus.NOT_ACCEPTABLE + PROXY_AUTHENTICATION_REQUIRED = HTTPStatus.PROXY_AUTHENTICATION_REQUIRED + REQUEST_TIMEOUT = HTTPStatus.REQUEST_TIMEOUT + CONFLICT = HTTPStatus.CONFLICT + GONE = HTTPStatus.GONE + LENGTH_REQUIRED = HTTPStatus.LENGTH_REQUIRED + PRECONDITION_FAILED = HTTPStatus.PRECONDITION_FAILED + REQUEST_ENTITY_TOO_LARGE = HTTPStatus.REQUEST_ENTITY_TOO_LARGE + REQUEST_URI_TOO_LONG = HTTPStatus.REQUEST_URI_TOO_LONG + UNSUPPORTED_MEDIA_TYPE = HTTPStatus.UNSUPPORTED_MEDIA_TYPE + REQUESTED_RANGE_NOT_SATISFIABLE = HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE + EXPECTATION_FAILED = HTTPStatus.EXPECTATION_FAILED + UNPROCESSABLE_ENTITY = HTTPStatus.UNPROCESSABLE_ENTITY + LOCKED = HTTPStatus.LOCKED + FAILED_DEPENDENCY = HTTPStatus.FAILED_DEPENDENCY + UPGRADE_REQUIRED = HTTPStatus.UPGRADE_REQUIRED + PRECONDITION_REQUIRED = HTTPStatus.PRECONDITION_REQUIRED + TOO_MANY_REQUESTS = HTTPStatus.TOO_MANY_REQUESTS + REQUEST_HEADER_FIELDS_TOO_LARGE = HTTPStatus.REQUEST_HEADER_FIELDS_TOO_LARGE + INTERNAL_SERVER_ERROR = HTTPStatus.INTERNAL_SERVER_ERROR + NOT_IMPLEMENTED = HTTPStatus.NOT_IMPLEMENTED + BAD_GATEWAY = HTTPStatus.BAD_GATEWAY + SERVICE_UNAVAILABLE = HTTPStatus.SERVICE_UNAVAILABLE + GATEWAY_TIMEOUT = HTTPStatus.GATEWAY_TIMEOUT + HTTP_VERSION_NOT_SUPPORTED = HTTPStatus.HTTP_VERSION_NOT_SUPPORTED + VARIANT_ALSO_NEGOTIATES = HTTPStatus.VARIANT_ALSO_NEGOTIATES + INSUFFICIENT_STORAGE = HTTPStatus.INSUFFICIENT_STORAGE + LOOP_DETECTED = HTTPStatus.LOOP_DETECTED + NOT_EXTENDED = HTTPStatus.NOT_EXTENDED + NETWORK_AUTHENTICATION_REQUIRED = HTTPStatus.NETWORK_AUTHENTICATION_REQUIRED + """ + ) + ) + + +astroid.register_module_extender(astroid.MANAGER, "http", _http_transform) +astroid.register_module_extender(astroid.MANAGER, "http.client", _http_client_transform) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_io.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_io.py new file mode 100644 index 0000000..4c68922 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_io.py @@ -0,0 +1,45 @@ +# Copyright (c) 2016 Claudiu Popa + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid brain hints for some of the _io C objects.""" + +import astroid + + +BUFFERED = {"BufferedWriter", "BufferedReader"} +TextIOWrapper = "TextIOWrapper" +FileIO = "FileIO" +BufferedWriter = "BufferedWriter" + + +def _generic_io_transform(node, name, cls): + """Transform the given name, by adding the given *class* as a member of the node.""" + + io_module = astroid.MANAGER.ast_from_module_name("_io") + attribute_object = io_module[cls] + instance = attribute_object.instantiate_class() + node.locals[name] = [instance] + + +def _transform_text_io_wrapper(node): + # This is not always correct, since it can vary with the type of the descriptor, + # being stdout, stderr or stdin. But we cannot get access to the name of the + # stream, which is why we are using the BufferedWriter class as a default + # value + return _generic_io_transform(node, name="buffer", cls=BufferedWriter) + + +def _transform_buffered(node): + return _generic_io_transform(node, name="raw", cls=FileIO) + + +astroid.MANAGER.register_transform( + astroid.ClassDef, _transform_buffered, lambda node: node.name in BUFFERED +) +astroid.MANAGER.register_transform( + astroid.ClassDef, + _transform_text_io_wrapper, + lambda node: node.name == TextIOWrapper, +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_mechanize.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_mechanize.py new file mode 100644 index 0000000..93f282e --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_mechanize.py @@ -0,0 +1,29 @@ +# Copyright (c) 2012-2013 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015-2016 Claudiu Popa +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder + + +def mechanize_transform(): + return AstroidBuilder(MANAGER).string_build( + """ + +class Browser(object): + def open(self, url, data=None, timeout=None): + return None + def open_novisit(self, url, data=None, timeout=None): + return None + def open_local_file(self, filename): + return None + +""" + ) + + +register_module_extender(MANAGER, "mechanize", mechanize_transform) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_multiprocessing.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_multiprocessing.py new file mode 100644 index 0000000..71256ee --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_multiprocessing.py @@ -0,0 +1,106 @@ +# Copyright (c) 2016 Claudiu Popa + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +import sys + +import astroid +from astroid import exceptions + + +def _multiprocessing_transform(): + module = astroid.parse( + """ + from multiprocessing.managers import SyncManager + def Manager(): + return SyncManager() + """ + ) + # Multiprocessing uses a getattr lookup inside contexts, + # in order to get the attributes they need. Since it's extremely + # dynamic, we use this approach to fake it. + node = astroid.parse( + """ + from multiprocessing.context import DefaultContext, BaseContext + default = DefaultContext() + base = BaseContext() + """ + ) + try: + context = next(node["default"].infer()) + base = next(node["base"].infer()) + except exceptions.InferenceError: + return module + + for node in (context, base): + for key, value in node.locals.items(): + if key.startswith("_"): + continue + + value = value[0] + if isinstance(value, astroid.FunctionDef): + # We need to rebound this, since otherwise + # it will have an extra argument (self). + value = astroid.BoundMethod(value, node) + module[key] = value + return module + + +def _multiprocessing_managers_transform(): + return astroid.parse( + """ + import array + import threading + import multiprocessing.pool as pool + + import six + + class Namespace(object): + pass + + class Value(object): + def __init__(self, typecode, value, lock=True): + self._typecode = typecode + self._value = value + def get(self): + return self._value + def set(self, value): + self._value = value + def __repr__(self): + return '%s(%r, %r)'%(type(self).__name__, self._typecode, self._value) + value = property(get, set) + + def Array(typecode, sequence, lock=True): + return array.array(typecode, sequence) + + class SyncManager(object): + Queue = JoinableQueue = six.moves.queue.Queue + Event = threading.Event + RLock = threading.RLock + BoundedSemaphore = threading.BoundedSemaphore + Condition = threading.Condition + Barrier = threading.Barrier + Pool = pool.Pool + list = list + dict = dict + Value = Value + Array = Array + Namespace = Namespace + __enter__ = lambda self: self + __exit__ = lambda *args: args + + def start(self, initializer=None, initargs=None): + pass + def shutdown(self): + pass + """ + ) + + +astroid.register_module_extender( + astroid.MANAGER, "multiprocessing.managers", _multiprocessing_managers_transform +) +astroid.register_module_extender( + astroid.MANAGER, "multiprocessing", _multiprocessing_transform +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_namedtuple_enum.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_namedtuple_enum.py new file mode 100644 index 0000000..de24067 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_namedtuple_enum.py @@ -0,0 +1,449 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2012-2015 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Dmitry Pribysh +# Copyright (c) 2015 David Shea +# Copyright (c) 2015 Philip Lorenz +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2016 Mateusz Bysiek +# Copyright (c) 2017 Hugo +# Copyright (c) 2017 Łukasz Rogalski + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for the Python standard library.""" + +import functools +import keyword +from textwrap import dedent + +from astroid import MANAGER, UseInferenceDefault, inference_tip, InferenceError +from astroid import arguments +from astroid import exceptions +from astroid import nodes +from astroid.builder import AstroidBuilder, extract_node +from astroid import util + + +TYPING_NAMEDTUPLE_BASENAMES = {"NamedTuple", "typing.NamedTuple"} +ENUM_BASE_NAMES = { + "Enum", + "IntEnum", + "enum.Enum", + "enum.IntEnum", + "IntFlag", + "enum.IntFlag", +} + + +def _infer_first(node, context): + if node is util.Uninferable: + raise UseInferenceDefault + try: + value = next(node.infer(context=context)) + if value is util.Uninferable: + raise UseInferenceDefault() + else: + return value + except StopIteration: + raise InferenceError() + + +def _find_func_form_arguments(node, context): + def _extract_namedtuple_arg_or_keyword(position, key_name=None): + + if len(args) > position: + return _infer_first(args[position], context) + if key_name and key_name in found_keywords: + return _infer_first(found_keywords[key_name], context) + + args = node.args + keywords = node.keywords + found_keywords = ( + {keyword.arg: keyword.value for keyword in keywords} if keywords else {} + ) + + name = _extract_namedtuple_arg_or_keyword(position=0, key_name="typename") + names = _extract_namedtuple_arg_or_keyword(position=1, key_name="field_names") + if name and names: + return name.value, names + + raise UseInferenceDefault() + + +def infer_func_form(node, base_type, context=None, enum=False): + """Specific inference function for namedtuple or Python 3 enum. """ + # node is a Call node, class name as first argument and generated class + # attributes as second argument + + # namedtuple or enums list of attributes can be a list of strings or a + # whitespace-separate string + try: + name, names = _find_func_form_arguments(node, context) + try: + attributes = names.value.replace(",", " ").split() + except AttributeError: + if not enum: + attributes = [ + _infer_first(const, context).value for const in names.elts + ] + else: + # Enums supports either iterator of (name, value) pairs + # or mappings. + if hasattr(names, "items") and isinstance(names.items, list): + attributes = [ + _infer_first(const[0], context).value + for const in names.items + if isinstance(const[0], nodes.Const) + ] + elif hasattr(names, "elts"): + # Enums can support either ["a", "b", "c"] + # or [("a", 1), ("b", 2), ...], but they can't + # be mixed. + if all(isinstance(const, nodes.Tuple) for const in names.elts): + attributes = [ + _infer_first(const.elts[0], context).value + for const in names.elts + if isinstance(const, nodes.Tuple) + ] + else: + attributes = [ + _infer_first(const, context).value for const in names.elts + ] + else: + raise AttributeError + if not attributes: + raise AttributeError + except (AttributeError, exceptions.InferenceError): + raise UseInferenceDefault() + + # If we can't infer the name of the class, don't crash, up to this point + # we know it is a namedtuple anyway. + name = name or "Uninferable" + # we want to return a Class node instance with proper attributes set + class_node = nodes.ClassDef(name, "docstring") + class_node.parent = node.parent + # set base class=tuple + class_node.bases.append(base_type) + # XXX add __init__(*attributes) method + for attr in attributes: + fake_node = nodes.EmptyNode() + fake_node.parent = class_node + fake_node.attrname = attr + class_node.instance_attrs[attr] = [fake_node] + return class_node, name, attributes + + +def _has_namedtuple_base(node): + """Predicate for class inference tip + + :type node: ClassDef + :rtype: bool + """ + return set(node.basenames) & TYPING_NAMEDTUPLE_BASENAMES + + +def _looks_like(node, name): + func = node.func + if isinstance(func, nodes.Attribute): + return func.attrname == name + if isinstance(func, nodes.Name): + return func.name == name + return False + + +_looks_like_namedtuple = functools.partial(_looks_like, name="namedtuple") +_looks_like_enum = functools.partial(_looks_like, name="Enum") +_looks_like_typing_namedtuple = functools.partial(_looks_like, name="NamedTuple") + + +def infer_named_tuple(node, context=None): + """Specific inference function for namedtuple Call node""" + tuple_base_name = nodes.Name(name="tuple", parent=node.root()) + class_node, name, attributes = infer_func_form( + node, tuple_base_name, context=context + ) + call_site = arguments.CallSite.from_call(node) + func = next(extract_node("import collections; collections.namedtuple").infer()) + try: + rename = next(call_site.infer_argument(func, "rename", context)).bool_value() + except InferenceError: + rename = False + + if rename: + attributes = _get_renamed_namedtuple_attributes(attributes) + + replace_args = ", ".join("{arg}=None".format(arg=arg) for arg in attributes) + field_def = ( + " {name} = property(lambda self: self[{index:d}], " + "doc='Alias for field number {index:d}')" + ) + field_defs = "\n".join( + field_def.format(name=name, index=index) + for index, name in enumerate(attributes) + ) + fake = AstroidBuilder(MANAGER).string_build( + """ +class %(name)s(tuple): + __slots__ = () + _fields = %(fields)r + def _asdict(self): + return self.__dict__ + @classmethod + def _make(cls, iterable, new=tuple.__new__, len=len): + return new(cls, iterable) + def _replace(self, %(replace_args)s): + return self + def __getnewargs__(self): + return tuple(self) +%(field_defs)s + """ + % { + "name": name, + "fields": attributes, + "field_defs": field_defs, + "replace_args": replace_args, + } + ) + class_node.locals["_asdict"] = fake.body[0].locals["_asdict"] + class_node.locals["_make"] = fake.body[0].locals["_make"] + class_node.locals["_replace"] = fake.body[0].locals["_replace"] + class_node.locals["_fields"] = fake.body[0].locals["_fields"] + for attr in attributes: + class_node.locals[attr] = fake.body[0].locals[attr] + # we use UseInferenceDefault, we can't be a generator so return an iterator + return iter([class_node]) + + +def _get_renamed_namedtuple_attributes(field_names): + names = list(field_names) + seen = set() + for i, name in enumerate(field_names): + if ( + not all(c.isalnum() or c == "_" for c in name) + or keyword.iskeyword(name) + or not name + or name[0].isdigit() + or name.startswith("_") + or name in seen + ): + names[i] = "_%d" % i + seen.add(name) + return tuple(names) + + +def infer_enum(node, context=None): + """ Specific inference function for enum Call node. """ + enum_meta = extract_node( + """ + class EnumMeta(object): + 'docstring' + def __call__(self, node): + class EnumAttribute(object): + name = '' + value = 0 + return EnumAttribute() + def __iter__(self): + class EnumAttribute(object): + name = '' + value = 0 + return [EnumAttribute()] + def __reversed__(self): + class EnumAttribute(object): + name = '' + value = 0 + return (EnumAttribute, ) + def __next__(self): + return next(iter(self)) + def __getitem__(self, attr): + class Value(object): + @property + def name(self): + return '' + @property + def value(self): + return attr + + return Value() + __members__ = [''] + """ + ) + class_node = infer_func_form(node, enum_meta, context=context, enum=True)[0] + return iter([class_node.instantiate_class()]) + + +INT_FLAG_ADDITION_METHODS = """ + def __or__(self, other): + return {name}(self.value | other.value) + def __and__(self, other): + return {name}(self.value & other.value) + def __xor__(self, other): + return {name}(self.value ^ other.value) + def __add__(self, other): + return {name}(self.value + other.value) + def __div__(self, other): + return {name}(self.value / other.value) + def __invert__(self): + return {name}(~self.value) + def __mul__(self, other): + return {name}(self.value * other.value) +""" + + +def infer_enum_class(node): + """ Specific inference for enums. """ + for basename in node.basenames: + # TODO: doesn't handle subclasses yet. This implementation + # is a hack to support enums. + if basename not in ENUM_BASE_NAMES: + continue + if node.root().name == "enum": + # Skip if the class is directly from enum module. + break + for local, values in node.locals.items(): + if any(not isinstance(value, nodes.AssignName) for value in values): + continue + + targets = [] + stmt = values[0].statement() + if isinstance(stmt, nodes.Assign): + if isinstance(stmt.targets[0], nodes.Tuple): + targets = stmt.targets[0].itered() + else: + targets = stmt.targets + elif isinstance(stmt, nodes.AnnAssign): + targets = [stmt.target] + + inferred_return_value = None + if isinstance(stmt, nodes.Assign): + if isinstance(stmt.value, nodes.Const): + if isinstance(stmt.value.value, str): + inferred_return_value = repr(stmt.value.value) + else: + inferred_return_value = stmt.value.value + else: + inferred_return_value = stmt.value.as_string() + + new_targets = [] + for target in targets: + # Replace all the assignments with our mocked class. + classdef = dedent( + """ + class {name}({types}): + @property + def value(self): + return {return_value} + @property + def name(self): + return "{name}" + """.format( + name=target.name, + types=", ".join(node.basenames), + return_value=inferred_return_value, + ) + ) + if "IntFlag" in basename: + # Alright, we need to add some additional methods. + # Unfortunately we still can't infer the resulting objects as + # Enum members, but once we'll be able to do that, the following + # should result in some nice symbolic execution + classdef += INT_FLAG_ADDITION_METHODS.format(name=target.name) + + fake = AstroidBuilder(MANAGER).string_build(classdef)[target.name] + fake.parent = target.parent + for method in node.mymethods(): + fake.locals[method.name] = [method] + new_targets.append(fake.instantiate_class()) + node.locals[local] = new_targets + break + return node + + +def infer_typing_namedtuple_class(class_node, context=None): + """Infer a subclass of typing.NamedTuple""" + # Check if it has the corresponding bases + annassigns_fields = [ + annassign.target.name + for annassign in class_node.body + if isinstance(annassign, nodes.AnnAssign) + ] + code = dedent( + """ + from collections import namedtuple + namedtuple({typename!r}, {fields!r}) + """ + ).format(typename=class_node.name, fields=",".join(annassigns_fields)) + node = extract_node(code) + generated_class_node = next(infer_named_tuple(node, context)) + for method in class_node.mymethods(): + generated_class_node.locals[method.name] = [method] + + for assign in class_node.body: + if not isinstance(assign, nodes.Assign): + continue + + for target in assign.targets: + attr = target.name + generated_class_node.locals[attr] = class_node.locals[attr] + + return iter((generated_class_node,)) + + +def infer_typing_namedtuple(node, context=None): + """Infer a typing.NamedTuple(...) call.""" + # This is essentially a namedtuple with different arguments + # so we extract the args and infer a named tuple. + try: + func = next(node.func.infer()) + except InferenceError: + raise UseInferenceDefault + + if func.qname() != "typing.NamedTuple": + raise UseInferenceDefault + + if len(node.args) != 2: + raise UseInferenceDefault + + if not isinstance(node.args[1], (nodes.List, nodes.Tuple)): + raise UseInferenceDefault + + names = [] + for elt in node.args[1].elts: + if not isinstance(elt, (nodes.List, nodes.Tuple)): + raise UseInferenceDefault + if len(elt.elts) != 2: + raise UseInferenceDefault + names.append(elt.elts[0].as_string()) + + typename = node.args[0].as_string() + if names: + field_names = "({},)".format(",".join(names)) + else: + field_names = "''" + node = extract_node( + "namedtuple({typename}, {fields})".format(typename=typename, fields=field_names) + ) + return infer_named_tuple(node, context) + + +MANAGER.register_transform( + nodes.Call, inference_tip(infer_named_tuple), _looks_like_namedtuple +) +MANAGER.register_transform(nodes.Call, inference_tip(infer_enum), _looks_like_enum) +MANAGER.register_transform( + nodes.ClassDef, + infer_enum_class, + predicate=lambda cls: any( + basename for basename in cls.basenames if basename in ENUM_BASE_NAMES + ), +) +MANAGER.register_transform( + nodes.ClassDef, inference_tip(infer_typing_namedtuple_class), _has_namedtuple_base +) +MANAGER.register_transform( + nodes.Call, inference_tip(infer_typing_namedtuple), _looks_like_typing_namedtuple +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_nose.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_nose.py new file mode 100644 index 0000000..7b12d76 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_nose.py @@ -0,0 +1,77 @@ +# Copyright (c) 2015-2016 Claudiu Popa +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +"""Hooks for nose library.""" + +import re +import textwrap + +import astroid +import astroid.builder + +_BUILDER = astroid.builder.AstroidBuilder(astroid.MANAGER) + + +def _pep8(name, caps=re.compile("([A-Z])")): + return caps.sub(lambda m: "_" + m.groups()[0].lower(), name) + + +def _nose_tools_functions(): + """Get an iterator of names and bound methods.""" + module = _BUILDER.string_build( + textwrap.dedent( + """ + import unittest + + class Test(unittest.TestCase): + pass + a = Test() + """ + ) + ) + try: + case = next(module["a"].infer()) + except astroid.InferenceError: + return + for method in case.methods(): + if method.name.startswith("assert") and "_" not in method.name: + pep8_name = _pep8(method.name) + yield pep8_name, astroid.BoundMethod(method, case) + if method.name == "assertEqual": + # nose also exports assert_equals. + yield "assert_equals", astroid.BoundMethod(method, case) + + +def _nose_tools_transform(node): + for method_name, method in _nose_tools_functions(): + node.locals[method_name] = [method] + + +def _nose_tools_trivial_transform(): + """Custom transform for the nose.tools module.""" + stub = _BUILDER.string_build("""__all__ = []""") + all_entries = ["ok_", "eq_"] + + for pep8_name, method in _nose_tools_functions(): + all_entries.append(pep8_name) + stub[pep8_name] = method + + # Update the __all__ variable, since nose.tools + # does this manually with .append. + all_assign = stub["__all__"].parent + all_object = astroid.List(all_entries) + all_object.parent = all_assign + all_assign.value = all_object + return stub + + +astroid.register_module_extender( + astroid.MANAGER, "nose.tools.trivial", _nose_tools_trivial_transform +) +astroid.MANAGER.register_transform( + astroid.Module, _nose_tools_transform, lambda n: n.name == "nose.tools" +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_fromnumeric.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_fromnumeric.py new file mode 100644 index 0000000..43b30e4 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_fromnumeric.py @@ -0,0 +1,23 @@ +# Copyright (c) 2018-2019 hippo91 + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +"""Astroid hooks for numpy.core.fromnumeric module.""" + +import astroid + + +def numpy_core_fromnumeric_transform(): + return astroid.parse( + """ + def sum(a, axis=None, dtype=None, out=None, keepdims=None, initial=None): + return numpy.ndarray([0, 0]) + """ + ) + + +astroid.register_module_extender( + astroid.MANAGER, "numpy.core.fromnumeric", numpy_core_fromnumeric_transform +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_function_base.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_function_base.py new file mode 100644 index 0000000..05a73d9 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_function_base.py @@ -0,0 +1,29 @@ +# Copyright (c) 2018-2019 hippo91 + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +"""Astroid hooks for numpy.core.function_base module.""" + +import functools +import astroid +from brain_numpy_utils import looks_like_numpy_member, infer_numpy_member + + +METHODS_TO_BE_INFERRED = { + "linspace": """def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0): + return numpy.ndarray([0, 0])""", + "logspace": """def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0): + return numpy.ndarray([0, 0])""", + "geomspace": """def geomspace(start, stop, num=50, endpoint=True, dtype=None, axis=0): + return numpy.ndarray([0, 0])""", +} + +for func_name, func_src in METHODS_TO_BE_INFERRED.items(): + inference_function = functools.partial(infer_numpy_member, func_src) + astroid.MANAGER.register_transform( + astroid.Attribute, + astroid.inference_tip(inference_function), + functools.partial(looks_like_numpy_member, func_name), + ) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_multiarray.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_multiarray.py new file mode 100644 index 0000000..3032acc --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_multiarray.py @@ -0,0 +1,55 @@ +# Copyright (c) 2018-2019 hippo91 + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +"""Astroid hooks for numpy.core.multiarray module.""" + +import functools +import astroid +from brain_numpy_utils import looks_like_numpy_member, infer_numpy_member + + +def numpy_core_multiarray_transform(): + return astroid.parse( + """ + # different functions defined in multiarray.py + def inner(a, b): + return numpy.ndarray([0, 0]) + + def vdot(a, b): + return numpy.ndarray([0, 0]) + """ + ) + + +astroid.register_module_extender( + astroid.MANAGER, "numpy.core.multiarray", numpy_core_multiarray_transform +) + + +METHODS_TO_BE_INFERRED = { + "array": """def array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0): + return numpy.ndarray([0, 0])""", + "dot": """def dot(a, b, out=None): + return numpy.ndarray([0, 0])""", + "empty_like": """def empty_like(a, dtype=None, order='K', subok=True): + return numpy.ndarray((0, 0))""", + "concatenate": """def concatenate(arrays, axis=None, out=None): + return numpy.ndarray((0, 0))""", + "where": """def where(condition, x=None, y=None): + return numpy.ndarray([0, 0])""", + "empty": """def empty(shape, dtype=float, order='C'): + return numpy.ndarray([0, 0])""", + "zeros": """def zeros(shape, dtype=float, order='C'): + return numpy.ndarray([0, 0])""", +} + +for method_name, function_src in METHODS_TO_BE_INFERRED.items(): + inference_function = functools.partial(infer_numpy_member, function_src) + astroid.MANAGER.register_transform( + astroid.Attribute, + astroid.inference_tip(inference_function), + functools.partial(looks_like_numpy_member, method_name), + ) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_numeric.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_numeric.py new file mode 100644 index 0000000..ba43c94 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_numeric.py @@ -0,0 +1,43 @@ +# Copyright (c) 2018-2019 hippo91 + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +"""Astroid hooks for numpy.core.numeric module.""" + +import functools +import astroid +from brain_numpy_utils import looks_like_numpy_member, infer_numpy_member + + +def numpy_core_numeric_transform(): + return astroid.parse( + """ + # different functions defined in numeric.py + import numpy + def zeros_like(a, dtype=None, order='K', subok=True): return numpy.ndarray((0, 0)) + def ones_like(a, dtype=None, order='K', subok=True): return numpy.ndarray((0, 0)) + def full_like(a, fill_value, dtype=None, order='K', subok=True): return numpy.ndarray((0, 0)) + """ + ) + + +astroid.register_module_extender( + astroid.MANAGER, "numpy.core.numeric", numpy_core_numeric_transform +) + + +METHODS_TO_BE_INFERRED = { + "ones": """def ones(shape, dtype=None, order='C'): + return numpy.ndarray([0, 0])""" +} + + +for method_name, function_src in METHODS_TO_BE_INFERRED.items(): + inference_function = functools.partial(infer_numpy_member, function_src) + astroid.MANAGER.register_transform( + astroid.Attribute, + astroid.inference_tip(inference_function), + functools.partial(looks_like_numpy_member, method_name), + ) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_numerictypes.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_numerictypes.py new file mode 100644 index 0000000..42021fa --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_numerictypes.py @@ -0,0 +1,250 @@ +# Copyright (c) 2018-2019 hippo91 + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +# TODO(hippo91) : correct the methods signature. + +"""Astroid hooks for numpy.core.numerictypes module.""" + +import astroid + + +def numpy_core_numerictypes_transform(): + return astroid.parse( + """ + # different types defined in numerictypes.py + class generic(object): + def __init__(self, value): + self.T = None + self.base = None + self.data = None + self.dtype = None + self.flags = None + self.flat = None + self.imag = None + self.itemsize = None + self.nbytes = None + self.ndim = None + self.real = None + self.size = None + self.strides = None + + def all(self): return uninferable + def any(self): return uninferable + def argmax(self): return uninferable + def argmin(self): return uninferable + def argsort(self): return uninferable + def astype(self): return uninferable + def base(self): return uninferable + def byteswap(self): return uninferable + def choose(self): return uninferable + def clip(self): return uninferable + def compress(self): return uninferable + def conj(self): return uninferable + def conjugate(self): return uninferable + def copy(self): return uninferable + def cumprod(self): return uninferable + def cumsum(self): return uninferable + def data(self): return uninferable + def diagonal(self): return uninferable + def dtype(self): return uninferable + def dump(self): return uninferable + def dumps(self): return uninferable + def fill(self): return uninferable + def flags(self): return uninferable + def flat(self): return uninferable + def flatten(self): return uninferable + def getfield(self): return uninferable + def imag(self): return uninferable + def item(self): return uninferable + def itemset(self): return uninferable + def itemsize(self): return uninferable + def max(self): return uninferable + def mean(self): return uninferable + def min(self): return uninferable + def nbytes(self): return uninferable + def ndim(self): return uninferable + def newbyteorder(self): return uninferable + def nonzero(self): return uninferable + def prod(self): return uninferable + def ptp(self): return uninferable + def put(self): return uninferable + def ravel(self): return uninferable + def real(self): return uninferable + def repeat(self): return uninferable + def reshape(self): return uninferable + def resize(self): return uninferable + def round(self): return uninferable + def searchsorted(self): return uninferable + def setfield(self): return uninferable + def setflags(self): return uninferable + def shape(self): return uninferable + def size(self): return uninferable + def sort(self): return uninferable + def squeeze(self): return uninferable + def std(self): return uninferable + def strides(self): return uninferable + def sum(self): return uninferable + def swapaxes(self): return uninferable + def take(self): return uninferable + def tobytes(self): return uninferable + def tofile(self): return uninferable + def tolist(self): return uninferable + def tostring(self): return uninferable + def trace(self): return uninferable + def transpose(self): return uninferable + def var(self): return uninferable + def view(self): return uninferable + + + class dtype(object): + def __init__(self, obj, align=False, copy=False): + self.alignment = None + self.base = None + self.byteorder = None + self.char = None + self.descr = None + self.fields = None + self.flags = None + self.hasobject = None + self.isalignedstruct = None + self.isbuiltin = None + self.isnative = None + self.itemsize = None + self.kind = None + self.metadata = None + self.name = None + self.names = None + self.num = None + self.shape = None + self.str = None + self.subdtype = None + self.type = None + + def newbyteorder(self, new_order='S'): return uninferable + def __neg__(self): return uninferable + + class busdaycalendar(object): + def __init__(self, weekmask='1111100', holidays=None): + self.holidays = None + self.weekmask = None + + class flexible(generic): pass + class bool_(generic): pass + class number(generic): + def __neg__(self): return uninferable + class datetime64(generic): + def __init__(self, nb, unit=None): pass + + + class void(flexible): + def __init__(self, *args, **kwargs): + self.base = None + self.dtype = None + self.flags = None + def getfield(self): return uninferable + def setfield(self): return uninferable + + + class character(flexible): pass + + + class integer(number): + def __init__(self, value): + self.denominator = None + self.numerator = None + + + class inexact(number): pass + + + class str_(str, character): + def maketrans(self, x, y=None, z=None): return uninferable + + + class bytes_(bytes, character): + def fromhex(self, string): return uninferable + def maketrans(self, frm, to): return uninferable + + + class signedinteger(integer): pass + + + class unsignedinteger(integer): pass + + + class complexfloating(inexact): pass + + + class floating(inexact): pass + + + class float64(floating, float): + def fromhex(self, string): return uninferable + + + class uint64(unsignedinteger): pass + class complex64(complexfloating): pass + class int16(signedinteger): pass + class float96(floating): pass + class int8(signedinteger): pass + class uint32(unsignedinteger): pass + class uint8(unsignedinteger): pass + class _typedict(dict): pass + class complex192(complexfloating): pass + class timedelta64(signedinteger): + def __init__(self, nb, unit=None): pass + class int32(signedinteger): pass + class uint16(unsignedinteger): pass + class float32(floating): pass + class complex128(complexfloating, complex): pass + class float16(floating): pass + class int64(signedinteger): pass + + buffer_type = memoryview + bool8 = bool_ + byte = int8 + bytes0 = bytes_ + cdouble = complex128 + cfloat = complex128 + clongdouble = complex192 + clongfloat = complex192 + complex_ = complex128 + csingle = complex64 + double = float64 + float_ = float64 + half = float16 + int0 = int32 + int_ = int32 + intc = int32 + intp = int32 + long = int32 + longcomplex = complex192 + longdouble = float96 + longfloat = float96 + longlong = int64 + object0 = object_ + object_ = object_ + short = int16 + single = float32 + singlecomplex = complex64 + str0 = str_ + string_ = bytes_ + ubyte = uint8 + uint = uint32 + uint0 = uint32 + uintc = uint32 + uintp = uint32 + ulonglong = uint64 + unicode = str_ + unicode_ = str_ + ushort = uint16 + void0 = void + """ + ) + + +astroid.register_module_extender( + astroid.MANAGER, "numpy.core.numerictypes", numpy_core_numerictypes_transform +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_umath.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_umath.py new file mode 100644 index 0000000..459d38c --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_core_umath.py @@ -0,0 +1,105 @@ +# Copyright (c) 2018-2019 hippo91 + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +"""Astroid hooks for numpy.core.umath module.""" + +import astroid + + +def numpy_core_umath_transform(): + ufunc_optional_keyword_arguments = ( + """out=None, where=True, casting='same_kind', order='K', """ + """dtype=None, subok=True""" + ) + return astroid.parse( + """ + # Constants + e = 2.718281828459045 + euler_gamma = 0.5772156649015329 + + # No arg functions + def geterrobj(): return [] + + # One arg functions + def seterrobj(errobj): return None + + # One arg functions with optional kwargs + def arccos(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def arccosh(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def arcsin(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def arcsinh(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def arctan(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def arctanh(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def cbrt(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def conj(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def conjugate(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def cosh(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def deg2rad(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def degrees(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def exp2(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def expm1(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def fabs(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def frexp(x, {opt_args:s}): return (numpy.ndarray((0, 0)), numpy.ndarray((0, 0))) + def isfinite(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def isinf(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def log(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def log1p(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def log2(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def logical_not(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def modf(x, {opt_args:s}): return (numpy.ndarray((0, 0)), numpy.ndarray((0, 0))) + def negative(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def rad2deg(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def radians(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def reciprocal(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def rint(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def sign(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def signbit(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def sinh(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def spacing(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def square(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def tan(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def tanh(x, {opt_args:s}): return numpy.ndarray((0, 0)) + def trunc(x, {opt_args:s}): return numpy.ndarray((0, 0)) + + # Two args functions with optional kwargs + def bitwise_and(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def bitwise_or(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def bitwise_xor(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def copysign(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def divide(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def equal(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def floor_divide(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def fmax(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def fmin(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def fmod(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def greater(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def hypot(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def ldexp(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def left_shift(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def less(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def logaddexp(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def logaddexp2(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def logical_and(x1, x2, {opt_args:s}): return numpy.ndarray([0, 0]) + def logical_or(x1, x2, {opt_args:s}): return numpy.ndarray([0, 0]) + def logical_xor(x1, x2, {opt_args:s}): return numpy.ndarray([0, 0]) + def maximum(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def minimum(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def nextafter(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def not_equal(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def power(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def remainder(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def right_shift(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def subtract(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + def true_divide(x1, x2, {opt_args:s}): return numpy.ndarray((0, 0)) + """.format( + opt_args=ufunc_optional_keyword_arguments + ) + ) + + +astroid.register_module_extender( + astroid.MANAGER, "numpy.core.umath", numpy_core_umath_transform +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_ndarray.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_ndarray.py new file mode 100644 index 0000000..8c231a3 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_ndarray.py @@ -0,0 +1,153 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2016 Ceridwen +# Copyright (c) 2017-2018 hippo91 + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +"""Astroid hooks for numpy ndarray class.""" + +import functools +import astroid + + +def infer_numpy_ndarray(node, context=None): + ndarray = """ + class ndarray(object): + def __init__(self, shape, dtype=float, buffer=None, offset=0, + strides=None, order=None): + self.T = None + self.base = None + self.ctypes = None + self.data = None + self.dtype = None + self.flags = None + self.flat = None + self.imag = None + self.itemsize = None + self.nbytes = None + self.ndim = None + self.real = None + self.shape = None + self.size = None + self.strides = None + + def __abs__(self): return numpy.ndarray([0, 0]) + def __add__(self, value): return numpy.ndarray([0, 0]) + def __and__(self, value): return numpy.ndarray([0, 0]) + def __array__(self, dtype=None): return numpy.ndarray([0, 0]) + def __array_wrap__(self, obj): return numpy.ndarray([0, 0]) + def __contains__(self, key): return True + def __copy__(self): return numpy.ndarray([0, 0]) + def __deepcopy__(self, memo): return numpy.ndarray([0, 0]) + def __divmod__(self, value): return (numpy.ndarray([0, 0]), numpy.ndarray([0, 0])) + def __eq__(self, value): return numpy.ndarray([0, 0]) + def __float__(self): return 0. + def __floordiv__(self): return numpy.ndarray([0, 0]) + def __ge__(self, value): return numpy.ndarray([0, 0]) + def __getitem__(self, key): return uninferable + def __gt__(self, value): return numpy.ndarray([0, 0]) + def __iadd__(self, value): return numpy.ndarray([0, 0]) + def __iand__(self, value): return numpy.ndarray([0, 0]) + def __ifloordiv__(self, value): return numpy.ndarray([0, 0]) + def __ilshift__(self, value): return numpy.ndarray([0, 0]) + def __imod__(self, value): return numpy.ndarray([0, 0]) + def __imul__(self, value): return numpy.ndarray([0, 0]) + def __int__(self): return 0 + def __invert__(self): return numpy.ndarray([0, 0]) + def __ior__(self, value): return numpy.ndarray([0, 0]) + def __ipow__(self, value): return numpy.ndarray([0, 0]) + def __irshift__(self, value): return numpy.ndarray([0, 0]) + def __isub__(self, value): return numpy.ndarray([0, 0]) + def __itruediv__(self, value): return numpy.ndarray([0, 0]) + def __ixor__(self, value): return numpy.ndarray([0, 0]) + def __le__(self, value): return numpy.ndarray([0, 0]) + def __len__(self): return 1 + def __lshift__(self, value): return numpy.ndarray([0, 0]) + def __lt__(self, value): return numpy.ndarray([0, 0]) + def __matmul__(self, value): return numpy.ndarray([0, 0]) + def __mod__(self, value): return numpy.ndarray([0, 0]) + def __mul__(self, value): return numpy.ndarray([0, 0]) + def __ne__(self, value): return numpy.ndarray([0, 0]) + def __neg__(self): return numpy.ndarray([0, 0]) + def __or__(self): return numpy.ndarray([0, 0]) + def __pos__(self): return numpy.ndarray([0, 0]) + def __pow__(self): return numpy.ndarray([0, 0]) + def __repr__(self): return str() + def __rshift__(self): return numpy.ndarray([0, 0]) + def __setitem__(self, key, value): return uninferable + def __str__(self): return str() + def __sub__(self, value): return numpy.ndarray([0, 0]) + def __truediv__(self, value): return numpy.ndarray([0, 0]) + def __xor__(self, value): return numpy.ndarray([0, 0]) + def all(self, axis=None, out=None, keepdims=False): return np.ndarray([0, 0]) + def any(self, axis=None, out=None, keepdims=False): return np.ndarray([0, 0]) + def argmax(self, axis=None, out=None): return np.ndarray([0, 0]) + def argmin(self, axis=None, out=None): return np.ndarray([0, 0]) + def argpartition(self, kth, axis=-1, kind='introselect', order=None): return np.ndarray([0, 0]) + def argsort(self, axis=-1, kind='quicksort', order=None): return np.ndarray([0, 0]) + def astype(self, dtype, order='K', casting='unsafe', subok=True, copy=True): return np.ndarray([0, 0]) + def byteswap(self, inplace=False): return np.ndarray([0, 0]) + def choose(self, choices, out=None, mode='raise'): return np.ndarray([0, 0]) + def clip(self, min=None, max=None, out=None): return np.ndarray([0, 0]) + def compress(self, condition, axis=None, out=None): return np.ndarray([0, 0]) + def conj(self): return np.ndarray([0, 0]) + def conjugate(self): return np.ndarray([0, 0]) + def copy(self, order='C'): return np.ndarray([0, 0]) + def cumprod(self, axis=None, dtype=None, out=None): return np.ndarray([0, 0]) + def cumsum(self, axis=None, dtype=None, out=None): return np.ndarray([0, 0]) + def diagonal(self, offset=0, axis1=0, axis2=1): return np.ndarray([0, 0]) + def dot(self, b, out=None): return np.ndarray([0, 0]) + def dump(self, file): return None + def dumps(self): return str() + def fill(self, value): return None + def flatten(self, order='C'): return np.ndarray([0, 0]) + def getfield(self, dtype, offset=0): return np.ndarray([0, 0]) + def item(self, *args): return uninferable + def itemset(self, *args): return None + def max(self, axis=None, out=None): return np.ndarray([0, 0]) + def mean(self, axis=None, dtype=None, out=None, keepdims=False): return np.ndarray([0, 0]) + def min(self, axis=None, out=None, keepdims=False): return np.ndarray([0, 0]) + def newbyteorder(self, new_order='S'): return np.ndarray([0, 0]) + def nonzero(self): return (1,) + def partition(self, kth, axis=-1, kind='introselect', order=None): return None + def prod(self, axis=None, dtype=None, out=None, keepdims=False): return np.ndarray([0, 0]) + def ptp(self, axis=None, out=None): return np.ndarray([0, 0]) + def put(self, indices, values, mode='raise'): return None + def ravel(self, order='C'): return np.ndarray([0, 0]) + def repeat(self, repeats, axis=None): return np.ndarray([0, 0]) + def reshape(self, shape, order='C'): return np.ndarray([0, 0]) + def resize(self, new_shape, refcheck=True): return None + def round(self, decimals=0, out=None): return np.ndarray([0, 0]) + def searchsorted(self, v, side='left', sorter=None): return np.ndarray([0, 0]) + def setfield(self, val, dtype, offset=0): return None + def setflags(self, write=None, align=None, uic=None): return None + def sort(self, axis=-1, kind='quicksort', order=None): return None + def squeeze(self, axis=None): return np.ndarray([0, 0]) + def std(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): return np.ndarray([0, 0]) + def sum(self, axis=None, dtype=None, out=None, keepdims=False): return np.ndarray([0, 0]) + def swapaxes(self, axis1, axis2): return np.ndarray([0, 0]) + def take(self, indices, axis=None, out=None, mode='raise'): return np.ndarray([0, 0]) + def tobytes(self, order='C'): return b'' + def tofile(self, fid, sep="", format="%s"): return None + def tolist(self, ): return [] + def tostring(self, order='C'): return b'' + def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None): return np.ndarray([0, 0]) + def transpose(self, *axes): return np.ndarray([0, 0]) + def var(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): return np.ndarray([0, 0]) + def view(self, dtype=None, type=None): return np.ndarray([0, 0]) + """ + node = astroid.extract_node(ndarray) + return node.infer(context=context) + + +def _looks_like_numpy_ndarray(node): + return isinstance(node, astroid.Attribute) and node.attrname == "ndarray" + + +astroid.MANAGER.register_transform( + astroid.Attribute, + astroid.inference_tip(infer_numpy_ndarray), + _looks_like_numpy_ndarray, +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_random_mtrand.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_random_mtrand.py new file mode 100644 index 0000000..772bfc4 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_random_mtrand.py @@ -0,0 +1,70 @@ +# Copyright (c) 2018-2019 hippo91 + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +# TODO(hippo91) : correct the functions return types +"""Astroid hooks for numpy.random.mtrand module.""" + +import astroid + + +def numpy_random_mtrand_transform(): + return astroid.parse( + """ + def beta(a, b, size=None): return uninferable + def binomial(n, p, size=None): return uninferable + def bytes(length): return uninferable + def chisquare(df, size=None): return uninferable + def choice(a, size=None, replace=True, p=None): return uninferable + def dirichlet(alpha, size=None): return uninferable + def exponential(scale=1.0, size=None): return uninferable + def f(dfnum, dfden, size=None): return uninferable + def gamma(shape, scale=1.0, size=None): return uninferable + def geometric(p, size=None): return uninferable + def get_state(): return uninferable + def gumbel(loc=0.0, scale=1.0, size=None): return uninferable + def hypergeometric(ngood, nbad, nsample, size=None): return uninferable + def laplace(loc=0.0, scale=1.0, size=None): return uninferable + def logistic(loc=0.0, scale=1.0, size=None): return uninferable + def lognormal(mean=0.0, sigma=1.0, size=None): return uninferable + def logseries(p, size=None): return uninferable + def multinomial(n, pvals, size=None): return uninferable + def multivariate_normal(mean, cov, size=None): return uninferable + def negative_binomial(n, p, size=None): return uninferable + def noncentral_chisquare(df, nonc, size=None): return uninferable + def noncentral_f(dfnum, dfden, nonc, size=None): return uninferable + def normal(loc=0.0, scale=1.0, size=None): return uninferable + def pareto(a, size=None): return uninferable + def permutation(x): return uninferable + def poisson(lam=1.0, size=None): return uninferable + def power(a, size=None): return uninferable + def rand(*args): return uninferable + def randint(low, high=None, size=None, dtype='l'): + import numpy + return numpy.ndarray((1,1)) + def randn(*args): return uninferable + def random_integers(low, high=None, size=None): return uninferable + def random_sample(size=None): return uninferable + def rayleigh(scale=1.0, size=None): return uninferable + def seed(seed=None): return uninferable + def set_state(state): return uninferable + def shuffle(x): return uninferable + def standard_cauchy(size=None): return uninferable + def standard_exponential(size=None): return uninferable + def standard_gamma(shape, size=None): return uninferable + def standard_normal(size=None): return uninferable + def standard_t(df, size=None): return uninferable + def triangular(left, mode, right, size=None): return uninferable + def uniform(low=0.0, high=1.0, size=None): return uninferable + def vonmises(mu, kappa, size=None): return uninferable + def wald(mean, scale, size=None): return uninferable + def weibull(a, size=None): return uninferable + def zipf(a, size=None): return uninferable + """ + ) + + +astroid.register_module_extender( + astroid.MANAGER, "numpy.random.mtrand", numpy_random_mtrand_transform +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_utils.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_utils.py new file mode 100644 index 0000000..2bad01e --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_numpy_utils.py @@ -0,0 +1,56 @@ +# Copyright (c) 2018-2019 hippo91 + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +"""Different utilities for the numpy brains""" + + +import astroid + + +def infer_numpy_member(src, node, context=None): + node = astroid.extract_node(src) + return node.infer(context=context) + + +def _is_a_numpy_module(node: astroid.node_classes.Name) -> bool: + """ + Returns True if the node is a representation of a numpy module. + + For example in : + import numpy as np + x = np.linspace(1, 2) + The node is a representation of the numpy module. + + :param node: node to test + :return: True if the node is a representation of the numpy module. + """ + module_nickname = node.name + potential_import_target = [ + x for x in node.lookup(module_nickname)[1] if isinstance(x, astroid.Import) + ] + for target in potential_import_target: + if ("numpy", module_nickname) in target.names: + return True + return False + + +def looks_like_numpy_member( + member_name: str, node: astroid.node_classes.NodeNG +) -> bool: + """ + Returns True if the node is a member of numpy whose + name is member_name. + + :param member_name: name of the member + :param node: node to test + :return: True if the node is a member of numpy + """ + return ( + isinstance(node, astroid.Attribute) + and node.attrname == member_name + and isinstance(node.expr, astroid.Name) + and _is_a_numpy_module(node.expr) + ) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_pkg_resources.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_pkg_resources.py new file mode 100644 index 0000000..25e7649 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_pkg_resources.py @@ -0,0 +1,75 @@ +# Copyright (c) 2016, 2018 Claudiu Popa +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +import astroid +from astroid import parse +from astroid import inference_tip +from astroid import register_module_extender +from astroid import MANAGER + + +def pkg_resources_transform(): + return parse( + """ +def require(*requirements): + return pkg_resources.working_set.require(*requirements) + +def run_script(requires, script_name): + return pkg_resources.working_set.run_script(requires, script_name) + +def iter_entry_points(group, name=None): + return pkg_resources.working_set.iter_entry_points(group, name) + +def resource_exists(package_or_requirement, resource_name): + return get_provider(package_or_requirement).has_resource(resource_name) + +def resource_isdir(package_or_requirement, resource_name): + return get_provider(package_or_requirement).resource_isdir( + resource_name) + +def resource_filename(package_or_requirement, resource_name): + return get_provider(package_or_requirement).get_resource_filename( + self, resource_name) + +def resource_stream(package_or_requirement, resource_name): + return get_provider(package_or_requirement).get_resource_stream( + self, resource_name) + +def resource_string(package_or_requirement, resource_name): + return get_provider(package_or_requirement).get_resource_string( + self, resource_name) + +def resource_listdir(package_or_requirement, resource_name): + return get_provider(package_or_requirement).resource_listdir( + resource_name) + +def extraction_error(): + pass + +def get_cache_path(archive_name, names=()): + extract_path = self.extraction_path or get_default_cache() + target_path = os.path.join(extract_path, archive_name+'-tmp', *names) + return target_path + +def postprocess(tempname, filename): + pass + +def set_extraction_path(path): + pass + +def cleanup_resources(force=False): + pass + +def get_distribution(dist): + return Distribution(dist) + +_namespace_packages = {} +""" + ) + + +register_module_extender(MANAGER, "pkg_resources", pkg_resources_transform) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_pytest.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_pytest.py new file mode 100644 index 0000000..d7e3ac8 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_pytest.py @@ -0,0 +1,88 @@ +# Copyright (c) 2014-2016 Claudiu Popa +# Copyright (c) 2014 Jeff Quast +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2016 Florian Bruhin +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for pytest.""" +from __future__ import absolute_import +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder + + +def pytest_transform(): + return AstroidBuilder(MANAGER).string_build( + """ + +try: + import _pytest.mark + import _pytest.recwarn + import _pytest.runner + import _pytest.python + import _pytest.skipping + import _pytest.assertion +except ImportError: + pass +else: + deprecated_call = _pytest.recwarn.deprecated_call + warns = _pytest.recwarn.warns + + exit = _pytest.runner.exit + fail = _pytest.runner.fail + skip = _pytest.runner.skip + importorskip = _pytest.runner.importorskip + + xfail = _pytest.skipping.xfail + mark = _pytest.mark.MarkGenerator() + raises = _pytest.python.raises + + # New in pytest 3.0 + try: + approx = _pytest.python.approx + register_assert_rewrite = _pytest.assertion.register_assert_rewrite + except AttributeError: + pass + + +# Moved in pytest 3.0 + +try: + import _pytest.freeze_support + freeze_includes = _pytest.freeze_support.freeze_includes +except ImportError: + try: + import _pytest.genscript + freeze_includes = _pytest.genscript.freeze_includes + except ImportError: + pass + +try: + import _pytest.debugging + set_trace = _pytest.debugging.pytestPDB().set_trace +except ImportError: + try: + import _pytest.pdb + set_trace = _pytest.pdb.pytestPDB().set_trace + except ImportError: + pass + +try: + import _pytest.fixtures + fixture = _pytest.fixtures.fixture + yield_fixture = _pytest.fixtures.yield_fixture +except ImportError: + try: + import _pytest.python + fixture = _pytest.python.fixture + yield_fixture = _pytest.python.yield_fixture + except ImportError: + pass +""" + ) + + +register_module_extender(MANAGER, "pytest", pytest_transform) +register_module_extender(MANAGER, "py.test", pytest_transform) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_qt.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_qt.py new file mode 100644 index 0000000..8679d14 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_qt.py @@ -0,0 +1,82 @@ +# Copyright (c) 2015-2016 Claudiu Popa +# Copyright (c) 2016 Ceridwen +# Copyright (c) 2017 Roy Wright +# Copyright (c) 2018 Ashley Whetter + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for the PyQT library.""" + +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder +from astroid import nodes +from astroid import parse + + +def _looks_like_signal(node, signal_name="pyqtSignal"): + if "__class__" in node.instance_attrs: + try: + cls = node.instance_attrs["__class__"][0] + return cls.name == signal_name + except AttributeError: + # return False if the cls does not have a name attribute + pass + return False + + +def transform_pyqt_signal(node): + module = parse( + """ + class pyqtSignal(object): + def connect(self, slot, type=None, no_receiver_check=False): + pass + def disconnect(self, slot): + pass + def emit(self, *args): + pass + """ + ) + signal_cls = module["pyqtSignal"] + node.instance_attrs["emit"] = signal_cls["emit"] + node.instance_attrs["disconnect"] = signal_cls["disconnect"] + node.instance_attrs["connect"] = signal_cls["connect"] + + +def transform_pyside_signal(node): + module = parse( + """ + class NotPySideSignal(object): + def connect(self, receiver, type=None): + pass + def disconnect(self, receiver): + pass + def emit(self, *args): + pass + """ + ) + signal_cls = module["NotPySideSignal"] + node.instance_attrs["connect"] = signal_cls["connect"] + node.instance_attrs["disconnect"] = signal_cls["disconnect"] + node.instance_attrs["emit"] = signal_cls["emit"] + + +def pyqt4_qtcore_transform(): + return AstroidBuilder(MANAGER).string_build( + """ + +def SIGNAL(signal_name): pass + +class QObject(object): + def emit(self, signal): pass +""" + ) + + +register_module_extender(MANAGER, "PyQt4.QtCore", pyqt4_qtcore_transform) +MANAGER.register_transform(nodes.FunctionDef, transform_pyqt_signal, _looks_like_signal) +MANAGER.register_transform( + nodes.ClassDef, + transform_pyside_signal, + lambda node: node.qname() in ("PySide.QtCore.Signal", "PySide2.QtCore.Signal"), +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_random.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_random.py new file mode 100644 index 0000000..5ec858a --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_random.py @@ -0,0 +1,75 @@ +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import random + +import astroid +from astroid import helpers +from astroid import MANAGER + + +ACCEPTED_ITERABLES_FOR_SAMPLE = (astroid.List, astroid.Set, astroid.Tuple) + + +def _clone_node_with_lineno(node, parent, lineno): + cls = node.__class__ + other_fields = node._other_fields + _astroid_fields = node._astroid_fields + init_params = {"lineno": lineno, "col_offset": node.col_offset, "parent": parent} + postinit_params = {param: getattr(node, param) for param in _astroid_fields} + if other_fields: + init_params.update({param: getattr(node, param) for param in other_fields}) + new_node = cls(**init_params) + if hasattr(node, "postinit") and _astroid_fields: + new_node.postinit(**postinit_params) + return new_node + + +def infer_random_sample(node, context=None): + if len(node.args) != 2: + raise astroid.UseInferenceDefault + + length = node.args[1] + if not isinstance(length, astroid.Const): + raise astroid.UseInferenceDefault + if not isinstance(length.value, int): + raise astroid.UseInferenceDefault + + inferred_sequence = helpers.safe_infer(node.args[0], context=context) + if not inferred_sequence: + raise astroid.UseInferenceDefault + + if not isinstance(inferred_sequence, ACCEPTED_ITERABLES_FOR_SAMPLE): + raise astroid.UseInferenceDefault + + if length.value > len(inferred_sequence.elts): + # In this case, this will raise a ValueError + raise astroid.UseInferenceDefault + + try: + elts = random.sample(inferred_sequence.elts, length.value) + except ValueError: + raise astroid.UseInferenceDefault + + new_node = astroid.List( + lineno=node.lineno, col_offset=node.col_offset, parent=node.scope() + ) + new_elts = [ + _clone_node_with_lineno(elt, parent=new_node, lineno=new_node.lineno) + for elt in elts + ] + new_node.postinit(new_elts) + return iter((new_node,)) + + +def _looks_like_random_sample(node): + func = node.func + if isinstance(func, astroid.Attribute): + return func.attrname == "sample" + if isinstance(func, astroid.Name): + return func.name == "sample" + return False + + +MANAGER.register_transform( + astroid.Call, astroid.inference_tip(infer_random_sample), _looks_like_random_sample +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_re.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_re.py new file mode 100644 index 0000000..c7ee51a --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_re.py @@ -0,0 +1,36 @@ +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import sys +import astroid + +PY36 = sys.version_info >= (3, 6) + +if PY36: + # Since Python 3.6 there is the RegexFlag enum + # where every entry will be exposed via updating globals() + + def _re_transform(): + return astroid.parse( + """ + import sre_compile + ASCII = sre_compile.SRE_FLAG_ASCII + IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE + LOCALE = sre_compile.SRE_FLAG_LOCALE + UNICODE = sre_compile.SRE_FLAG_UNICODE + MULTILINE = sre_compile.SRE_FLAG_MULTILINE + DOTALL = sre_compile.SRE_FLAG_DOTALL + VERBOSE = sre_compile.SRE_FLAG_VERBOSE + A = ASCII + I = IGNORECASE + L = LOCALE + U = UNICODE + M = MULTILINE + S = DOTALL + X = VERBOSE + TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE + T = TEMPLATE + DEBUG = sre_compile.SRE_FLAG_DEBUG + """ + ) + + astroid.register_module_extender(astroid.MANAGER, "re", _re_transform) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_six.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_six.py new file mode 100644 index 0000000..b342fbf --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_six.py @@ -0,0 +1,200 @@ +# Copyright (c) 2014-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +"""Astroid hooks for six module.""" + +from textwrap import dedent + +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder +from astroid.exceptions import ( + AstroidBuildingError, + InferenceError, + AttributeInferenceError, +) +from astroid import nodes + + +SIX_ADD_METACLASS = "six.add_metaclass" + + +def _indent(text, prefix, predicate=None): + """Adds 'prefix' to the beginning of selected lines in 'text'. + + If 'predicate' is provided, 'prefix' will only be added to the lines + where 'predicate(line)' is True. If 'predicate' is not provided, + it will default to adding 'prefix' to all non-empty lines that do not + consist solely of whitespace characters. + """ + if predicate is None: + predicate = lambda line: line.strip() + + def prefixed_lines(): + for line in text.splitlines(True): + yield prefix + line if predicate(line) else line + + return "".join(prefixed_lines()) + + +_IMPORTS = """ +import _io +cStringIO = _io.StringIO +filter = filter +from itertools import filterfalse +input = input +from sys import intern +map = map +range = range +from imp import reload as reload_module +from functools import reduce +from shlex import quote as shlex_quote +from io import StringIO +from collections import UserDict, UserList, UserString +xrange = range +zip = zip +from itertools import zip_longest +import builtins +import configparser +import copyreg +import _dummy_thread +import http.cookiejar as http_cookiejar +import http.cookies as http_cookies +import html.entities as html_entities +import html.parser as html_parser +import http.client as http_client +import http.server as http_server +BaseHTTPServer = CGIHTTPServer = SimpleHTTPServer = http.server +import pickle as cPickle +import queue +import reprlib +import socketserver +import _thread +import winreg +import xmlrpc.server as xmlrpc_server +import xmlrpc.client as xmlrpc_client +import urllib.robotparser as urllib_robotparser +import email.mime.multipart as email_mime_multipart +import email.mime.nonmultipart as email_mime_nonmultipart +import email.mime.text as email_mime_text +import email.mime.base as email_mime_base +import urllib.parse as urllib_parse +import urllib.error as urllib_error +import tkinter +import tkinter.dialog as tkinter_dialog +import tkinter.filedialog as tkinter_filedialog +import tkinter.scrolledtext as tkinter_scrolledtext +import tkinter.simpledialog as tkinder_simpledialog +import tkinter.tix as tkinter_tix +import tkinter.ttk as tkinter_ttk +import tkinter.constants as tkinter_constants +import tkinter.dnd as tkinter_dnd +import tkinter.colorchooser as tkinter_colorchooser +import tkinter.commondialog as tkinter_commondialog +import tkinter.filedialog as tkinter_tkfiledialog +import tkinter.font as tkinter_font +import tkinter.messagebox as tkinter_messagebox +import urllib +import urllib.request as urllib_request +import urllib.robotparser as urllib_robotparser +import urllib.parse as urllib_parse +import urllib.error as urllib_error +""" + + +def six_moves_transform(): + code = dedent( + """ + class Moves(object): + {} + moves = Moves() + """ + ).format(_indent(_IMPORTS, " ")) + module = AstroidBuilder(MANAGER).string_build(code) + module.name = "six.moves" + return module + + +def _six_fail_hook(modname): + """Fix six.moves imports due to the dynamic nature of this + class. + + Construct a pseudo-module which contains all the necessary imports + for six + + :param modname: Name of failed module + :type modname: str + + :return: An astroid module + :rtype: nodes.Module + """ + + attribute_of = modname != "six.moves" and modname.startswith("six.moves") + if modname != "six.moves" and not attribute_of: + raise AstroidBuildingError(modname=modname) + module = AstroidBuilder(MANAGER).string_build(_IMPORTS) + module.name = "six.moves" + if attribute_of: + # Facilitate import of submodules in Moves + start_index = len(module.name) + attribute = modname[start_index:].lstrip(".").replace(".", "_") + try: + import_attr = module.getattr(attribute)[0] + except AttributeInferenceError: + raise AstroidBuildingError(modname=modname) + if isinstance(import_attr, nodes.Import): + submodule = MANAGER.ast_from_module_name(import_attr.names[0][0]) + return submodule + # Let dummy submodule imports pass through + # This will cause an Uninferable result, which is okay + return module + + +def _looks_like_decorated_with_six_add_metaclass(node): + if not node.decorators: + return False + + for decorator in node.decorators.nodes: + if not isinstance(decorator, nodes.Call): + continue + if decorator.func.as_string() == SIX_ADD_METACLASS: + return True + return False + + +def transform_six_add_metaclass(node): + """Check if the given class node is decorated with *six.add_metaclass* + + If so, inject its argument as the metaclass of the underlying class. + """ + if not node.decorators: + return + + for decorator in node.decorators.nodes: + if not isinstance(decorator, nodes.Call): + continue + + try: + func = next(decorator.func.infer()) + except InferenceError: + continue + if func.qname() == SIX_ADD_METACLASS and decorator.args: + metaclass = decorator.args[0] + node._metaclass = metaclass + return node + + +register_module_extender(MANAGER, "six", six_moves_transform) +register_module_extender( + MANAGER, "requests.packages.urllib3.packages.six", six_moves_transform +) +MANAGER.register_failed_import_hook(_six_fail_hook) +MANAGER.register_transform( + nodes.ClassDef, + transform_six_add_metaclass, + _looks_like_decorated_with_six_add_metaclass, +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_ssl.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_ssl.py new file mode 100644 index 0000000..893d8a2 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_ssl.py @@ -0,0 +1,74 @@ +# Copyright (c) 2016 Claudiu Popa +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for the ssl library.""" + +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder +from astroid import nodes +from astroid import parse + + +def ssl_transform(): + return parse( + """ + from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION + from _ssl import _SSLContext, MemoryBIO + from _ssl import ( + SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError, + SSLSyscallError, SSLEOFError, + ) + from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED + from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj + from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes + try: + from _ssl import RAND_egd + except ImportError: + # LibreSSL does not provide RAND_egd + pass + from _ssl import (OP_ALL, OP_CIPHER_SERVER_PREFERENCE, + OP_NO_COMPRESSION, OP_NO_SSLv2, OP_NO_SSLv3, + OP_NO_TLSv1, OP_NO_TLSv1_1, OP_NO_TLSv1_2, + OP_SINGLE_DH_USE, OP_SINGLE_ECDH_USE) + + from _ssl import (ALERT_DESCRIPTION_ACCESS_DENIED, ALERT_DESCRIPTION_BAD_CERTIFICATE, + ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE, + ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE, + ALERT_DESCRIPTION_BAD_RECORD_MAC, + ALERT_DESCRIPTION_CERTIFICATE_EXPIRED, + ALERT_DESCRIPTION_CERTIFICATE_REVOKED, + ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN, + ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE, + ALERT_DESCRIPTION_CLOSE_NOTIFY, ALERT_DESCRIPTION_DECODE_ERROR, + ALERT_DESCRIPTION_DECOMPRESSION_FAILURE, + ALERT_DESCRIPTION_DECRYPT_ERROR, + ALERT_DESCRIPTION_HANDSHAKE_FAILURE, + ALERT_DESCRIPTION_ILLEGAL_PARAMETER, + ALERT_DESCRIPTION_INSUFFICIENT_SECURITY, + ALERT_DESCRIPTION_INTERNAL_ERROR, + ALERT_DESCRIPTION_NO_RENEGOTIATION, + ALERT_DESCRIPTION_PROTOCOL_VERSION, + ALERT_DESCRIPTION_RECORD_OVERFLOW, + ALERT_DESCRIPTION_UNEXPECTED_MESSAGE, + ALERT_DESCRIPTION_UNKNOWN_CA, + ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY, + ALERT_DESCRIPTION_UNRECOGNIZED_NAME, + ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE, + ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION, + ALERT_DESCRIPTION_USER_CANCELLED) + from _ssl import (SSL_ERROR_EOF, SSL_ERROR_INVALID_ERROR_CODE, SSL_ERROR_SSL, + SSL_ERROR_SYSCALL, SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_READ, + SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_X509_LOOKUP, SSL_ERROR_ZERO_RETURN) + from _ssl import VERIFY_CRL_CHECK_CHAIN, VERIFY_CRL_CHECK_LEAF, VERIFY_DEFAULT, VERIFY_X509_STRICT + from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN + from _ssl import _OPENSSL_API_VERSION + from _ssl import PROTOCOL_SSLv23, PROTOCOL_TLSv1, PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2 + from _ssl import PROTOCOL_TLS, PROTOCOL_TLS_CLIENT, PROTOCOL_TLS_SERVER + """ + ) + + +register_module_extender(MANAGER, "ssl", ssl_transform) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_subprocess.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_subprocess.py new file mode 100644 index 0000000..c14dc55 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_subprocess.py @@ -0,0 +1,111 @@ +# Copyright (c) 2016-2017 Claudiu Popa +# Copyright (c) 2017 Hugo +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +import sys +import textwrap + +import astroid + + +PY37 = sys.version_info >= (3, 7) +PY36 = sys.version_info >= (3, 6) + + +def _subprocess_transform(): + communicate = (bytes("string", "ascii"), bytes("string", "ascii")) + communicate_signature = "def communicate(self, input=None, timeout=None)" + if PY37: + init = """ + def __init__(self, args, bufsize=0, executable=None, + stdin=None, stdout=None, stderr=None, + preexec_fn=None, close_fds=False, shell=False, + cwd=None, env=None, universal_newlines=False, + startupinfo=None, creationflags=0, restore_signals=True, + start_new_session=False, pass_fds=(), *, + encoding=None, errors=None, text=None): + pass + """ + elif PY36: + init = """ + def __init__(self, args, bufsize=0, executable=None, + stdin=None, stdout=None, stderr=None, + preexec_fn=None, close_fds=False, shell=False, + cwd=None, env=None, universal_newlines=False, + startupinfo=None, creationflags=0, restore_signals=True, + start_new_session=False, pass_fds=(), *, + encoding=None, errors=None): + pass + """ + else: + init = """ + def __init__(self, args, bufsize=0, executable=None, + stdin=None, stdout=None, stderr=None, + preexec_fn=None, close_fds=False, shell=False, + cwd=None, env=None, universal_newlines=False, + startupinfo=None, creationflags=0, restore_signals=True, + start_new_session=False, pass_fds=()): + pass + """ + wait_signature = "def wait(self, timeout=None)" + ctx_manager = """ + def __enter__(self): return self + def __exit__(self, *args): pass + """ + py3_args = "args = []" + code = textwrap.dedent( + """ + def check_output( + args, *, + stdin=None, + stderr=None, + shell=False, + cwd=None, + encoding=None, + errors=None, + universal_newlines=False, + timeout=None, + env=None + ): + + if universal_newlines: + return "" + return b"" + class Popen(object): + returncode = pid = 0 + stdin = stdout = stderr = file() + %(py3_args)s + + %(communicate_signature)s: + return %(communicate)r + %(wait_signature)s: + return self.returncode + def poll(self): + return self.returncode + def send_signal(self, signal): + pass + def terminate(self): + pass + def kill(self): + pass + %(ctx_manager)s + """ + % { + "communicate": communicate, + "communicate_signature": communicate_signature, + "wait_signature": wait_signature, + "ctx_manager": ctx_manager, + "py3_args": py3_args, + } + ) + + init_lines = textwrap.dedent(init).splitlines() + indented_init = "\n".join(" " * 4 + line for line in init_lines) + code += indented_init + return astroid.parse(code) + + +astroid.register_module_extender(astroid.MANAGER, "subprocess", _subprocess_transform) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_threading.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_threading.py new file mode 100644 index 0000000..dffa55a --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_threading.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016 Claudiu Popa +# Copyright (c) 2017 Łukasz Rogalski + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import astroid + + +def _thread_transform(): + return astroid.parse( + """ + class lock(object): + def acquire(self, blocking=True, timeout=-1): + pass + def release(self): + pass + def __enter__(self): + return True + def __exit__(self, *args): + pass + def locked(self): + return False + + def Lock(): + return lock() + """ + ) + + +astroid.register_module_extender(astroid.MANAGER, "threading", _thread_transform) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_typing.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_typing.py new file mode 100644 index 0000000..9ff7227 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_typing.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2017-2018 Claudiu Popa +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2017 David Euresti +# Copyright (c) 2018 Bryce Guinta + +"""Astroid hooks for typing.py support.""" +import typing + +from astroid import ( + MANAGER, + UseInferenceDefault, + extract_node, + inference_tip, + nodes, + InferenceError, +) + + +TYPING_NAMEDTUPLE_BASENAMES = {"NamedTuple", "typing.NamedTuple"} +TYPING_TYPEVARS = {"TypeVar", "NewType"} +TYPING_TYPEVARS_QUALIFIED = {"typing.TypeVar", "typing.NewType"} +TYPING_TYPE_TEMPLATE = """ +class Meta(type): + def __getitem__(self, item): + return self + + @property + def __args__(self): + return () + +class {0}(metaclass=Meta): + pass +""" +TYPING_MEMBERS = set(typing.__all__) + + +def looks_like_typing_typevar_or_newtype(node): + func = node.func + if isinstance(func, nodes.Attribute): + return func.attrname in TYPING_TYPEVARS + if isinstance(func, nodes.Name): + return func.name in TYPING_TYPEVARS + return False + + +def infer_typing_typevar_or_newtype(node, context=None): + """Infer a typing.TypeVar(...) or typing.NewType(...) call""" + try: + func = next(node.func.infer(context=context)) + except InferenceError as exc: + raise UseInferenceDefault from exc + + if func.qname() not in TYPING_TYPEVARS_QUALIFIED: + raise UseInferenceDefault + if not node.args: + raise UseInferenceDefault + + typename = node.args[0].as_string().strip("'") + node = extract_node(TYPING_TYPE_TEMPLATE.format(typename)) + return node.infer(context=context) + + +def _looks_like_typing_subscript(node): + """Try to figure out if a Subscript node *might* be a typing-related subscript""" + if isinstance(node, nodes.Name): + return node.name in TYPING_MEMBERS + elif isinstance(node, nodes.Attribute): + return node.attrname in TYPING_MEMBERS + elif isinstance(node, nodes.Subscript): + return _looks_like_typing_subscript(node.value) + return False + + +def infer_typing_attr(node, context=None): + """Infer a typing.X[...] subscript""" + try: + value = next(node.value.infer()) + except InferenceError as exc: + raise UseInferenceDefault from exc + + if not value.qname().startswith("typing."): + raise UseInferenceDefault + + node = extract_node(TYPING_TYPE_TEMPLATE.format(value.qname().split(".")[-1])) + return node.infer(context=context) + + +MANAGER.register_transform( + nodes.Call, + inference_tip(infer_typing_typevar_or_newtype), + looks_like_typing_typevar_or_newtype, +) +MANAGER.register_transform( + nodes.Subscript, inference_tip(infer_typing_attr), _looks_like_typing_subscript +) diff --git a/py3/lib/python3.6/site-packages/astroid/brain/brain_uuid.py b/py3/lib/python3.6/site-packages/astroid/brain/brain_uuid.py new file mode 100644 index 0000000..8bda631 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/brain/brain_uuid.py @@ -0,0 +1,20 @@ +# Copyright (c) 2017 Claudiu Popa + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for the UUID module.""" + + +from astroid import MANAGER +from astroid import nodes + + +def _patch_uuid_class(node): + # The .int member is patched using __dict__ + node.locals["int"] = [nodes.Const(0, parent=node)] + + +MANAGER.register_transform( + nodes.ClassDef, _patch_uuid_class, lambda node: node.qname() == "uuid.UUID" +) diff --git a/py3/lib/python3.6/site-packages/astroid/builder.py b/py3/lib/python3.6/site-packages/astroid/builder.py new file mode 100644 index 0000000..ac71093 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/builder.py @@ -0,0 +1,435 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2013 Phil Schaf +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014-2015 Google, Inc. +# Copyright (c) 2014 Alexander Presnyakov +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2018 Anthony Sottile + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""The AstroidBuilder makes astroid from living object and / or from _ast + +The builder is not thread safe and can't be used to parse different sources +at the same time. +""" + +import os +import textwrap +from tokenize import detect_encoding + +from astroid._ast import _parse +from astroid import bases +from astroid import exceptions +from astroid import manager +from astroid import modutils +from astroid import raw_building +from astroid import rebuilder +from astroid import nodes +from astroid import util + +# The name of the transient function that is used to +# wrap expressions to be extracted when calling +# extract_node. +_TRANSIENT_FUNCTION = "__" + +# The comment used to select a statement to be extracted +# when calling extract_node. +_STATEMENT_SELECTOR = "#@" + +MANAGER = manager.AstroidManager() + + +def open_source_file(filename): + with open(filename, "rb") as byte_stream: + encoding = detect_encoding(byte_stream.readline)[0] + stream = open(filename, "r", newline=None, encoding=encoding) + data = stream.read() + return stream, encoding, data + + +def _can_assign_attr(node, attrname): + try: + slots = node.slots() + except NotImplementedError: + pass + else: + if slots and attrname not in {slot.value for slot in slots}: + return False + return True + + +class AstroidBuilder(raw_building.InspectBuilder): + """Class for building an astroid tree from source code or from a live module. + + The param *manager* specifies the manager class which should be used. + If no manager is given, then the default one will be used. The + param *apply_transforms* determines if the transforms should be + applied after the tree was built from source or from a live object, + by default being True. + """ + + # pylint: disable=redefined-outer-name + def __init__(self, manager=None, apply_transforms=True): + super(AstroidBuilder, self).__init__() + self._manager = manager or MANAGER + self._apply_transforms = apply_transforms + + def module_build(self, module, modname=None): + """Build an astroid from a living module instance.""" + node = None + path = getattr(module, "__file__", None) + if path is not None: + path_, ext = os.path.splitext(modutils._path_from_filename(path)) + if ext in (".py", ".pyc", ".pyo") and os.path.exists(path_ + ".py"): + node = self.file_build(path_ + ".py", modname) + if node is None: + # this is a built-in module + # get a partial representation by introspection + node = self.inspect_build(module, modname=modname, path=path) + if self._apply_transforms: + # We have to handle transformation by ourselves since the + # rebuilder isn't called for builtin nodes + node = self._manager.visit_transforms(node) + return node + + def file_build(self, path, modname=None): + """Build astroid from a source code file (i.e. from an ast) + + *path* is expected to be a python source file + """ + try: + stream, encoding, data = open_source_file(path) + except IOError as exc: + raise exceptions.AstroidBuildingError( + "Unable to load file {path}:\n{error}", + modname=modname, + path=path, + error=exc, + ) from exc + except (SyntaxError, LookupError) as exc: + raise exceptions.AstroidSyntaxError( + "Python 3 encoding specification error or unknown encoding:\n" + "{error}", + modname=modname, + path=path, + error=exc, + ) from exc + except UnicodeError as exc: # wrong encoding + # detect_encoding returns utf-8 if no encoding specified + raise exceptions.AstroidBuildingError( + "Wrong or no encoding specified for {filename}.", filename=path + ) from exc + with stream: + # get module name if necessary + if modname is None: + try: + modname = ".".join(modutils.modpath_from_file(path)) + except ImportError: + modname = os.path.splitext(os.path.basename(path))[0] + # build astroid representation + module = self._data_build(data, modname, path) + return self._post_build(module, encoding) + + def string_build(self, data, modname="", path=None): + """Build astroid from source code string.""" + module = self._data_build(data, modname, path) + module.file_bytes = data.encode("utf-8") + return self._post_build(module, "utf-8") + + def _post_build(self, module, encoding): + """Handles encoding and delayed nodes after a module has been built""" + module.file_encoding = encoding + self._manager.cache_module(module) + # post tree building steps after we stored the module in the cache: + for from_node in module._import_from_nodes: + if from_node.modname == "__future__": + for symbol, _ in from_node.names: + module.future_imports.add(symbol) + self.add_from_names_to_locals(from_node) + # handle delayed assattr nodes + for delayed in module._delayed_assattr: + self.delayed_assattr(delayed) + + # Visit the transforms + if self._apply_transforms: + module = self._manager.visit_transforms(module) + return module + + def _data_build(self, data, modname, path): + """Build tree node from data and add some informations""" + try: + node = _parse(data + "\n") + except (TypeError, ValueError, SyntaxError) as exc: + raise exceptions.AstroidSyntaxError( + "Parsing Python code failed:\n{error}", + source=data, + modname=modname, + path=path, + error=exc, + ) from exc + if path is not None: + node_file = os.path.abspath(path) + else: + node_file = "" + if modname.endswith(".__init__"): + modname = modname[:-9] + package = True + else: + package = ( + path is not None + and os.path.splitext(os.path.basename(path))[0] == "__init__" + ) + builder = rebuilder.TreeRebuilder(self._manager) + module = builder.visit_module(node, modname, node_file, package) + module._import_from_nodes = builder._import_from_nodes + module._delayed_assattr = builder._delayed_assattr + return module + + def add_from_names_to_locals(self, node): + """Store imported names to the locals + + Resort the locals if coming from a delayed node + """ + _key_func = lambda node: node.fromlineno + + def sort_locals(my_list): + my_list.sort(key=_key_func) + + for (name, asname) in node.names: + if name == "*": + try: + imported = node.do_import_module() + except exceptions.AstroidBuildingError: + continue + for name in imported.public_names(): + node.parent.set_local(name, node) + sort_locals(node.parent.scope().locals[name]) + else: + node.parent.set_local(asname or name, node) + sort_locals(node.parent.scope().locals[asname or name]) + + def delayed_assattr(self, node): + """Visit a AssAttr node + + This adds name to locals and handle members definition. + """ + try: + frame = node.frame() + for inferred in node.expr.infer(): + if inferred is util.Uninferable: + continue + try: + if inferred.__class__ is bases.Instance: + inferred = inferred._proxied + iattrs = inferred.instance_attrs + if not _can_assign_attr(inferred, node.attrname): + continue + elif isinstance(inferred, bases.Instance): + # Const, Tuple, ... we may be wrong, may be not, but + # anyway we don't want to pollute builtin's namespace + continue + elif inferred.is_function: + iattrs = inferred.instance_attrs + else: + iattrs = inferred.locals + except AttributeError: + # XXX log error + continue + values = iattrs.setdefault(node.attrname, []) + if node in values: + continue + # get assign in __init__ first XXX useful ? + if ( + frame.name == "__init__" + and values + and values[0].frame().name != "__init__" + ): + values.insert(0, node) + else: + values.append(node) + except exceptions.InferenceError: + pass + + +def build_namespace_package_module(name, path): + return nodes.Module(name, doc="", path=path, package=True) + + +def parse(code, module_name="", path=None, apply_transforms=True): + """Parses a source string in order to obtain an astroid AST from it + + :param str code: The code for the module. + :param str module_name: The name for the module, if any + :param str path: The path for the module + :param bool apply_transforms: + Apply the transforms for the give code. Use it if you + don't want the default transforms to be applied. + """ + code = textwrap.dedent(code) + builder = AstroidBuilder(manager=MANAGER, apply_transforms=apply_transforms) + return builder.string_build(code, modname=module_name, path=path) + + +def _extract_expressions(node): + """Find expressions in a call to _TRANSIENT_FUNCTION and extract them. + + The function walks the AST recursively to search for expressions that + are wrapped into a call to _TRANSIENT_FUNCTION. If it finds such an + expression, it completely removes the function call node from the tree, + replacing it by the wrapped expression inside the parent. + + :param node: An astroid node. + :type node: astroid.bases.NodeNG + :yields: The sequence of wrapped expressions on the modified tree + expression can be found. + """ + if ( + isinstance(node, nodes.Call) + and isinstance(node.func, nodes.Name) + and node.func.name == _TRANSIENT_FUNCTION + ): + real_expr = node.args[0] + real_expr.parent = node.parent + # Search for node in all _astng_fields (the fields checked when + # get_children is called) of its parent. Some of those fields may + # be lists or tuples, in which case the elements need to be checked. + # When we find it, replace it by real_expr, so that the AST looks + # like no call to _TRANSIENT_FUNCTION ever took place. + for name in node.parent._astroid_fields: + child = getattr(node.parent, name) + if isinstance(child, (list, tuple)): + for idx, compound_child in enumerate(child): + if compound_child is node: + child[idx] = real_expr + elif child is node: + setattr(node.parent, name, real_expr) + yield real_expr + else: + for child in node.get_children(): + yield from _extract_expressions(child) + + +def _find_statement_by_line(node, line): + """Extracts the statement on a specific line from an AST. + + If the line number of node matches line, it will be returned; + otherwise its children are iterated and the function is called + recursively. + + :param node: An astroid node. + :type node: astroid.bases.NodeNG + :param line: The line number of the statement to extract. + :type line: int + :returns: The statement on the line, or None if no statement for the line + can be found. + :rtype: astroid.bases.NodeNG or None + """ + if isinstance(node, (nodes.ClassDef, nodes.FunctionDef)): + # This is an inaccuracy in the AST: the nodes that can be + # decorated do not carry explicit information on which line + # the actual definition (class/def), but .fromline seems to + # be close enough. + node_line = node.fromlineno + else: + node_line = node.lineno + + if node_line == line: + return node + + for child in node.get_children(): + result = _find_statement_by_line(child, line) + if result: + return result + + return None + + +def extract_node(code, module_name=""): + """Parses some Python code as a module and extracts a designated AST node. + + Statements: + To extract one or more statement nodes, append #@ to the end of the line + + Examples: + >>> def x(): + >>> def y(): + >>> return 1 #@ + + The return statement will be extracted. + + >>> class X(object): + >>> def meth(self): #@ + >>> pass + + The function object 'meth' will be extracted. + + Expressions: + To extract arbitrary expressions, surround them with the fake + function call __(...). After parsing, the surrounded expression + will be returned and the whole AST (accessible via the returned + node's parent attribute) will look like the function call was + never there in the first place. + + Examples: + >>> a = __(1) + + The const node will be extracted. + + >>> def x(d=__(foo.bar)): pass + + The node containing the default argument will be extracted. + + >>> def foo(a, b): + >>> return 0 < __(len(a)) < b + + The node containing the function call 'len' will be extracted. + + If no statements or expressions are selected, the last toplevel + statement will be returned. + + If the selected statement is a discard statement, (i.e. an expression + turned into a statement), the wrapped expression is returned instead. + + For convenience, singleton lists are unpacked. + + :param str code: A piece of Python code that is parsed as + a module. Will be passed through textwrap.dedent first. + :param str module_name: The name of the module. + :returns: The designated node from the parse tree, or a list of nodes. + :rtype: astroid.bases.NodeNG, or a list of nodes. + """ + + def _extract(node): + if isinstance(node, nodes.Expr): + return node.value + + return node + + requested_lines = [] + for idx, line in enumerate(code.splitlines()): + if line.strip().endswith(_STATEMENT_SELECTOR): + requested_lines.append(idx + 1) + + tree = parse(code, module_name=module_name) + if not tree.body: + raise ValueError("Empty tree, cannot extract from it") + + extracted = [] + if requested_lines: + extracted = [_find_statement_by_line(tree, line) for line in requested_lines] + + # Modifies the tree. + extracted.extend(_extract_expressions(tree)) + + if not extracted: + extracted.append(tree.body[-1]) + + extracted = [_extract(node) for node in extracted] + if len(extracted) == 1: + return extracted[0] + return extracted diff --git a/py3/lib/python3.6/site-packages/astroid/context.py b/py3/lib/python3.6/site-packages/astroid/context.py new file mode 100644 index 0000000..70a9208 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/context.py @@ -0,0 +1,179 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Various context related utilities, including inference and call contexts.""" +import contextlib +import pprint +from typing import Optional + + +class InferenceContext: + """Provide context for inference + + Store already inferred nodes to save time + Account for already visited nodes to infinite stop infinite recursion + """ + + __slots__ = ( + "path", + "lookupname", + "callcontext", + "boundnode", + "inferred", + "extra_context", + ) + + def __init__(self, path=None, inferred=None): + self.path = path or set() + """ + :type: set(tuple(NodeNG, optional(str))) + + Path of visited nodes and their lookupname + + Currently this key is ``(node, context.lookupname)`` + """ + self.lookupname = None + """ + :type: optional[str] + + The original name of the node + + e.g. + foo = 1 + The inference of 'foo' is nodes.Const(1) but the lookup name is 'foo' + """ + self.callcontext = None + """ + :type: optional[CallContext] + + The call arguments and keywords for the given context + """ + self.boundnode = None + """ + :type: optional[NodeNG] + + The bound node of the given context + + e.g. the bound node of object.__new__(cls) is the object node + """ + self.inferred = inferred or {} + """ + :type: dict(seq, seq) + + Inferred node contexts to their mapped results + Currently the key is ``(node, lookupname, callcontext, boundnode)`` + and the value is tuple of the inferred results + """ + self.extra_context = {} + """ + :type: dict(NodeNG, Context) + + Context that needs to be passed down through call stacks + for call arguments + """ + + def push(self, node): + """Push node into inference path + + :return: True if node is already in context path else False + :rtype: bool + + Allows one to see if the given node has already + been looked at for this inference context""" + name = self.lookupname + if (node, name) in self.path: + return True + + self.path.add((node, name)) + return False + + def clone(self): + """Clone inference path + + For example, each side of a binary operation (BinOp) + starts with the same context but diverge as each side is inferred + so the InferenceContext will need be cloned""" + # XXX copy lookupname/callcontext ? + clone = InferenceContext(self.path, inferred=self.inferred) + clone.callcontext = self.callcontext + clone.boundnode = self.boundnode + clone.extra_context = self.extra_context + return clone + + def cache_generator(self, key, generator): + """Cache result of generator into dictionary + + Used to cache inference results""" + results = [] + for result in generator: + results.append(result) + yield result + + self.inferred[key] = tuple(results) + + @contextlib.contextmanager + def restore_path(self): + path = set(self.path) + yield + self.path = path + + def __str__(self): + state = ( + "%s=%s" + % (field, pprint.pformat(getattr(self, field), width=80 - len(field))) + for field in self.__slots__ + ) + return "%s(%s)" % (type(self).__name__, ",\n ".join(state)) + + +class CallContext: + """Holds information for a call site.""" + + __slots__ = ("args", "keywords") + + def __init__(self, args, keywords=None): + """ + :param List[NodeNG] args: Call positional arguments + :param Union[List[nodes.Keyword], None] keywords: Call keywords + """ + self.args = args + if keywords: + keywords = [(arg.arg, arg.value) for arg in keywords] + else: + keywords = [] + self.keywords = keywords + + +def copy_context(context: Optional[InferenceContext]) -> InferenceContext: + """Clone a context if given, or return a fresh contexxt""" + if context is not None: + return context.clone() + + return InferenceContext() + + +def bind_context_to_node(context, node): + """Give a context a boundnode + to retrieve the correct function name or attribute value + with from further inference. + + Do not use an existing context since the boundnode could then + be incorrectly propagated higher up in the call stack. + + :param context: Context to use + :type context: Optional(context) + + :param node: Node to do name lookups from + :type node NodeNG: + + :returns: A new context + :rtype: InferenceContext + """ + context = copy_context(context) + context.boundnode = node + return context diff --git a/py3/lib/python3.6/site-packages/astroid/decorators.py b/py3/lib/python3.6/site-packages/astroid/decorators.py new file mode 100644 index 0000000..1448757 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/decorators.py @@ -0,0 +1,141 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Ashley Whetter +# Copyright (c) 2018 HoverHell +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +""" A few useful function/method decorators.""" + +import functools + +import wrapt + +from astroid import context as contextmod +from astroid import exceptions +from astroid import util + + +@wrapt.decorator +def cached(func, instance, args, kwargs): + """Simple decorator to cache result of method calls without args.""" + cache = getattr(instance, "__cache", None) + if cache is None: + instance.__cache = cache = {} + try: + return cache[func] + except KeyError: + cache[func] = result = func(*args, **kwargs) + return result + + +class cachedproperty: + """ Provides a cached property equivalent to the stacking of + @cached and @property, but more efficient. + + After first usage, the becomes part of the object's + __dict__. Doing: + + del obj. empties the cache. + + Idea taken from the pyramid_ framework and the mercurial_ project. + + .. _pyramid: http://pypi.python.org/pypi/pyramid + .. _mercurial: http://pypi.python.org/pypi/Mercurial + """ + + __slots__ = ("wrapped",) + + def __init__(self, wrapped): + try: + wrapped.__name__ + except AttributeError as exc: + raise TypeError("%s must have a __name__ attribute" % wrapped) from exc + self.wrapped = wrapped + + @property + def __doc__(self): + doc = getattr(self.wrapped, "__doc__", None) + return "%s" % ( + "\n%s" % doc if doc else "" + ) + + def __get__(self, inst, objtype=None): + if inst is None: + return self + val = self.wrapped(inst) + setattr(inst, self.wrapped.__name__, val) + return val + + +def path_wrapper(func): + """return the given infer function wrapped to handle the path + + Used to stop inference if the node has already been looked + at for a given `InferenceContext` to prevent infinite recursion + """ + + @functools.wraps(func) + def wrapped(node, context=None, _func=func, **kwargs): + """wrapper function handling context""" + if context is None: + context = contextmod.InferenceContext() + if context.push(node): + return None + + yielded = set() + generator = _func(node, context, **kwargs) + try: + while True: + res = next(generator) + # unproxy only true instance, not const, tuple, dict... + if res.__class__.__name__ == "Instance": + ares = res._proxied + else: + ares = res + if ares not in yielded: + yield res + yielded.add(ares) + except StopIteration as error: + if error.args: + return error.args[0] + return None + + return wrapped + + +@wrapt.decorator +def yes_if_nothing_inferred(func, instance, args, kwargs): + generator = func(*args, **kwargs) + + try: + yield next(generator) + except StopIteration: + # generator is empty + yield util.Uninferable + return + + yield from generator + + +@wrapt.decorator +def raise_if_nothing_inferred(func, instance, args, kwargs): + generator = func(*args, **kwargs) + + try: + yield next(generator) + except StopIteration as error: + # generator is empty + if error.args: + # pylint: disable=not-a-mapping + raise exceptions.InferenceError(**error.args[0]) + raise exceptions.InferenceError( + "StopIteration raised without any error information." + ) + + yield from generator diff --git a/py3/lib/python3.6/site-packages/astroid/exceptions.py b/py3/lib/python3.6/site-packages/astroid/exceptions.py new file mode 100644 index 0000000..7e9d655 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/exceptions.py @@ -0,0 +1,230 @@ +# Copyright (c) 2007, 2009-2010, 2013 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015-2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""this module contains exceptions used in the astroid library +""" +from astroid import util + + +class AstroidError(Exception): + """base exception class for all astroid related exceptions + + AstroidError and its subclasses are structured, intended to hold + objects representing state when the exception is thrown. Field + values are passed to the constructor as keyword-only arguments. + Each subclass has its own set of standard fields, but use your + best judgment to decide whether a specific exception instance + needs more or fewer fields for debugging. Field values may be + used to lazily generate the error message: self.message.format() + will be called with the field names and values supplied as keyword + arguments. + """ + + def __init__(self, message="", **kws): + super(AstroidError, self).__init__(message) + self.message = message + for key, value in kws.items(): + setattr(self, key, value) + + def __str__(self): + return self.message.format(**vars(self)) + + +class AstroidBuildingError(AstroidError): + """exception class when we are unable to build an astroid representation + + Standard attributes: + modname: Name of the module that AST construction failed for. + error: Exception raised during construction. + """ + + def __init__(self, message="Failed to import module {modname}.", **kws): + super(AstroidBuildingError, self).__init__(message, **kws) + + +class AstroidImportError(AstroidBuildingError): + """Exception class used when a module can't be imported by astroid.""" + + +class TooManyLevelsError(AstroidImportError): + """Exception class which is raised when a relative import was beyond the top-level. + + Standard attributes: + level: The level which was attempted. + name: the name of the module on which the relative import was attempted. + """ + + level = None + name = None + + def __init__( + self, + message="Relative import with too many levels " "({level}) for module {name!r}", + **kws + ): + super(TooManyLevelsError, self).__init__(message, **kws) + + +class AstroidSyntaxError(AstroidBuildingError): + """Exception class used when a module can't be parsed.""" + + +class NoDefault(AstroidError): + """raised by function's `default_value` method when an argument has + no default value + + Standard attributes: + func: Function node. + name: Name of argument without a default. + """ + + func = None + name = None + + def __init__(self, message="{func!r} has no default for {name!r}.", **kws): + super(NoDefault, self).__init__(message, **kws) + + +class ResolveError(AstroidError): + """Base class of astroid resolution/inference error. + + ResolveError is not intended to be raised. + + Standard attributes: + context: InferenceContext object. + """ + + context = None + + +class MroError(ResolveError): + """Error raised when there is a problem with method resolution of a class. + + Standard attributes: + mros: A sequence of sequences containing ClassDef nodes. + cls: ClassDef node whose MRO resolution failed. + context: InferenceContext object. + """ + + mros = () + cls = None + + def __str__(self): + mro_names = ", ".join( + "({})".format(", ".join(b.name for b in m)) for m in self.mros + ) + return self.message.format(mros=mro_names, cls=self.cls) + + +class DuplicateBasesError(MroError): + """Error raised when there are duplicate bases in the same class bases.""" + + +class InconsistentMroError(MroError): + """Error raised when a class's MRO is inconsistent.""" + + +class SuperError(ResolveError): + """Error raised when there is a problem with a *super* call. + + Standard attributes: + *super_*: The Super instance that raised the exception. + context: InferenceContext object. + """ + + super_ = None + + def __str__(self): + return self.message.format(**vars(self.super_)) + + +class InferenceError(ResolveError): + """raised when we are unable to infer a node + + Standard attributes: + node: The node inference was called on. + context: InferenceContext object. + """ + + node = None + context = None + + def __init__(self, message="Inference failed for {node!r}.", **kws): + super(InferenceError, self).__init__(message, **kws) + + +# Why does this inherit from InferenceError rather than ResolveError? +# Changing it causes some inference tests to fail. +class NameInferenceError(InferenceError): + """Raised when a name lookup fails, corresponds to NameError. + + Standard attributes: + name: The name for which lookup failed, as a string. + scope: The node representing the scope in which the lookup occurred. + context: InferenceContext object. + """ + + name = None + scope = None + + def __init__(self, message="{name!r} not found in {scope!r}.", **kws): + super(NameInferenceError, self).__init__(message, **kws) + + +class AttributeInferenceError(ResolveError): + """Raised when an attribute lookup fails, corresponds to AttributeError. + + Standard attributes: + target: The node for which lookup failed. + attribute: The attribute for which lookup failed, as a string. + context: InferenceContext object. + """ + + target = None + attribute = None + + def __init__(self, message="{attribute!r} not found on {target!r}.", **kws): + super(AttributeInferenceError, self).__init__(message, **kws) + + +class UseInferenceDefault(Exception): + """exception to be raised in custom inference function to indicate that it + should go back to the default behaviour + """ + + +class _NonDeducibleTypeHierarchy(Exception): + """Raised when is_subtype / is_supertype can't deduce the relation between two types.""" + + +class AstroidIndexError(AstroidError): + """Raised when an Indexable / Mapping does not have an index / key.""" + + +class AstroidTypeError(AstroidError): + """Raised when a TypeError would be expected in Python code.""" + + +class InferenceOverwriteError(AstroidError): + """Raised when an inference tip is overwritten + + Currently only used for debugging. + """ + + +# Backwards-compatibility aliases +OperationError = util.BadOperationMessage +UnaryOperationError = util.BadUnaryOperationMessage +BinaryOperationError = util.BadBinaryOperationMessage + +SuperArgumentTypeError = SuperError +UnresolvableName = NameInferenceError +NotFoundError = AttributeInferenceError +AstroidBuildingException = AstroidBuildingError diff --git a/py3/lib/python3.6/site-packages/astroid/helpers.py b/py3/lib/python3.6/site-packages/astroid/helpers.py new file mode 100644 index 0000000..be133b3 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/helpers.py @@ -0,0 +1,273 @@ +# Copyright (c) 2015-2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +""" +Various helper utilities. +""" + +import builtins as builtins_mod + +from astroid import bases +from astroid import context as contextmod +from astroid import exceptions +from astroid import manager +from astroid import nodes +from astroid import raw_building +from astroid import scoped_nodes +from astroid import util + + +BUILTINS = builtins_mod.__name__ + + +def _build_proxy_class(cls_name, builtins): + proxy = raw_building.build_class(cls_name) + proxy.parent = builtins + return proxy + + +def _function_type(function, builtins): + if isinstance(function, scoped_nodes.Lambda): + if function.root().name == BUILTINS: + cls_name = "builtin_function_or_method" + else: + cls_name = "function" + elif isinstance(function, bases.BoundMethod): + cls_name = "method" + elif isinstance(function, bases.UnboundMethod): + cls_name = "function" + return _build_proxy_class(cls_name, builtins) + + +def _object_type(node, context=None): + astroid_manager = manager.AstroidManager() + builtins = astroid_manager.builtins_module + context = context or contextmod.InferenceContext() + + for inferred in node.infer(context=context): + if isinstance(inferred, scoped_nodes.ClassDef): + if inferred.newstyle: + metaclass = inferred.metaclass(context=context) + if metaclass: + yield metaclass + continue + yield builtins.getattr("type")[0] + elif isinstance(inferred, (scoped_nodes.Lambda, bases.UnboundMethod)): + yield _function_type(inferred, builtins) + elif isinstance(inferred, scoped_nodes.Module): + yield _build_proxy_class("module", builtins) + else: + yield inferred._proxied + + +def object_type(node, context=None): + """Obtain the type of the given node + + This is used to implement the ``type`` builtin, which means that it's + used for inferring type calls, as well as used in a couple of other places + in the inference. + The node will be inferred first, so this function can support all + sorts of objects, as long as they support inference. + """ + + try: + types = set(_object_type(node, context)) + except exceptions.InferenceError: + return util.Uninferable + if len(types) > 1 or not types: + return util.Uninferable + return list(types)[0] + + +def _object_type_is_subclass(obj_type, class_or_seq, context=None): + if not isinstance(class_or_seq, (tuple, list)): + class_seq = (class_or_seq,) + else: + class_seq = class_or_seq + + if obj_type is util.Uninferable: + return util.Uninferable + + # Instances are not types + class_seq = [ + item if not isinstance(item, bases.Instance) else util.Uninferable + for item in class_seq + ] + # strict compatibility with issubclass + # issubclass(type, (object, 1)) evaluates to true + # issubclass(object, (1, type)) raises TypeError + for klass in class_seq: + if klass is util.Uninferable: + raise exceptions.AstroidTypeError("arg 2 must be a type or tuple of types") + + for obj_subclass in obj_type.mro(): + if obj_subclass == klass: + return True + return False + + +def object_isinstance(node, class_or_seq, context=None): + """Check if a node 'isinstance' any node in class_or_seq + + :param node: A given node + :param class_or_seq: Union[nodes.NodeNG, Sequence[nodes.NodeNG]] + :rtype: bool + + :raises AstroidTypeError: if the given ``classes_or_seq`` are not types + """ + obj_type = object_type(node, context) + if obj_type is util.Uninferable: + return util.Uninferable + return _object_type_is_subclass(obj_type, class_or_seq, context=context) + + +def object_issubclass(node, class_or_seq, context=None): + """Check if a type is a subclass of any node in class_or_seq + + :param node: A given node + :param class_or_seq: Union[Nodes.NodeNG, Sequence[nodes.NodeNG]] + :rtype: bool + + :raises AstroidTypeError: if the given ``classes_or_seq`` are not types + :raises AstroidError: if the type of the given node cannot be inferred + or its type's mro doesn't work + """ + if not isinstance(node, nodes.ClassDef): + raise TypeError("{node} needs to be a ClassDef node".format(node=node)) + return _object_type_is_subclass(node, class_or_seq, context=context) + + +def safe_infer(node, context=None): + """Return the inferred value for the given node. + + Return None if inference failed or if there is some ambiguity (more than + one node has been inferred). + """ + try: + inferit = node.infer(context=context) + value = next(inferit) + except exceptions.InferenceError: + return None + try: + next(inferit) + return None # None if there is ambiguity on the inferred node + except exceptions.InferenceError: + return None # there is some kind of ambiguity + except StopIteration: + return value + + +def has_known_bases(klass, context=None): + """Return true if all base classes of a class could be inferred.""" + try: + return klass._all_bases_known + except AttributeError: + pass + for base in klass.bases: + result = safe_infer(base, context=context) + # TODO: check for A->B->A->B pattern in class structure too? + if ( + not isinstance(result, scoped_nodes.ClassDef) + or result is klass + or not has_known_bases(result, context=context) + ): + klass._all_bases_known = False + return False + klass._all_bases_known = True + return True + + +def _type_check(type1, type2): + if not all(map(has_known_bases, (type1, type2))): + raise exceptions._NonDeducibleTypeHierarchy + + if not all([type1.newstyle, type2.newstyle]): + return False + try: + return type1 in type2.mro()[:-1] + except exceptions.MroError: + # The MRO is invalid. + raise exceptions._NonDeducibleTypeHierarchy + + +def is_subtype(type1, type2): + """Check if *type1* is a subtype of *type2*.""" + return _type_check(type1=type2, type2=type1) + + +def is_supertype(type1, type2): + """Check if *type2* is a supertype of *type1*.""" + return _type_check(type1, type2) + + +def class_instance_as_index(node): + """Get the value as an index for the given instance. + + If an instance provides an __index__ method, then it can + be used in some scenarios where an integer is expected, + for instance when multiplying or subscripting a list. + """ + context = contextmod.InferenceContext() + context.callcontext = contextmod.CallContext(args=[node]) + + try: + for inferred in node.igetattr("__index__", context=context): + if not isinstance(inferred, bases.BoundMethod): + continue + + for result in inferred.infer_call_result(node, context=context): + if isinstance(result, nodes.Const) and isinstance(result.value, int): + return result + except exceptions.InferenceError: + pass + return None + + +def object_len(node, context=None): + """Infer length of given node object + + :param Union[nodes.ClassDef, nodes.Instance] node: + :param node: Node to infer length of + + :raises AstroidTypeError: If an invalid node is returned + from __len__ method or no __len__ method exists + :raises InferenceError: If the given node cannot be inferred + or if multiple nodes are inferred + :rtype int: Integer length of node + """ + # pylint: disable=import-outside-toplevel; circular import + from astroid.objects import FrozenSet + + inferred_node = safe_infer(node, context=context) + if inferred_node is None or inferred_node is util.Uninferable: + raise exceptions.InferenceError(node=node) + if isinstance(inferred_node, nodes.Const) and isinstance( + inferred_node.value, (bytes, str) + ): + return len(inferred_node.value) + if isinstance(inferred_node, (nodes.List, nodes.Set, nodes.Tuple, FrozenSet)): + return len(inferred_node.elts) + if isinstance(inferred_node, nodes.Dict): + return len(inferred_node.items) + try: + node_type = object_type(inferred_node, context=context) + len_call = next(node_type.igetattr("__len__", context=context)) + except exceptions.AttributeInferenceError: + raise exceptions.AstroidTypeError( + "object of type '{}' has no len()".format(len_call.pytype()) + ) + + result_of_len = next(len_call.infer_call_result(node, context)) + if ( + isinstance(result_of_len, nodes.Const) + and result_of_len.pytype() == "builtins.int" + ): + return result_of_len.value + raise exceptions.AstroidTypeError( + "'{}' object cannot be interpreted as an integer".format(result_of_len) + ) diff --git a/py3/lib/python3.6/site-packages/astroid/inference.py b/py3/lib/python3.6/site-packages/astroid/inference.py new file mode 100644 index 0000000..77c6b1d --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/inference.py @@ -0,0 +1,943 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2012 FELD Boris +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Dmitry Pribysh +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2017 Michał Masłowski +# Copyright (c) 2017 Calen Pennington +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Ashley Whetter +# Copyright (c) 2018 HoverHell + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""this module contains a set of functions to handle inference on astroid trees +""" + +import functools +import itertools +import operator + +from astroid import bases +from astroid import context as contextmod +from astroid import exceptions +from astroid import decorators +from astroid import helpers +from astroid import manager +from astroid import nodes +from astroid.interpreter import dunder_lookup +from astroid import protocols +from astroid import util + + +MANAGER = manager.AstroidManager() + + +# .infer method ############################################################### + + +def infer_end(self, context=None): + """inference's end for node such as Module, ClassDef, FunctionDef, + Const... + + """ + yield self + + +nodes.Module._infer = infer_end +nodes.ClassDef._infer = infer_end +nodes.FunctionDef._infer = infer_end +nodes.Lambda._infer = infer_end +nodes.Const._infer = infer_end +nodes.Slice._infer = infer_end + + +def _infer_sequence_helper(node, context=None): + """Infer all values based on _BaseContainer.elts""" + values = [] + + for elt in node.elts: + if isinstance(elt, nodes.Starred): + starred = helpers.safe_infer(elt.value, context) + if not starred: + raise exceptions.InferenceError(node=node, context=context) + if not hasattr(starred, "elts"): + raise exceptions.InferenceError(node=node, context=context) + values.extend(_infer_sequence_helper(starred)) + elif isinstance(elt, nodes.NamedExpr): + value = helpers.safe_infer(elt.value, context) + if not value: + raise exceptions.InferenceError(node=node, context=context) + values.append(value) + else: + values.append(elt) + return values + + +@decorators.raise_if_nothing_inferred +def infer_sequence(self, context=None): + has_starred_named_expr = any( + isinstance(e, (nodes.Starred, nodes.NamedExpr)) for e in self.elts + ) + if has_starred_named_expr: + values = _infer_sequence_helper(self, context) + new_seq = type(self)( + lineno=self.lineno, col_offset=self.col_offset, parent=self.parent + ) + new_seq.postinit(values) + + yield new_seq + else: + yield self + + +nodes.List._infer = infer_sequence +nodes.Tuple._infer = infer_sequence +nodes.Set._infer = infer_sequence + + +def infer_map(self, context=None): + if not any(isinstance(k, nodes.DictUnpack) for k, _ in self.items): + yield self + else: + items = _infer_map(self, context) + new_seq = type(self)(self.lineno, self.col_offset, self.parent) + new_seq.postinit(list(items.items())) + yield new_seq + + +def _update_with_replacement(lhs_dict, rhs_dict): + """Delete nodes that equate to duplicate keys + + Since an astroid node doesn't 'equal' another node with the same value, + this function uses the as_string method to make sure duplicate keys + don't get through + + Note that both the key and the value are astroid nodes + + Fixes issue with DictUnpack causing duplicte keys + in inferred Dict items + + :param dict(nodes.NodeNG, nodes.NodeNG) lhs_dict: Dictionary to 'merge' nodes into + :param dict(nodes.NodeNG, nodes.NodeNG) rhs_dict: Dictionary with nodes to pull from + :return dict(nodes.NodeNG, nodes.NodeNG): merged dictionary of nodes + """ + combined_dict = itertools.chain(lhs_dict.items(), rhs_dict.items()) + # Overwrite keys which have the same string values + string_map = {key.as_string(): (key, value) for key, value in combined_dict} + # Return to dictionary + return dict(string_map.values()) + + +def _infer_map(node, context): + """Infer all values based on Dict.items""" + values = {} + for name, value in node.items: + if isinstance(name, nodes.DictUnpack): + double_starred = helpers.safe_infer(value, context) + if not double_starred: + raise exceptions.InferenceError + if not isinstance(double_starred, nodes.Dict): + raise exceptions.InferenceError(node=node, context=context) + unpack_items = _infer_map(double_starred, context) + values = _update_with_replacement(values, unpack_items) + else: + key = helpers.safe_infer(name, context=context) + value = helpers.safe_infer(value, context=context) + if any(not elem for elem in (key, value)): + raise exceptions.InferenceError(node=node, context=context) + values = _update_with_replacement(values, {key: value}) + return values + + +nodes.Dict._infer = infer_map + + +def _higher_function_scope(node): + """ Search for the first function which encloses the given + scope. This can be used for looking up in that function's + scope, in case looking up in a lower scope for a particular + name fails. + + :param node: A scope node. + :returns: + ``None``, if no parent function scope was found, + otherwise an instance of :class:`astroid.scoped_nodes.Function`, + which encloses the given node. + """ + current = node + while current.parent and not isinstance(current.parent, nodes.FunctionDef): + current = current.parent + if current and current.parent: + return current.parent + return None + + +def infer_name(self, context=None): + """infer a Name: use name lookup rules""" + frame, stmts = self.lookup(self.name) + if not stmts: + # Try to see if the name is enclosed in a nested function + # and use the higher (first function) scope for searching. + parent_function = _higher_function_scope(self.scope()) + if parent_function: + _, stmts = parent_function.lookup(self.name) + + if not stmts: + raise exceptions.NameInferenceError( + name=self.name, scope=self.scope(), context=context + ) + context = contextmod.copy_context(context) + context.lookupname = self.name + return bases._infer_stmts(stmts, context, frame) + + +# pylint: disable=no-value-for-parameter +nodes.Name._infer = decorators.raise_if_nothing_inferred( + decorators.path_wrapper(infer_name) +) +nodes.AssignName.infer_lhs = infer_name # won't work with a path wrapper + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_call(self, context=None): + """infer a Call node by trying to guess what the function returns""" + callcontext = contextmod.copy_context(context) + callcontext.callcontext = contextmod.CallContext( + args=self.args, keywords=self.keywords + ) + callcontext.boundnode = None + if context is not None: + callcontext.extra_context = _populate_context_lookup(self, context.clone()) + + for callee in self.func.infer(context): + if callee is util.Uninferable: + yield callee + continue + try: + if hasattr(callee, "infer_call_result"): + yield from callee.infer_call_result(caller=self, context=callcontext) + except exceptions.InferenceError: + continue + return dict(node=self, context=context) + + +nodes.Call._infer = infer_call + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_import(self, context=None, asname=True): + """infer an Import node: return the imported module/object""" + name = context.lookupname + if name is None: + raise exceptions.InferenceError(node=self, context=context) + + try: + if asname: + yield self.do_import_module(self.real_name(name)) + else: + yield self.do_import_module(name) + except exceptions.AstroidBuildingError as exc: + raise exceptions.InferenceError(node=self, context=context) from exc + + +nodes.Import._infer = infer_import + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_import_from(self, context=None, asname=True): + """infer a ImportFrom node: return the imported module/object""" + name = context.lookupname + if name is None: + raise exceptions.InferenceError(node=self, context=context) + if asname: + name = self.real_name(name) + + try: + module = self.do_import_module() + except exceptions.AstroidBuildingError as exc: + raise exceptions.InferenceError(node=self, context=context) from exc + + try: + context = contextmod.copy_context(context) + context.lookupname = name + stmts = module.getattr(name, ignore_locals=module is self.root()) + return bases._infer_stmts(stmts, context) + except exceptions.AttributeInferenceError as error: + raise exceptions.InferenceError( + error.message, target=self, attribute=name, context=context + ) from error + + +nodes.ImportFrom._infer = infer_import_from + + +def infer_attribute(self, context=None): + """infer an Attribute node by using getattr on the associated object""" + for owner in self.expr.infer(context): + if owner is util.Uninferable: + yield owner + continue + + if context and context.boundnode: + # This handles the situation where the attribute is accessed through a subclass + # of a base class and the attribute is defined at the base class's level, + # by taking in consideration a redefinition in the subclass. + if isinstance(owner, bases.Instance) and isinstance( + context.boundnode, bases.Instance + ): + try: + if helpers.is_subtype( + helpers.object_type(context.boundnode), + helpers.object_type(owner), + ): + owner = context.boundnode + except exceptions._NonDeducibleTypeHierarchy: + # Can't determine anything useful. + pass + + try: + context.boundnode = owner + yield from owner.igetattr(self.attrname, context) + context.boundnode = None + except (exceptions.AttributeInferenceError, exceptions.InferenceError): + context.boundnode = None + except AttributeError: + # XXX method / function + context.boundnode = None + return dict(node=self, context=context) + + +nodes.Attribute._infer = decorators.raise_if_nothing_inferred( + decorators.path_wrapper(infer_attribute) +) +# won't work with a path wrapper +nodes.AssignAttr.infer_lhs = decorators.raise_if_nothing_inferred(infer_attribute) + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_global(self, context=None): + if context.lookupname is None: + raise exceptions.InferenceError(node=self, context=context) + try: + return bases._infer_stmts(self.root().getattr(context.lookupname), context) + except exceptions.AttributeInferenceError as error: + raise exceptions.InferenceError( + error.message, target=self, attribute=context.lookupname, context=context + ) from error + + +nodes.Global._infer = infer_global + + +_SUBSCRIPT_SENTINEL = object() + + +@decorators.raise_if_nothing_inferred +def infer_subscript(self, context=None): + """Inference for subscripts + + We're understanding if the index is a Const + or a slice, passing the result of inference + to the value's `getitem` method, which should + handle each supported index type accordingly. + """ + + found_one = False + for value in self.value.infer(context): + if value is util.Uninferable: + yield util.Uninferable + return None + for index in self.slice.infer(context): + if index is util.Uninferable: + yield util.Uninferable + return None + + # Try to deduce the index value. + index_value = _SUBSCRIPT_SENTINEL + if value.__class__ == bases.Instance: + index_value = index + else: + if index.__class__ == bases.Instance: + instance_as_index = helpers.class_instance_as_index(index) + if instance_as_index: + index_value = instance_as_index + else: + index_value = index + if index_value is _SUBSCRIPT_SENTINEL: + raise exceptions.InferenceError(node=self, context=context) + + try: + assigned = value.getitem(index_value, context) + except ( + exceptions.AstroidTypeError, + exceptions.AstroidIndexError, + exceptions.AttributeInferenceError, + AttributeError, + ) as exc: + raise exceptions.InferenceError(node=self, context=context) from exc + + # Prevent inferring if the inferred subscript + # is the same as the original subscripted object. + if self is assigned or assigned is util.Uninferable: + yield util.Uninferable + return None + yield from assigned.infer(context) + found_one = True + + if found_one: + return dict(node=self, context=context) + return None + + +nodes.Subscript._infer = decorators.path_wrapper(infer_subscript) +nodes.Subscript.infer_lhs = infer_subscript + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def _infer_boolop(self, context=None): + """Infer a boolean operation (and / or / not). + + The function will calculate the boolean operation + for all pairs generated through inference for each component + node. + """ + values = self.values + if self.op == "or": + predicate = operator.truth + else: + predicate = operator.not_ + + try: + values = [value.infer(context=context) for value in values] + except exceptions.InferenceError: + yield util.Uninferable + return None + + for pair in itertools.product(*values): + if any(item is util.Uninferable for item in pair): + # Can't infer the final result, just yield Uninferable. + yield util.Uninferable + continue + + bool_values = [item.bool_value() for item in pair] + if any(item is util.Uninferable for item in bool_values): + # Can't infer the final result, just yield Uninferable. + yield util.Uninferable + continue + + # Since the boolean operations are short circuited operations, + # this code yields the first value for which the predicate is True + # and if no value respected the predicate, then the last value will + # be returned (or Uninferable if there was no last value). + # This is conforming to the semantics of `and` and `or`: + # 1 and 0 -> 1 + # 0 and 1 -> 0 + # 1 or 0 -> 1 + # 0 or 1 -> 1 + value = util.Uninferable + for value, bool_value in zip(pair, bool_values): + if predicate(bool_value): + yield value + break + else: + yield value + + return dict(node=self, context=context) + + +nodes.BoolOp._infer = _infer_boolop + + +# UnaryOp, BinOp and AugAssign inferences + + +def _filter_operation_errors(self, infer_callable, context, error): + for result in infer_callable(self, context): + if isinstance(result, error): + # For the sake of .infer(), we don't care about operation + # errors, which is the job of pylint. So return something + # which shows that we can't infer the result. + yield util.Uninferable + else: + yield result + + +def _infer_unaryop(self, context=None): + """Infer what an UnaryOp should return when evaluated.""" + for operand in self.operand.infer(context): + try: + yield operand.infer_unary_op(self.op) + except TypeError as exc: + # The operand doesn't support this operation. + yield util.BadUnaryOperationMessage(operand, self.op, exc) + except AttributeError as exc: + meth = protocols.UNARY_OP_METHOD[self.op] + if meth is None: + # `not node`. Determine node's boolean + # value and negate its result, unless it is + # Uninferable, which will be returned as is. + bool_value = operand.bool_value() + if bool_value is not util.Uninferable: + yield nodes.const_factory(not bool_value) + else: + yield util.Uninferable + else: + if not isinstance(operand, (bases.Instance, nodes.ClassDef)): + # The operation was used on something which + # doesn't support it. + yield util.BadUnaryOperationMessage(operand, self.op, exc) + continue + + try: + try: + methods = dunder_lookup.lookup(operand, meth) + except exceptions.AttributeInferenceError: + yield util.BadUnaryOperationMessage(operand, self.op, exc) + continue + + meth = methods[0] + inferred = next(meth.infer(context=context)) + if inferred is util.Uninferable or not inferred.callable(): + continue + + context = contextmod.copy_context(context) + context.callcontext = contextmod.CallContext(args=[operand]) + call_results = inferred.infer_call_result(self, context=context) + result = next(call_results, None) + if result is None: + # Failed to infer, return the same type. + yield operand + else: + yield result + except exceptions.AttributeInferenceError as exc: + # The unary operation special method was not found. + yield util.BadUnaryOperationMessage(operand, self.op, exc) + except exceptions.InferenceError: + yield util.Uninferable + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_unaryop(self, context=None): + """Infer what an UnaryOp should return when evaluated.""" + yield from _filter_operation_errors( + self, _infer_unaryop, context, util.BadUnaryOperationMessage + ) + return dict(node=self, context=context) + + +nodes.UnaryOp._infer_unaryop = _infer_unaryop +nodes.UnaryOp._infer = infer_unaryop + + +def _is_not_implemented(const): + """Check if the given const node is NotImplemented.""" + return isinstance(const, nodes.Const) and const.value is NotImplemented + + +def _invoke_binop_inference(instance, opnode, op, other, context, method_name): + """Invoke binary operation inference on the given instance.""" + methods = dunder_lookup.lookup(instance, method_name) + context = contextmod.bind_context_to_node(context, instance) + method = methods[0] + inferred = next(method.infer(context=context)) + if inferred is util.Uninferable: + raise exceptions.InferenceError + return instance.infer_binary_op(opnode, op, other, context, inferred) + + +def _aug_op(instance, opnode, op, other, context, reverse=False): + """Get an inference callable for an augmented binary operation.""" + method_name = protocols.AUGMENTED_OP_METHOD[op] + return functools.partial( + _invoke_binop_inference, + instance=instance, + op=op, + opnode=opnode, + other=other, + context=context, + method_name=method_name, + ) + + +def _bin_op(instance, opnode, op, other, context, reverse=False): + """Get an inference callable for a normal binary operation. + + If *reverse* is True, then the reflected method will be used instead. + """ + if reverse: + method_name = protocols.REFLECTED_BIN_OP_METHOD[op] + else: + method_name = protocols.BIN_OP_METHOD[op] + return functools.partial( + _invoke_binop_inference, + instance=instance, + op=op, + opnode=opnode, + other=other, + context=context, + method_name=method_name, + ) + + +def _get_binop_contexts(context, left, right): + """Get contexts for binary operations. + + This will return two inference contexts, the first one + for x.__op__(y), the other one for y.__rop__(x), where + only the arguments are inversed. + """ + # The order is important, since the first one should be + # left.__op__(right). + for arg in (right, left): + new_context = context.clone() + new_context.callcontext = contextmod.CallContext(args=[arg]) + new_context.boundnode = None + yield new_context + + +def _same_type(type1, type2): + """Check if type1 is the same as type2.""" + return type1.qname() == type2.qname() + + +def _get_binop_flow( + left, left_type, binary_opnode, right, right_type, context, reverse_context +): + """Get the flow for binary operations. + + The rules are a bit messy: + + * if left and right have the same type, then only one + method will be called, left.__op__(right) + * if left and right are unrelated typewise, then first + left.__op__(right) is tried and if this does not exist + or returns NotImplemented, then right.__rop__(left) is tried. + * if left is a subtype of right, then only left.__op__(right) + is tried. + * if left is a supertype of right, then right.__rop__(left) + is first tried and then left.__op__(right) + """ + op = binary_opnode.op + if _same_type(left_type, right_type): + methods = [_bin_op(left, binary_opnode, op, right, context)] + elif helpers.is_subtype(left_type, right_type): + methods = [_bin_op(left, binary_opnode, op, right, context)] + elif helpers.is_supertype(left_type, right_type): + methods = [ + _bin_op(right, binary_opnode, op, left, reverse_context, reverse=True), + _bin_op(left, binary_opnode, op, right, context), + ] + else: + methods = [ + _bin_op(left, binary_opnode, op, right, context), + _bin_op(right, binary_opnode, op, left, reverse_context, reverse=True), + ] + return methods + + +def _get_aug_flow( + left, left_type, aug_opnode, right, right_type, context, reverse_context +): + """Get the flow for augmented binary operations. + + The rules are a bit messy: + + * if left and right have the same type, then left.__augop__(right) + is first tried and then left.__op__(right). + * if left and right are unrelated typewise, then + left.__augop__(right) is tried, then left.__op__(right) + is tried and then right.__rop__(left) is tried. + * if left is a subtype of right, then left.__augop__(right) + is tried and then left.__op__(right). + * if left is a supertype of right, then left.__augop__(right) + is tried, then right.__rop__(left) and then + left.__op__(right) + """ + bin_op = aug_opnode.op.strip("=") + aug_op = aug_opnode.op + if _same_type(left_type, right_type): + methods = [ + _aug_op(left, aug_opnode, aug_op, right, context), + _bin_op(left, aug_opnode, bin_op, right, context), + ] + elif helpers.is_subtype(left_type, right_type): + methods = [ + _aug_op(left, aug_opnode, aug_op, right, context), + _bin_op(left, aug_opnode, bin_op, right, context), + ] + elif helpers.is_supertype(left_type, right_type): + methods = [ + _aug_op(left, aug_opnode, aug_op, right, context), + _bin_op(right, aug_opnode, bin_op, left, reverse_context, reverse=True), + _bin_op(left, aug_opnode, bin_op, right, context), + ] + else: + methods = [ + _aug_op(left, aug_opnode, aug_op, right, context), + _bin_op(left, aug_opnode, bin_op, right, context), + _bin_op(right, aug_opnode, bin_op, left, reverse_context, reverse=True), + ] + return methods + + +def _infer_binary_operation(left, right, binary_opnode, context, flow_factory): + """Infer a binary operation between a left operand and a right operand + + This is used by both normal binary operations and augmented binary + operations, the only difference is the flow factory used. + """ + + context, reverse_context = _get_binop_contexts(context, left, right) + left_type = helpers.object_type(left) + right_type = helpers.object_type(right) + methods = flow_factory( + left, left_type, binary_opnode, right, right_type, context, reverse_context + ) + for method in methods: + try: + results = list(method()) + except AttributeError: + continue + except exceptions.AttributeInferenceError: + continue + except exceptions.InferenceError: + yield util.Uninferable + return + else: + if any(result is util.Uninferable for result in results): + yield util.Uninferable + return + + if all(map(_is_not_implemented, results)): + continue + not_implemented = sum( + 1 for result in results if _is_not_implemented(result) + ) + if not_implemented and not_implemented != len(results): + # Can't infer yet what this is. + yield util.Uninferable + return + + yield from results + return + # The operation doesn't seem to be supported so let the caller know about it + yield util.BadBinaryOperationMessage(left_type, binary_opnode.op, right_type) + + +def _infer_binop(self, context): + """Binary operation inference logic.""" + left = self.left + right = self.right + + # we use two separate contexts for evaluating lhs and rhs because + # 1. evaluating lhs may leave some undesired entries in context.path + # which may not let us infer right value of rhs + context = context or contextmod.InferenceContext() + lhs_context = contextmod.copy_context(context) + rhs_context = contextmod.copy_context(context) + lhs_iter = left.infer(context=lhs_context) + rhs_iter = right.infer(context=rhs_context) + for lhs, rhs in itertools.product(lhs_iter, rhs_iter): + if any(value is util.Uninferable for value in (rhs, lhs)): + # Don't know how to process this. + yield util.Uninferable + return + + try: + yield from _infer_binary_operation(lhs, rhs, self, context, _get_binop_flow) + except exceptions._NonDeducibleTypeHierarchy: + yield util.Uninferable + + +@decorators.yes_if_nothing_inferred +@decorators.path_wrapper +def infer_binop(self, context=None): + return _filter_operation_errors( + self, _infer_binop, context, util.BadBinaryOperationMessage + ) + + +nodes.BinOp._infer_binop = _infer_binop +nodes.BinOp._infer = infer_binop + + +def _infer_augassign(self, context=None): + """Inference logic for augmented binary operations.""" + if context is None: + context = contextmod.InferenceContext() + + rhs_context = context.clone() + + lhs_iter = self.target.infer_lhs(context=context) + rhs_iter = self.value.infer(context=rhs_context) + for lhs, rhs in itertools.product(lhs_iter, rhs_iter): + if any(value is util.Uninferable for value in (rhs, lhs)): + # Don't know how to process this. + yield util.Uninferable + return + + try: + yield from _infer_binary_operation( + left=lhs, + right=rhs, + binary_opnode=self, + context=context, + flow_factory=_get_aug_flow, + ) + except exceptions._NonDeducibleTypeHierarchy: + yield util.Uninferable + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_augassign(self, context=None): + return _filter_operation_errors( + self, _infer_augassign, context, util.BadBinaryOperationMessage + ) + + +nodes.AugAssign._infer_augassign = _infer_augassign +nodes.AugAssign._infer = infer_augassign + +# End of binary operation inference. + + +@decorators.raise_if_nothing_inferred +def infer_arguments(self, context=None): + name = context.lookupname + if name is None: + raise exceptions.InferenceError(node=self, context=context) + return protocols._arguments_infer_argname(self, name, context) + + +nodes.Arguments._infer = infer_arguments + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_assign(self, context=None): + """infer a AssignName/AssignAttr: need to inspect the RHS part of the + assign node + """ + stmt = self.statement() + if isinstance(stmt, nodes.AugAssign): + return stmt.infer(context) + + stmts = list(self.assigned_stmts(context=context)) + return bases._infer_stmts(stmts, context) + + +nodes.AssignName._infer = infer_assign +nodes.AssignAttr._infer = infer_assign + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_empty_node(self, context=None): + if not self.has_underlying_object(): + yield util.Uninferable + else: + try: + yield from MANAGER.infer_ast_from_something(self.object, context=context) + except exceptions.AstroidError: + yield util.Uninferable + + +nodes.EmptyNode._infer = infer_empty_node + + +@decorators.raise_if_nothing_inferred +def infer_index(self, context=None): + return self.value.infer(context) + + +nodes.Index._infer = infer_index + +# TODO: move directly into bases.Instance when the dependency hell +# will be solved. +def instance_getitem(self, index, context=None): + # Rewrap index to Const for this case + new_context = contextmod.bind_context_to_node(context, self) + if not context: + context = new_context + + # Create a new callcontext for providing index as an argument. + new_context.callcontext = contextmod.CallContext(args=[index]) + + method = next(self.igetattr("__getitem__", context=context), None) + if not isinstance(method, bases.BoundMethod): + raise exceptions.InferenceError( + "Could not find __getitem__ for {node!r}.", node=self, context=context + ) + + return next(method.infer_call_result(self, new_context)) + + +bases.Instance.getitem = instance_getitem + + +def _populate_context_lookup(call, context): + # Allows context to be saved for later + # for inference inside a function + context_lookup = {} + if context is None: + return context_lookup + for arg in call.args: + if isinstance(arg, nodes.Starred): + context_lookup[arg.value] = context + else: + context_lookup[arg] = context + keywords = call.keywords if call.keywords is not None else [] + for keyword in keywords: + context_lookup[keyword.value] = context + return context_lookup + + +@decorators.raise_if_nothing_inferred +def infer_ifexp(self, context=None): + """Support IfExp inference + + If we can't infer the truthiness of the condition, we default + to inferring both branches. Otherwise, we infer either branch + depending on the condition. + """ + both_branches = False + # We use two separate contexts for evaluating lhs and rhs because + # evaluating lhs may leave some undesired entries in context.path + # which may not let us infer right value of rhs. + + context = context or contextmod.InferenceContext() + lhs_context = contextmod.copy_context(context) + rhs_context = contextmod.copy_context(context) + try: + test = next(self.test.infer(context=context.clone())) + except exceptions.InferenceError: + both_branches = True + else: + if test is not util.Uninferable: + if test.bool_value(): + yield from self.body.infer(context=lhs_context) + else: + yield from self.orelse.infer(context=rhs_context) + else: + both_branches = True + if both_branches: + yield from self.body.infer(context=lhs_context) + yield from self.orelse.infer(context=rhs_context) + + +nodes.IfExp._infer = infer_ifexp diff --git a/py3/lib/python3.6/site-packages/socketio/tests/__init__.py b/py3/lib/python3.6/site-packages/astroid/interpreter/__init__.py similarity index 100% rename from py3/lib/python3.6/site-packages/socketio/tests/__init__.py rename to py3/lib/python3.6/site-packages/astroid/interpreter/__init__.py diff --git a/py3/lib/python3.6/site-packages/astroid/interpreter/_import/__init__.py b/py3/lib/python3.6/site-packages/astroid/interpreter/_import/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/py3/lib/python3.6/site-packages/astroid/interpreter/_import/spec.py b/py3/lib/python3.6/site-packages/astroid/interpreter/_import/spec.py new file mode 100644 index 0000000..84e093b --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/interpreter/_import/spec.py @@ -0,0 +1,344 @@ +# Copyright (c) 2016-2018 Claudiu Popa +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2017 Chris Philip +# Copyright (c) 2017 Hugo +# Copyright (c) 2017 ioanatia +# Copyright (c) 2017 Calen Pennington +# Copyright (c) 2018 Nick Drozd + +import abc +import collections +import distutils +import enum +import imp +import os +import sys +import zipimport + +try: + import importlib.machinery + + _HAS_MACHINERY = True +except ImportError: + _HAS_MACHINERY = False + +try: + from functools import lru_cache +except ImportError: + from backports.functools_lru_cache import lru_cache + +from . import util + +ModuleType = enum.Enum( + "ModuleType", + "C_BUILTIN C_EXTENSION PKG_DIRECTORY " + "PY_CODERESOURCE PY_COMPILED PY_FROZEN PY_RESOURCE " + "PY_SOURCE PY_ZIPMODULE PY_NAMESPACE", +) +_ImpTypes = { + imp.C_BUILTIN: ModuleType.C_BUILTIN, + imp.C_EXTENSION: ModuleType.C_EXTENSION, + imp.PKG_DIRECTORY: ModuleType.PKG_DIRECTORY, + imp.PY_COMPILED: ModuleType.PY_COMPILED, + imp.PY_FROZEN: ModuleType.PY_FROZEN, + imp.PY_SOURCE: ModuleType.PY_SOURCE, +} +if hasattr(imp, "PY_RESOURCE"): + _ImpTypes[imp.PY_RESOURCE] = ModuleType.PY_RESOURCE +if hasattr(imp, "PY_CODERESOURCE"): + _ImpTypes[imp.PY_CODERESOURCE] = ModuleType.PY_CODERESOURCE + + +def _imp_type_to_module_type(imp_type): + return _ImpTypes[imp_type] + + +_ModuleSpec = collections.namedtuple( + "_ModuleSpec", "name type location " "origin submodule_search_locations" +) + + +class ModuleSpec(_ModuleSpec): + """Defines a class similar to PEP 420's ModuleSpec + + A module spec defines a name of a module, its type, location + and where submodules can be found, if the module is a package. + """ + + def __new__( + cls, + name, + module_type, + location=None, + origin=None, + submodule_search_locations=None, + ): + return _ModuleSpec.__new__( + cls, + name=name, + type=module_type, + location=location, + origin=origin, + submodule_search_locations=submodule_search_locations, + ) + + +class Finder: + """A finder is a class which knows how to find a particular module.""" + + def __init__(self, path=None): + self._path = path or sys.path + + @abc.abstractmethod + def find_module(self, modname, module_parts, processed, submodule_path): + """Find the given module + + Each finder is responsible for each protocol of finding, as long as + they all return a ModuleSpec. + + :param str modname: The module which needs to be searched. + :param list module_parts: It should be a list of strings, + where each part contributes to the module's + namespace. + :param list processed: What parts from the module parts were processed + so far. + :param list submodule_path: A list of paths where the module + can be looked into. + :returns: A ModuleSpec, describing how and where the module was found, + None, otherwise. + """ + + def contribute_to_path(self, spec, processed): + """Get a list of extra paths where this finder can search.""" + + +class ImpFinder(Finder): + """A finder based on the imp module.""" + + def find_module(self, modname, module_parts, processed, submodule_path): + if submodule_path is not None: + submodule_path = list(submodule_path) + try: + stream, mp_filename, mp_desc = imp.find_module(modname, submodule_path) + except ImportError: + return None + + # Close resources. + if stream: + stream.close() + + return ModuleSpec( + name=modname, + location=mp_filename, + module_type=_imp_type_to_module_type(mp_desc[2]), + ) + + def contribute_to_path(self, spec, processed): + if spec.location is None: + # Builtin. + return None + + if _is_setuptools_namespace(spec.location): + # extend_path is called, search sys.path for module/packages + # of this name see pkgutil.extend_path documentation + path = [ + os.path.join(p, *processed) + for p in sys.path + if os.path.isdir(os.path.join(p, *processed)) + ] + # We already import distutils elsewhere in astroid, + # so if it is the same module, we can use it directly. + elif spec.name == "distutils" and spec.location in distutils.__path__: + # distutils is patched inside virtualenvs to pick up submodules + # from the original Python, not from the virtualenv itself. + path = list(distutils.__path__) + else: + path = [spec.location] + return path + + +class ExplicitNamespacePackageFinder(ImpFinder): + """A finder for the explicit namespace packages, generated through pkg_resources.""" + + def find_module(self, modname, module_parts, processed, submodule_path): + if processed: + modname = ".".join(processed + [modname]) + if util.is_namespace(modname) and modname in sys.modules: + submodule_path = sys.modules[modname].__path__ + return ModuleSpec( + name=modname, + location="", + origin="namespace", + module_type=ModuleType.PY_NAMESPACE, + submodule_search_locations=submodule_path, + ) + return None + + def contribute_to_path(self, spec, processed): + return spec.submodule_search_locations + + +class ZipFinder(Finder): + """Finder that knows how to find a module inside zip files.""" + + def __init__(self, path): + super(ZipFinder, self).__init__(path) + self._zipimporters = _precache_zipimporters(path) + + def find_module(self, modname, module_parts, processed, submodule_path): + try: + file_type, filename, path = _search_zip(module_parts, self._zipimporters) + except ImportError: + return None + + return ModuleSpec( + name=modname, + location=filename, + origin="egg", + module_type=file_type, + submodule_search_locations=path, + ) + + +class PathSpecFinder(Finder): + """Finder based on importlib.machinery.PathFinder.""" + + def find_module(self, modname, module_parts, processed, submodule_path): + spec = importlib.machinery.PathFinder.find_spec(modname, path=submodule_path) + if spec: + # origin can be either a string on older Python versions + # or None in case it is a namespace package: + # https://github.com/python/cpython/pull/5481 + is_namespace_pkg = spec.origin in ("namespace", None) + location = spec.origin if not is_namespace_pkg else None + module_type = ModuleType.PY_NAMESPACE if is_namespace_pkg else None + spec = ModuleSpec( + name=spec.name, + location=location, + origin=spec.origin, + module_type=module_type, + submodule_search_locations=list(spec.submodule_search_locations or []), + ) + return spec + + def contribute_to_path(self, spec, processed): + if spec.type == ModuleType.PY_NAMESPACE: + return spec.submodule_search_locations + return None + + +_SPEC_FINDERS = (ImpFinder, ZipFinder) +if _HAS_MACHINERY: + _SPEC_FINDERS += (PathSpecFinder,) +_SPEC_FINDERS += (ExplicitNamespacePackageFinder,) + + +def _is_setuptools_namespace(location): + try: + with open(os.path.join(location, "__init__.py"), "rb") as stream: + data = stream.read(4096) + except IOError: + pass + else: + extend_path = b"pkgutil" in data and b"extend_path" in data + declare_namespace = ( + b"pkg_resources" in data and b"declare_namespace(__name__)" in data + ) + return extend_path or declare_namespace + + +@lru_cache() +def _cached_set_diff(left, right): + result = set(left) + result.difference_update(right) + return result + + +def _precache_zipimporters(path=None): + pic = sys.path_importer_cache + + # When measured, despite having the same complexity (O(n)), + # converting to tuples and then caching the conversion to sets + # and the set difference is faster than converting to sets + # and then only caching the set difference. + + req_paths = tuple(path or sys.path) + cached_paths = tuple(pic) + new_paths = _cached_set_diff(req_paths, cached_paths) + for entry_path in new_paths: + try: + pic[entry_path] = zipimport.zipimporter(entry_path) + except zipimport.ZipImportError: + continue + return pic + + +def _search_zip(modpath, pic): + for filepath, importer in list(pic.items()): + if importer is not None: + found = importer.find_module(modpath[0]) + if found: + if not importer.find_module(os.path.sep.join(modpath)): + raise ImportError( + "No module named %s in %s/%s" + % (".".join(modpath[1:]), filepath, modpath) + ) + # import code; code.interact(local=locals()) + return ( + ModuleType.PY_ZIPMODULE, + os.path.abspath(filepath) + os.path.sep + os.path.sep.join(modpath), + filepath, + ) + raise ImportError("No module named %s" % ".".join(modpath)) + + +def _find_spec_with_path(search_path, modname, module_parts, processed, submodule_path): + finders = [finder(search_path) for finder in _SPEC_FINDERS] + for finder in finders: + spec = finder.find_module(modname, module_parts, processed, submodule_path) + if spec is None: + continue + return finder, spec + + raise ImportError("No module named %s" % ".".join(module_parts)) + + +def find_spec(modpath, path=None): + """Find a spec for the given module. + + :type modpath: list or tuple + :param modpath: + split module's name (i.e name of a module or package split + on '.'), with leading empty strings for explicit relative import + + :type path: list or None + :param path: + optional list of path where the module or package should be + searched (use sys.path if nothing or None is given) + + :rtype: ModuleSpec + :return: A module spec, which describes how the module was + found and where. + """ + _path = path or sys.path + + # Need a copy for not mutating the argument. + modpath = modpath[:] + + submodule_path = None + module_parts = modpath[:] + processed = [] + + while modpath: + modname = modpath.pop(0) + finder, spec = _find_spec_with_path( + _path, modname, module_parts, processed, submodule_path or path + ) + processed.append(modname) + if modpath: + submodule_path = finder.contribute_to_path(spec, processed) + + if spec.type == ModuleType.PKG_DIRECTORY: + spec = spec._replace(submodule_search_locations=submodule_path) + + return spec diff --git a/py3/lib/python3.6/site-packages/astroid/interpreter/_import/util.py b/py3/lib/python3.6/site-packages/astroid/interpreter/_import/util.py new file mode 100644 index 0000000..a917bd3 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/interpreter/_import/util.py @@ -0,0 +1,10 @@ +# Copyright (c) 2016, 2018 Claudiu Popa + +try: + import pkg_resources +except ImportError: + pkg_resources = None + + +def is_namespace(modname): + return pkg_resources is not None and modname in pkg_resources._namespace_packages diff --git a/py3/lib/python3.6/site-packages/astroid/interpreter/dunder_lookup.py b/py3/lib/python3.6/site-packages/astroid/interpreter/dunder_lookup.py new file mode 100644 index 0000000..0ae9bc9 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/interpreter/dunder_lookup.py @@ -0,0 +1,66 @@ +# Copyright (c) 2016-2018 Claudiu Popa +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Contains logic for retrieving special methods. + +This implementation does not rely on the dot attribute access +logic, found in ``.getattr()``. The difference between these two +is that the dunder methods are looked with the type slots +(you can find more about these here +http://lucumr.pocoo.org/2014/8/16/the-python-i-would-like-to-see/) +As such, the lookup for the special methods is actually simpler than +the dot attribute access. +""" +import itertools + +import astroid +from astroid import exceptions + + +def _lookup_in_mro(node, name): + attrs = node.locals.get(name, []) + + nodes = itertools.chain.from_iterable( + ancestor.locals.get(name, []) for ancestor in node.ancestors(recurs=True) + ) + values = list(itertools.chain(attrs, nodes)) + if not values: + raise exceptions.AttributeInferenceError(attribute=name, target=node) + + return values + + +def lookup(node, name): + """Lookup the given special method name in the given *node* + + If the special method was found, then a list of attributes + will be returned. Otherwise, `astroid.AttributeInferenceError` + is going to be raised. + """ + if isinstance( + node, (astroid.List, astroid.Tuple, astroid.Const, astroid.Dict, astroid.Set) + ): + return _builtin_lookup(node, name) + if isinstance(node, astroid.Instance): + return _lookup_in_mro(node, name) + if isinstance(node, astroid.ClassDef): + return _class_lookup(node, name) + + raise exceptions.AttributeInferenceError(attribute=name, target=node) + + +def _class_lookup(node, name): + metaclass = node.metaclass() + if metaclass is None: + raise exceptions.AttributeInferenceError(attribute=name, target=node) + + return _lookup_in_mro(metaclass, name) + + +def _builtin_lookup(node, name): + values = node.locals.get(name, []) + if not values: + raise exceptions.AttributeInferenceError(attribute=name, target=node) + + return values diff --git a/py3/lib/python3.6/site-packages/astroid/interpreter/objectmodel.py b/py3/lib/python3.6/site-packages/astroid/interpreter/objectmodel.py new file mode 100644 index 0000000..5e488d9 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/interpreter/objectmodel.py @@ -0,0 +1,738 @@ +# Copyright (c) 2016-2018 Claudiu Popa +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2017-2018 Bryce Guinta +# Copyright (c) 2017 Ceridwen +# Copyright (c) 2017 Calen Pennington +# Copyright (c) 2018 Nick Drozd +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +""" +Data object model, as per https://docs.python.org/3/reference/datamodel.html. + +This module describes, at least partially, a data object model for some +of astroid's nodes. The model contains special attributes that nodes such +as functions, classes, modules etc have, such as __doc__, __class__, +__module__ etc, being used when doing attribute lookups over nodes. + +For instance, inferring `obj.__class__` will first trigger an inference +of the `obj` variable. If it was successfully inferred, then an attribute +`__class__ will be looked for in the inferred object. This is the part +where the data model occurs. The model is attached to those nodes +and the lookup mechanism will try to see if attributes such as +`__class__` are defined by the model or not. If they are defined, +the model will be requested to return the corresponding value of that +attribute. Thus the model can be viewed as a special part of the lookup +mechanism. +""" + +import itertools +import pprint +import os +import types +from functools import lru_cache + +import astroid +from astroid import context as contextmod +from astroid import exceptions +from astroid import node_classes + + +IMPL_PREFIX = "attr_" + + +def _dunder_dict(instance, attributes): + obj = node_classes.Dict(parent=instance) + + # Convert the keys to node strings + keys = [ + node_classes.Const(value=value, parent=obj) for value in list(attributes.keys()) + ] + + # The original attribute has a list of elements for each key, + # but that is not useful for retrieving the special attribute's value. + # In this case, we're picking the last value from each list. + values = [elem[-1] for elem in attributes.values()] + + obj.postinit(list(zip(keys, values))) + return obj + + +class ObjectModel: + def __init__(self): + self._instance = None + + def __repr__(self): + result = [] + cname = type(self).__name__ + string = "%(cname)s(%(fields)s)" + alignment = len(cname) + 1 + for field in sorted(self.attributes()): + width = 80 - len(field) - alignment + lines = pprint.pformat(field, indent=2, width=width).splitlines(True) + + inner = [lines[0]] + for line in lines[1:]: + inner.append(" " * alignment + line) + result.append(field) + + return string % { + "cname": cname, + "fields": (",\n" + " " * alignment).join(result), + } + + def __call__(self, instance): + self._instance = instance + return self + + def __get__(self, instance, cls=None): + # ObjectModel needs to be a descriptor so that just doing + # `special_attributes = SomeObjectModel` should be enough in the body of a node. + # But at the same time, node.special_attributes should return an object + # which can be used for manipulating the special attributes. That's the reason + # we pass the instance through which it got accessed to ObjectModel.__call__, + # returning itself afterwards, so we can still have access to the + # underlying data model and to the instance for which it got accessed. + return self(instance) + + def __contains__(self, name): + return name in self.attributes() + + @lru_cache(maxsize=None) + def attributes(self): + """Get the attributes which are exported by this object model.""" + return [ + obj[len(IMPL_PREFIX) :] for obj in dir(self) if obj.startswith(IMPL_PREFIX) + ] + + def lookup(self, name): + """Look up the given *name* in the current model + + It should return an AST or an interpreter object, + but if the name is not found, then an AttributeInferenceError will be raised. + """ + + if name in self.attributes(): + return getattr(self, IMPL_PREFIX + name) + raise exceptions.AttributeInferenceError(target=self._instance, attribute=name) + + +class ModuleModel(ObjectModel): + def _builtins(self): + builtins_ast_module = astroid.MANAGER.builtins_module + return builtins_ast_module.special_attributes.lookup("__dict__") + + @property + def attr_builtins(self): + return self._builtins() + + @property + def attr___path__(self): + if not self._instance.package: + raise exceptions.AttributeInferenceError( + target=self._instance, attribute="__path__" + ) + + path_objs = [ + node_classes.Const( + value=path + if not path.endswith("__init__.py") + else os.path.dirname(path), + parent=self._instance, + ) + for path in self._instance.path + ] + + container = node_classes.List(parent=self._instance) + container.postinit(path_objs) + + return container + + @property + def attr___name__(self): + return node_classes.Const(value=self._instance.name, parent=self._instance) + + @property + def attr___doc__(self): + return node_classes.Const(value=self._instance.doc, parent=self._instance) + + @property + def attr___file__(self): + return node_classes.Const(value=self._instance.file, parent=self._instance) + + @property + def attr___dict__(self): + return _dunder_dict(self._instance, self._instance.globals) + + @property + def attr___package__(self): + if not self._instance.package: + value = "" + else: + value = self._instance.name + + return node_classes.Const(value=value, parent=self._instance) + + # These are related to the Python 3 implementation of the + # import system, + # https://docs.python.org/3/reference/import.html#import-related-module-attributes + + @property + def attr___spec__(self): + # No handling for now. + return node_classes.Unknown() + + @property + def attr___loader__(self): + # No handling for now. + return node_classes.Unknown() + + @property + def attr___cached__(self): + # No handling for now. + return node_classes.Unknown() + + +class FunctionModel(ObjectModel): + @property + def attr___name__(self): + return node_classes.Const(value=self._instance.name, parent=self._instance) + + @property + def attr___doc__(self): + return node_classes.Const(value=self._instance.doc, parent=self._instance) + + @property + def attr___qualname__(self): + return node_classes.Const(value=self._instance.qname(), parent=self._instance) + + @property + def attr___defaults__(self): + func = self._instance + if not func.args.defaults: + return node_classes.Const(value=None, parent=func) + + defaults_obj = node_classes.Tuple(parent=func) + defaults_obj.postinit(func.args.defaults) + return defaults_obj + + @property + def attr___annotations__(self): + obj = node_classes.Dict(parent=self._instance) + + if not self._instance.returns: + returns = None + else: + returns = self._instance.returns + + args = self._instance.args + pair_annotations = itertools.chain( + zip(args.args or [], args.annotations), + zip(args.kwonlyargs, args.kwonlyargs_annotations), + zip(args.posonlyargs or [], args.posonlyargs_annotations), + ) + + annotations = { + arg.name: annotation for (arg, annotation) in pair_annotations if annotation + } + if args.varargannotation: + annotations[args.vararg] = args.varargannotation + if args.kwargannotation: + annotations[args.kwarg] = args.kwargannotation + if returns: + annotations["return"] = returns + + items = [ + (node_classes.Const(key, parent=obj), value) + for (key, value) in annotations.items() + ] + + obj.postinit(items) + return obj + + @property + def attr___dict__(self): + return node_classes.Dict(parent=self._instance) + + attr___globals__ = attr___dict__ + + @property + def attr___kwdefaults__(self): + def _default_args(args, parent): + for arg in args.kwonlyargs: + try: + default = args.default_value(arg.name) + except exceptions.NoDefault: + continue + + name = node_classes.Const(arg.name, parent=parent) + yield name, default + + args = self._instance.args + obj = node_classes.Dict(parent=self._instance) + defaults = dict(_default_args(args, obj)) + + obj.postinit(list(defaults.items())) + return obj + + @property + def attr___module__(self): + return node_classes.Const(self._instance.root().qname()) + + @property + def attr___get__(self): + # pylint: disable=import-outside-toplevel; circular import + from astroid import bases + + func = self._instance + + class DescriptorBoundMethod(bases.BoundMethod): + """Bound method which knows how to understand calling descriptor binding.""" + + def implicit_parameters(self): + # Different than BoundMethod since the signature + # is different. + return 0 + + def infer_call_result(self, caller, context=None): + if len(caller.args) > 2 or len(caller.args) < 1: + raise exceptions.InferenceError( + "Invalid arguments for descriptor binding", + target=self, + context=context, + ) + + context = contextmod.copy_context(context) + cls = next(caller.args[0].infer(context=context)) + + if cls is astroid.Uninferable: + raise exceptions.InferenceError( + "Invalid class inferred", target=self, context=context + ) + + # For some reason func is a Node that the below + # code is not expecting + if isinstance(func, bases.BoundMethod): + yield func + return + + # Rebuild the original value, but with the parent set as the + # class where it will be bound. + new_func = func.__class__( + name=func.name, + doc=func.doc, + lineno=func.lineno, + col_offset=func.col_offset, + parent=cls, + ) + # pylint: disable=no-member + new_func.postinit(func.args, func.body, func.decorators, func.returns) + + # Build a proper bound method that points to our newly built function. + proxy = bases.UnboundMethod(new_func) + yield bases.BoundMethod(proxy=proxy, bound=cls) + + @property + def args(self): + """Overwrite the underlying args to match those of the underlying func + + Usually the underlying *func* is a function/method, as in: + + def test(self): + pass + + This has only the *self* parameter but when we access test.__get__ + we get a new object which has two parameters, *self* and *type*. + """ + nonlocal func + positional_or_keyword_params = func.args.args.copy() + positional_or_keyword_params.append(astroid.AssignName(name="type")) + + positional_only_params = func.args.posonlyargs.copy() + + arguments = astroid.Arguments(parent=func.args.parent) + arguments.postinit( + args=positional_or_keyword_params, + posonlyargs=positional_only_params, + defaults=[], + kwonlyargs=[], + kw_defaults=[], + annotations=[], + ) + return arguments + + return DescriptorBoundMethod(proxy=self._instance, bound=self._instance) + + # These are here just for completion. + @property + def attr___ne__(self): + return node_classes.Unknown() + + attr___subclasshook__ = attr___ne__ + attr___str__ = attr___ne__ + attr___sizeof__ = attr___ne__ + attr___setattr___ = attr___ne__ + attr___repr__ = attr___ne__ + attr___reduce__ = attr___ne__ + attr___reduce_ex__ = attr___ne__ + attr___new__ = attr___ne__ + attr___lt__ = attr___ne__ + attr___eq__ = attr___ne__ + attr___gt__ = attr___ne__ + attr___format__ = attr___ne__ + attr___delattr___ = attr___ne__ + attr___getattribute__ = attr___ne__ + attr___hash__ = attr___ne__ + attr___init__ = attr___ne__ + attr___dir__ = attr___ne__ + attr___call__ = attr___ne__ + attr___class__ = attr___ne__ + attr___closure__ = attr___ne__ + attr___code__ = attr___ne__ + + +class ClassModel(ObjectModel): + @property + def attr___module__(self): + return node_classes.Const(self._instance.root().qname()) + + @property + def attr___name__(self): + return node_classes.Const(self._instance.name) + + @property + def attr___qualname__(self): + return node_classes.Const(self._instance.qname()) + + @property + def attr___doc__(self): + return node_classes.Const(self._instance.doc) + + @property + def attr___mro__(self): + if not self._instance.newstyle: + raise exceptions.AttributeInferenceError( + target=self._instance, attribute="__mro__" + ) + + mro = self._instance.mro() + obj = node_classes.Tuple(parent=self._instance) + obj.postinit(mro) + return obj + + @property + def attr_mro(self): + if not self._instance.newstyle: + raise exceptions.AttributeInferenceError( + target=self._instance, attribute="mro" + ) + + # pylint: disable=import-outside-toplevel; circular import + from astroid import bases + + other_self = self + + # Cls.mro is a method and we need to return one in order to have a proper inference. + # The method we're returning is capable of inferring the underlying MRO though. + class MroBoundMethod(bases.BoundMethod): + def infer_call_result(self, caller, context=None): + yield other_self.attr___mro__ + + implicit_metaclass = self._instance.implicit_metaclass() + mro_method = implicit_metaclass.locals["mro"][0] + return MroBoundMethod(proxy=mro_method, bound=implicit_metaclass) + + @property + def attr___bases__(self): + obj = node_classes.Tuple() + context = contextmod.InferenceContext() + elts = list(self._instance._inferred_bases(context)) + obj.postinit(elts=elts) + return obj + + @property + def attr___class__(self): + # pylint: disable=import-outside-toplevel; circular import + from astroid import helpers + + return helpers.object_type(self._instance) + + @property + def attr___subclasses__(self): + """Get the subclasses of the underlying class + + This looks only in the current module for retrieving the subclasses, + thus it might miss a couple of them. + """ + # pylint: disable=import-outside-toplevel; circular import + from astroid import bases + from astroid import scoped_nodes + + if not self._instance.newstyle: + raise exceptions.AttributeInferenceError( + target=self._instance, attribute="__subclasses__" + ) + + qname = self._instance.qname() + root = self._instance.root() + classes = [ + cls + for cls in root.nodes_of_class(scoped_nodes.ClassDef) + if cls != self._instance and cls.is_subtype_of(qname) + ] + + obj = node_classes.List(parent=self._instance) + obj.postinit(classes) + + class SubclassesBoundMethod(bases.BoundMethod): + def infer_call_result(self, caller, context=None): + yield obj + + implicit_metaclass = self._instance.implicit_metaclass() + subclasses_method = implicit_metaclass.locals["__subclasses__"][0] + return SubclassesBoundMethod(proxy=subclasses_method, bound=implicit_metaclass) + + @property + def attr___dict__(self): + return node_classes.Dict(parent=self._instance) + + +class SuperModel(ObjectModel): + @property + def attr___thisclass__(self): + return self._instance.mro_pointer + + @property + def attr___self_class__(self): + return self._instance._self_class + + @property + def attr___self__(self): + return self._instance.type + + @property + def attr___class__(self): + return self._instance._proxied + + +class UnboundMethodModel(ObjectModel): + @property + def attr___class__(self): + # pylint: disable=import-outside-toplevel; circular import + from astroid import helpers + + return helpers.object_type(self._instance) + + @property + def attr___func__(self): + return self._instance._proxied + + @property + def attr___self__(self): + return node_classes.Const(value=None, parent=self._instance) + + attr_im_func = attr___func__ + attr_im_class = attr___class__ + attr_im_self = attr___self__ + + +class BoundMethodModel(FunctionModel): + @property + def attr___func__(self): + return self._instance._proxied._proxied + + @property + def attr___self__(self): + return self._instance.bound + + +class GeneratorModel(FunctionModel): + def __new__(cls, *args, **kwargs): + # Append the values from the GeneratorType unto this object. + ret = super(GeneratorModel, cls).__new__(cls, *args, **kwargs) + generator = astroid.MANAGER.builtins_module["generator"] + for name, values in generator.locals.items(): + method = values[0] + patched = lambda cls, meth=method: meth + + setattr(type(ret), IMPL_PREFIX + name, property(patched)) + + return ret + + @property + def attr___name__(self): + return node_classes.Const( + value=self._instance.parent.name, parent=self._instance + ) + + @property + def attr___doc__(self): + return node_classes.Const( + value=self._instance.parent.doc, parent=self._instance + ) + + +class AsyncGeneratorModel(GeneratorModel): + def __new__(cls, *args, **kwargs): + # Append the values from the AGeneratorType unto this object. + ret = super().__new__(cls, *args, **kwargs) + astroid_builtins = astroid.MANAGER.builtins_module + generator = astroid_builtins.get("async_generator") + if generator is None: + # Make it backward compatible. + generator = astroid_builtins.get("generator") + + for name, values in generator.locals.items(): + method = values[0] + patched = lambda cls, meth=method: meth + + setattr(type(ret), IMPL_PREFIX + name, property(patched)) + + return ret + + +class InstanceModel(ObjectModel): + @property + def attr___class__(self): + return self._instance._proxied + + @property + def attr___module__(self): + return node_classes.Const(self._instance.root().qname()) + + @property + def attr___doc__(self): + return node_classes.Const(self._instance.doc) + + @property + def attr___dict__(self): + return _dunder_dict(self._instance, self._instance.instance_attrs) + + +# Exception instances + + +class ExceptionInstanceModel(InstanceModel): + @property + def attr_args(self): + message = node_classes.Const("") + args = node_classes.Tuple(parent=self._instance) + args.postinit((message,)) + return args + + @property + def attr___traceback__(self): + builtins_ast_module = astroid.MANAGER.builtins_module + traceback_type = builtins_ast_module[types.TracebackType.__name__] + return traceback_type.instantiate_class() + + +class SyntaxErrorInstanceModel(ExceptionInstanceModel): + @property + def attr_text(self): + return node_classes.Const("") + + +class OSErrorInstanceModel(ExceptionInstanceModel): + @property + def attr_filename(self): + return node_classes.Const("") + + @property + def attr_errno(self): + return node_classes.Const(0) + + @property + def attr_strerror(self): + return node_classes.Const("") + + attr_filename2 = attr_filename + + +class ImportErrorInstanceModel(ExceptionInstanceModel): + @property + def attr_name(self): + return node_classes.Const("") + + @property + def attr_path(self): + return node_classes.Const("") + + +BUILTIN_EXCEPTIONS = { + "builtins.SyntaxError": SyntaxErrorInstanceModel, + "builtins.ImportError": ImportErrorInstanceModel, + # These are all similar to OSError in terms of attributes + "builtins.OSError": OSErrorInstanceModel, + "builtins.BlockingIOError": OSErrorInstanceModel, + "builtins.BrokenPipeError": OSErrorInstanceModel, + "builtins.ChildProcessError": OSErrorInstanceModel, + "builtins.ConnectionAbortedError": OSErrorInstanceModel, + "builtins.ConnectionError": OSErrorInstanceModel, + "builtins.ConnectionRefusedError": OSErrorInstanceModel, + "builtins.ConnectionResetError": OSErrorInstanceModel, + "builtins.FileExistsError": OSErrorInstanceModel, + "builtins.FileNotFoundError": OSErrorInstanceModel, + "builtins.InterruptedError": OSErrorInstanceModel, + "builtins.IsADirectoryError": OSErrorInstanceModel, + "builtins.NotADirectoryError": OSErrorInstanceModel, + "builtins.PermissionError": OSErrorInstanceModel, + "builtins.ProcessLookupError": OSErrorInstanceModel, + "builtins.TimeoutError": OSErrorInstanceModel, +} + + +class DictModel(ObjectModel): + @property + def attr___class__(self): + return self._instance._proxied + + def _generic_dict_attribute(self, obj, name): + """Generate a bound method that can infer the given *obj*.""" + + class DictMethodBoundMethod(astroid.BoundMethod): + def infer_call_result(self, caller, context=None): + yield obj + + meth = next(self._instance._proxied.igetattr(name)) + return DictMethodBoundMethod(proxy=meth, bound=self._instance) + + @property + def attr_items(self): + elems = [] + obj = node_classes.List(parent=self._instance) + for key, value in self._instance.items: + elem = node_classes.Tuple(parent=obj) + elem.postinit((key, value)) + elems.append(elem) + obj.postinit(elts=elems) + + # pylint: disable=import-outside-toplevel; circular import + from astroid import objects + + obj = objects.DictItems(obj) + return self._generic_dict_attribute(obj, "items") + + @property + def attr_keys(self): + keys = [key for (key, _) in self._instance.items] + obj = node_classes.List(parent=self._instance) + obj.postinit(elts=keys) + + # pylint: disable=import-outside-toplevel; circular import + from astroid import objects + + obj = objects.DictKeys(obj) + return self._generic_dict_attribute(obj, "keys") + + @property + def attr_values(self): + + values = [value for (_, value) in self._instance.items] + obj = node_classes.List(parent=self._instance) + obj.postinit(values) + + # pylint: disable=import-outside-toplevel; circular import + from astroid import objects + + obj = objects.DictValues(obj) + return self._generic_dict_attribute(obj, "values") diff --git a/py3/lib/python3.6/site-packages/astroid/manager.py b/py3/lib/python3.6/site-packages/astroid/manager.py new file mode 100644 index 0000000..e5fd0d6 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/manager.py @@ -0,0 +1,337 @@ +# Copyright (c) 2006-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 BioGeek +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2017 Iva Miholic +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""astroid manager: avoid multiple astroid build of a same module when +possible by providing a class responsible to get astroid representation +from various source and using a cache of built modules) +""" + +import os +import zipimport + +from astroid import exceptions +from astroid.interpreter._import import spec +from astroid import modutils +from astroid import transforms + + +ZIP_IMPORT_EXTS = (".zip", ".egg", ".whl") + + +def safe_repr(obj): + try: + return repr(obj) + except Exception: # pylint: disable=broad-except + return "???" + + +class AstroidManager: + """the astroid manager, responsible to build astroid from files + or modules. + + Use the Borg pattern. + """ + + name = "astroid loader" + brain = {} + + def __init__(self): + self.__dict__ = AstroidManager.brain + if not self.__dict__: + # NOTE: cache entries are added by the [re]builder + self.astroid_cache = {} + self._mod_file_cache = {} + self._failed_import_hooks = [] + self.always_load_extensions = False + self.optimize_ast = False + self.extension_package_whitelist = set() + self._transform = transforms.TransformVisitor() + + # Export these APIs for convenience + self.register_transform = self._transform.register_transform + self.unregister_transform = self._transform.unregister_transform + self.max_inferable_values = 100 + + @property + def builtins_module(self): + return self.astroid_cache["builtins"] + + def visit_transforms(self, node): + """Visit the transforms and apply them to the given *node*.""" + return self._transform.visit(node) + + def ast_from_file(self, filepath, modname=None, fallback=True, source=False): + """given a module name, return the astroid object""" + try: + filepath = modutils.get_source_file(filepath, include_no_ext=True) + source = True + except modutils.NoSourceFile: + pass + if modname is None: + try: + modname = ".".join(modutils.modpath_from_file(filepath)) + except ImportError: + modname = filepath + if ( + modname in self.astroid_cache + and self.astroid_cache[modname].file == filepath + ): + return self.astroid_cache[modname] + if source: + # pylint: disable=import-outside-toplevel; circular import + from astroid.builder import AstroidBuilder + + return AstroidBuilder(self).file_build(filepath, modname) + if fallback and modname: + return self.ast_from_module_name(modname) + raise exceptions.AstroidBuildingError( + "Unable to build an AST for {path}.", path=filepath + ) + + def _build_stub_module(self, modname): + # pylint: disable=import-outside-toplevel; circular import + from astroid.builder import AstroidBuilder + + return AstroidBuilder(self).string_build("", modname) + + def _build_namespace_module(self, modname, path): + # pylint: disable=import-outside-toplevel; circular import + from astroid.builder import build_namespace_package_module + + return build_namespace_package_module(modname, path) + + def _can_load_extension(self, modname): + if self.always_load_extensions: + return True + if modutils.is_standard_module(modname): + return True + parts = modname.split(".") + return any( + ".".join(parts[:x]) in self.extension_package_whitelist + for x in range(1, len(parts) + 1) + ) + + def ast_from_module_name(self, modname, context_file=None): + """given a module name, return the astroid object""" + if modname in self.astroid_cache: + return self.astroid_cache[modname] + if modname == "__main__": + return self._build_stub_module(modname) + old_cwd = os.getcwd() + if context_file: + os.chdir(os.path.dirname(context_file)) + try: + found_spec = self.file_from_module_name(modname, context_file) + if found_spec.type == spec.ModuleType.PY_ZIPMODULE: + module = self.zip_import_data(found_spec.location) + if module is not None: + return module + + elif found_spec.type in ( + spec.ModuleType.C_BUILTIN, + spec.ModuleType.C_EXTENSION, + ): + if ( + found_spec.type == spec.ModuleType.C_EXTENSION + and not self._can_load_extension(modname) + ): + return self._build_stub_module(modname) + try: + module = modutils.load_module_from_name(modname) + except Exception as ex: + raise exceptions.AstroidImportError( + "Loading {modname} failed with:\n{error}", + modname=modname, + path=found_spec.location, + ) from ex + return self.ast_from_module(module, modname) + + elif found_spec.type == spec.ModuleType.PY_COMPILED: + raise exceptions.AstroidImportError( + "Unable to load compiled module {modname}.", + modname=modname, + path=found_spec.location, + ) + + elif found_spec.type == spec.ModuleType.PY_NAMESPACE: + return self._build_namespace_module( + modname, found_spec.submodule_search_locations + ) + + if found_spec.location is None: + raise exceptions.AstroidImportError( + "Can't find a file for module {modname}.", modname=modname + ) + + return self.ast_from_file(found_spec.location, modname, fallback=False) + except exceptions.AstroidBuildingError as e: + for hook in self._failed_import_hooks: + try: + return hook(modname) + except exceptions.AstroidBuildingError: + pass + raise e + finally: + os.chdir(old_cwd) + + def zip_import_data(self, filepath): + if zipimport is None: + return None + + # pylint: disable=import-outside-toplevel; circular import + from astroid.builder import AstroidBuilder + + builder = AstroidBuilder(self) + for ext in ZIP_IMPORT_EXTS: + try: + eggpath, resource = filepath.rsplit(ext + os.path.sep, 1) + except ValueError: + continue + try: + importer = zipimport.zipimporter(eggpath + ext) + zmodname = resource.replace(os.path.sep, ".") + if importer.is_package(resource): + zmodname = zmodname + ".__init__" + module = builder.string_build( + importer.get_source(resource), zmodname, filepath + ) + return module + except Exception: # pylint: disable=broad-except + continue + return None + + def file_from_module_name(self, modname, contextfile): + try: + value = self._mod_file_cache[(modname, contextfile)] + except KeyError: + try: + value = modutils.file_info_from_modpath( + modname.split("."), context_file=contextfile + ) + except ImportError as ex: + value = exceptions.AstroidImportError( + "Failed to import module {modname} with error:\n{error}.", + modname=modname, + error=ex, + ) + self._mod_file_cache[(modname, contextfile)] = value + if isinstance(value, exceptions.AstroidBuildingError): + raise value + return value + + def ast_from_module(self, module, modname=None): + """given an imported module, return the astroid object""" + modname = modname or module.__name__ + if modname in self.astroid_cache: + return self.astroid_cache[modname] + try: + # some builtin modules don't have __file__ attribute + filepath = module.__file__ + if modutils.is_python_source(filepath): + return self.ast_from_file(filepath, modname) + except AttributeError: + pass + + # pylint: disable=import-outside-toplevel; circular import + from astroid.builder import AstroidBuilder + + return AstroidBuilder(self).module_build(module, modname) + + def ast_from_class(self, klass, modname=None): + """get astroid for the given class""" + if modname is None: + try: + modname = klass.__module__ + except AttributeError as exc: + raise exceptions.AstroidBuildingError( + "Unable to get module for class {class_name}.", + cls=klass, + class_repr=safe_repr(klass), + modname=modname, + ) from exc + modastroid = self.ast_from_module_name(modname) + return modastroid.getattr(klass.__name__)[0] # XXX + + def infer_ast_from_something(self, obj, context=None): + """infer astroid for the given class""" + if hasattr(obj, "__class__") and not isinstance(obj, type): + klass = obj.__class__ + else: + klass = obj + try: + modname = klass.__module__ + except AttributeError as exc: + raise exceptions.AstroidBuildingError( + "Unable to get module for {class_repr}.", + cls=klass, + class_repr=safe_repr(klass), + ) from exc + except Exception as exc: + raise exceptions.AstroidImportError( + "Unexpected error while retrieving module for {class_repr}:\n" + "{error}", + cls=klass, + class_repr=safe_repr(klass), + ) from exc + try: + name = klass.__name__ + except AttributeError as exc: + raise exceptions.AstroidBuildingError( + "Unable to get name for {class_repr}:\n", + cls=klass, + class_repr=safe_repr(klass), + ) from exc + except Exception as exc: + raise exceptions.AstroidImportError( + "Unexpected error while retrieving name for {class_repr}:\n" "{error}", + cls=klass, + class_repr=safe_repr(klass), + ) from exc + # take care, on living object __module__ is regularly wrong :( + modastroid = self.ast_from_module_name(modname) + if klass is obj: + for inferred in modastroid.igetattr(name, context): + yield inferred + else: + for inferred in modastroid.igetattr(name, context): + yield inferred.instantiate_class() + + def register_failed_import_hook(self, hook): + """Registers a hook to resolve imports that cannot be found otherwise. + + `hook` must be a function that accepts a single argument `modname` which + contains the name of the module or package that could not be imported. + If `hook` can resolve the import, must return a node of type `astroid.Module`, + otherwise, it must raise `AstroidBuildingError`. + """ + self._failed_import_hooks.append(hook) + + def cache_module(self, module): + """Cache a module if no module with the same name is known yet.""" + self.astroid_cache.setdefault(module.name, module) + + def bootstrap(self): + """Bootstrap the required AST modules needed for the manager to work + + The bootstrap usually involves building the AST for the builtins + module, which is required by the rest of astroid to work correctly. + """ + from astroid import raw_building # pylint: disable=import-outside-toplevel + + raw_building._astroid_bootstrapping() + + def clear_cache(self): + """Clear the underlying cache. Also bootstraps the builtins module.""" + self.astroid_cache.clear() + self.bootstrap() diff --git a/py3/lib/python3.6/site-packages/astroid/mixins.py b/py3/lib/python3.6/site-packages/astroid/mixins.py new file mode 100644 index 0000000..497a840 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/mixins.py @@ -0,0 +1,160 @@ +# Copyright (c) 2010-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014-2016, 2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""This module contains some mixins for the different nodes. +""" +import itertools + +from astroid import decorators +from astroid import exceptions + + +class BlockRangeMixIn: + """override block range """ + + @decorators.cachedproperty + def blockstart_tolineno(self): + return self.lineno + + def _elsed_block_range(self, lineno, orelse, last=None): + """handle block line numbers range for try/finally, for, if and while + statements + """ + if lineno == self.fromlineno: + return lineno, lineno + if orelse: + if lineno >= orelse[0].fromlineno: + return lineno, orelse[-1].tolineno + return lineno, orelse[0].fromlineno - 1 + return lineno, last or self.tolineno + + +class FilterStmtsMixin: + """Mixin for statement filtering and assignment type""" + + def _get_filtered_stmts(self, _, node, _stmts, mystmt): + """method used in _filter_stmts to get statements and trigger break""" + if self.statement() is mystmt: + # original node's statement is the assignment, only keep + # current node (gen exp, list comp) + return [node], True + return _stmts, False + + def assign_type(self): + return self + + +class AssignTypeMixin: + def assign_type(self): + return self + + def _get_filtered_stmts(self, lookup_node, node, _stmts, mystmt): + """method used in filter_stmts""" + if self is mystmt: + return _stmts, True + if self.statement() is mystmt: + # original node's statement is the assignment, only keep + # current node (gen exp, list comp) + return [node], True + return _stmts, False + + +class ParentAssignTypeMixin(AssignTypeMixin): + def assign_type(self): + return self.parent.assign_type() + + +class ImportFromMixin(FilterStmtsMixin): + """MixIn for From and Import Nodes""" + + def _infer_name(self, frame, name): + return name + + def do_import_module(self, modname=None): + """return the ast for a module whose name is imported by + """ + # handle special case where we are on a package node importing a module + # using the same name as the package, which may end in an infinite loop + # on relative imports + # XXX: no more needed ? + mymodule = self.root() + level = getattr(self, "level", None) # Import as no level + if modname is None: + modname = self.modname + # XXX we should investigate deeper if we really want to check + # importing itself: modname and mymodule.name be relative or absolute + if mymodule.relative_to_absolute_name(modname, level) == mymodule.name: + # FIXME: we used to raise InferenceError here, but why ? + return mymodule + + return mymodule.import_module( + modname, level=level, relative_only=level and level >= 1 + ) + + def real_name(self, asname): + """get name from 'as' name""" + for name, _asname in self.names: + if name == "*": + return asname + if not _asname: + name = name.split(".", 1)[0] + _asname = name + if asname == _asname: + return name + raise exceptions.AttributeInferenceError( + "Could not find original name for {attribute} in {target!r}", + target=self, + attribute=asname, + ) + + +class MultiLineBlockMixin: + """Mixin for nodes with multi-line blocks, e.g. For and FunctionDef. + Note that this does not apply to every node with a `body` field. + For instance, an If node has a multi-line body, but the body of an + IfExpr is not multi-line, and hence cannot contain Return nodes, + Assign nodes, etc. + """ + + @decorators.cachedproperty + def _multi_line_blocks(self): + return tuple(getattr(self, field) for field in self._multi_line_block_fields) + + def _get_return_nodes_skip_functions(self): + for block in self._multi_line_blocks: + for child_node in block: + if child_node.is_function: + continue + yield from child_node._get_return_nodes_skip_functions() + + def _get_yield_nodes_skip_lambdas(self): + for block in self._multi_line_blocks: + for child_node in block: + if child_node.is_lambda: + continue + yield from child_node._get_yield_nodes_skip_lambdas() + + @decorators.cached + def _get_assign_nodes(self): + children_assign_nodes = ( + child_node._get_assign_nodes() + for block in self._multi_line_blocks + for child_node in block + ) + return list(itertools.chain.from_iterable(children_assign_nodes)) + + +class NoChildrenMixin: + """Mixin for nodes with no children, e.g. Pass.""" + + def get_children(self): + yield from () diff --git a/py3/lib/python3.6/site-packages/astroid/modutils.py b/py3/lib/python3.6/site-packages/astroid/modutils.py new file mode 100644 index 0000000..0c009b1 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/modutils.py @@ -0,0 +1,698 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Denis Laxalde +# Copyright (c) 2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2015 Radosław Ganczarek +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2016 Ceridwen +# Copyright (c) 2018 Mario Corchero +# Copyright (c) 2018 Mario Corchero +# Copyright (c) 2018 Anthony Sottile + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Python modules manipulation utility functions. + +:type PY_SOURCE_EXTS: tuple(str) +:var PY_SOURCE_EXTS: list of possible python source file extension + +:type STD_LIB_DIRS: set of str +:var STD_LIB_DIRS: directories where standard modules are located + +:type BUILTIN_MODULES: dict +:var BUILTIN_MODULES: dictionary with builtin module names has key +""" +import imp +import os +import platform +import sys +import itertools +from distutils.sysconfig import get_python_lib # pylint: disable=import-error + +# pylint: disable=import-error, no-name-in-module +from distutils.errors import DistutilsPlatformError + +# distutils is replaced by virtualenv with a module that does +# weird path manipulations in order to get to the +# real distutils module. + +from .interpreter._import import spec +from .interpreter._import import util + +if sys.platform.startswith("win"): + PY_SOURCE_EXTS = ("py", "pyw") + PY_COMPILED_EXTS = ("dll", "pyd") +else: + PY_SOURCE_EXTS = ("py",) + PY_COMPILED_EXTS = ("so",) + + +try: + # The explicit sys.prefix is to work around a patch in virtualenv that + # replaces the 'real' sys.prefix (i.e. the location of the binary) + # with the prefix from which the virtualenv was created. This throws + # off the detection logic for standard library modules, thus the + # workaround. + STD_LIB_DIRS = { + get_python_lib(standard_lib=True, prefix=sys.prefix), + # Take care of installations where exec_prefix != prefix. + get_python_lib(standard_lib=True, prefix=sys.exec_prefix), + get_python_lib(standard_lib=True), + } +# get_python_lib(standard_lib=1) is not available on pypy, set STD_LIB_DIR to +# non-valid path, see https://bugs.pypy.org/issue1164 +except DistutilsPlatformError: + STD_LIB_DIRS = set() + +if os.name == "nt": + STD_LIB_DIRS.add(os.path.join(sys.prefix, "dlls")) + try: + # real_prefix is defined when running inside virtual environments, + # created with the **virtualenv** library. + STD_LIB_DIRS.add(os.path.join(sys.real_prefix, "dlls")) + except AttributeError: + # sys.base_exec_prefix is always defined, but in a virtual environment + # created with the stdlib **venv** module, it points to the original + # installation, if the virtual env is activated. + try: + STD_LIB_DIRS.add(os.path.join(sys.base_exec_prefix, "dlls")) + except AttributeError: + pass + +if platform.python_implementation() == "PyPy": + _root = os.path.join(sys.prefix, "lib_pypy") + STD_LIB_DIRS.add(_root) + try: + # real_prefix is defined when running inside virtualenv. + STD_LIB_DIRS.add(os.path.join(sys.real_prefix, "lib_pypy")) + except AttributeError: + pass + del _root +if os.name == "posix": + # Need the real prefix is we're under a virtualenv, otherwise + # the usual one will do. + try: + prefix = sys.real_prefix + except AttributeError: + prefix = sys.prefix + + def _posix_path(path): + base_python = "python%d.%d" % sys.version_info[:2] + return os.path.join(prefix, path, base_python) + + STD_LIB_DIRS.add(_posix_path("lib")) + if sys.maxsize > 2 ** 32: + # This tries to fix a problem with /usr/lib64 builds, + # where systems are running both 32-bit and 64-bit code + # on the same machine, which reflects into the places where + # standard library could be found. More details can be found + # here http://bugs.python.org/issue1294959. + # An easy reproducing case would be + # https://github.com/PyCQA/pylint/issues/712#issuecomment-163178753 + STD_LIB_DIRS.add(_posix_path("lib64")) + +EXT_LIB_DIRS = {get_python_lib(), get_python_lib(True)} +IS_JYTHON = platform.python_implementation() == "Jython" +BUILTIN_MODULES = dict.fromkeys(sys.builtin_module_names, True) + + +class NoSourceFile(Exception): + """exception raised when we are not able to get a python + source file for a precompiled file + """ + + +def _normalize_path(path): + return os.path.normcase(os.path.abspath(path)) + + +def _canonicalize_path(path): + return os.path.realpath(os.path.expanduser(path)) + + +def _path_from_filename(filename, is_jython=IS_JYTHON): + if not is_jython: + return filename + head, has_pyclass, _ = filename.partition("$py.class") + if has_pyclass: + return head + ".py" + return filename + + +def _handle_blacklist(blacklist, dirnames, filenames): + """remove files/directories in the black list + + dirnames/filenames are usually from os.walk + """ + for norecurs in blacklist: + if norecurs in dirnames: + dirnames.remove(norecurs) + elif norecurs in filenames: + filenames.remove(norecurs) + + +_NORM_PATH_CACHE = {} + + +def _cache_normalize_path(path): + """abspath with caching""" + # _module_file calls abspath on every path in sys.path every time it's + # called; on a larger codebase this easily adds up to half a second just + # assembling path components. This cache alleviates that. + try: + return _NORM_PATH_CACHE[path] + except KeyError: + if not path: # don't cache result for '' + return _normalize_path(path) + result = _NORM_PATH_CACHE[path] = _normalize_path(path) + return result + + +def load_module_from_name(dotted_name, path=None, use_sys=True): + """Load a Python module from its name. + + :type dotted_name: str + :param dotted_name: python name of a module or package + + :type path: list or None + :param path: + optional list of path where the module or package should be + searched (use sys.path if nothing or None is given) + + :type use_sys: bool + :param use_sys: + boolean indicating whether the sys.modules dictionary should be + used or not + + + :raise ImportError: if the module or package is not found + + :rtype: module + :return: the loaded module + """ + return load_module_from_modpath(dotted_name.split("."), path, use_sys) + + +def load_module_from_modpath(parts, path=None, use_sys=1): + """Load a python module from its split name. + + :type parts: list(str) or tuple(str) + :param parts: + python name of a module or package split on '.' + + :type path: list or None + :param path: + optional list of path where the module or package should be + searched (use sys.path if nothing or None is given) + + :type use_sys: bool + :param use_sys: + boolean indicating whether the sys.modules dictionary should be used or not + + :raise ImportError: if the module or package is not found + + :rtype: module + :return: the loaded module + """ + if use_sys: + try: + return sys.modules[".".join(parts)] + except KeyError: + pass + modpath = [] + prevmodule = None + for part in parts: + modpath.append(part) + curname = ".".join(modpath) + module = None + if len(modpath) != len(parts): + # even with use_sys=False, should try to get outer packages from sys.modules + module = sys.modules.get(curname) + elif use_sys: + # because it may have been indirectly loaded through a parent + module = sys.modules.get(curname) + if module is None: + mp_file, mp_filename, mp_desc = imp.find_module(part, path) + module = imp.load_module(curname, mp_file, mp_filename, mp_desc) + # mp_file still needs to be closed. + if mp_file: + mp_file.close() + if prevmodule: + setattr(prevmodule, part, module) + _file = getattr(module, "__file__", "") + prevmodule = module + if not _file and util.is_namespace(curname): + continue + if not _file and len(modpath) != len(parts): + raise ImportError("no module in %s" % ".".join(parts[len(modpath) :])) + path = [os.path.dirname(_file)] + return module + + +def load_module_from_file(filepath, path=None, use_sys=True, extrapath=None): + """Load a Python module from it's path. + + :type filepath: str + :param filepath: path to the python module or package + + :type path: list or None + :param path: + optional list of path where the module or package should be + searched (use sys.path if nothing or None is given) + + :type use_sys: bool + :param use_sys: + boolean indicating whether the sys.modules dictionary should be + used or not + + + :raise ImportError: if the module or package is not found + + :rtype: module + :return: the loaded module + """ + modpath = modpath_from_file(filepath, extrapath) + return load_module_from_modpath(modpath, path, use_sys) + + +def check_modpath_has_init(path, mod_path): + """check there are some __init__.py all along the way""" + modpath = [] + for part in mod_path: + modpath.append(part) + path = os.path.join(path, part) + if not _has_init(path): + old_namespace = util.is_namespace(".".join(modpath)) + if not old_namespace: + return False + return True + + +def _get_relative_base_path(filename, path_to_check): + """Extracts the relative mod path of the file to import from + + Check if a file is within the passed in path and if so, returns the + relative mod path from the one passed in. + + If the filename is no in path_to_check, returns None + + Note this function will look for both abs and realpath of the file, + this allows to find the relative base path even if the file is a + symlink of a file in the passed in path + + Examples: + _get_relative_base_path("/a/b/c/d.py", "/a/b") -> ["c","d"] + _get_relative_base_path("/a/b/c/d.py", "/dev") -> None + """ + importable_path = None + path_to_check = os.path.normcase(path_to_check) + abs_filename = os.path.abspath(filename) + if os.path.normcase(abs_filename).startswith(path_to_check): + importable_path = abs_filename + + real_filename = os.path.realpath(filename) + if os.path.normcase(real_filename).startswith(path_to_check): + importable_path = real_filename + + if importable_path: + base_path = os.path.splitext(importable_path)[0] + relative_base_path = base_path[len(path_to_check) :] + return [pkg for pkg in relative_base_path.split(os.sep) if pkg] + + return None + + +def modpath_from_file_with_callback(filename, extrapath=None, is_package_cb=None): + filename = os.path.expanduser(_path_from_filename(filename)) + + if extrapath is not None: + for path_ in itertools.chain(map(_canonicalize_path, extrapath), extrapath): + path = os.path.abspath(path_) + if not path: + continue + submodpath = _get_relative_base_path(filename, path) + if not submodpath: + continue + if is_package_cb(path, submodpath[:-1]): + return extrapath[path_].split(".") + submodpath + + for path in itertools.chain(map(_canonicalize_path, sys.path), sys.path): + path = _cache_normalize_path(path) + if not path: + continue + modpath = _get_relative_base_path(filename, path) + if not modpath: + continue + if is_package_cb(path, modpath[:-1]): + return modpath + + raise ImportError( + "Unable to find module for %s in %s" % (filename, ", \n".join(sys.path)) + ) + + +def modpath_from_file(filename, extrapath=None): + """given a file path return the corresponding split module's name + (i.e name of a module or package split on '.') + + :type filename: str + :param filename: file's path for which we want the module's name + + :type extrapath: dict + :param extrapath: + optional extra search path, with path as key and package name for the path + as value. This is usually useful to handle package split in multiple + directories using __path__ trick. + + + :raise ImportError: + if the corresponding module's name has not been found + + :rtype: list(str) + :return: the corresponding split module's name + """ + return modpath_from_file_with_callback(filename, extrapath, check_modpath_has_init) + + +def file_from_modpath(modpath, path=None, context_file=None): + return file_info_from_modpath(modpath, path, context_file).location + + +def file_info_from_modpath(modpath, path=None, context_file=None): + """given a mod path (i.e. split module / package name), return the + corresponding file, giving priority to source file over precompiled + file if it exists + + :type modpath: list or tuple + :param modpath: + split module's name (i.e name of a module or package split + on '.') + (this means explicit relative imports that start with dots have + empty strings in this list!) + + :type path: list or None + :param path: + optional list of path where the module or package should be + searched (use sys.path if nothing or None is given) + + :type context_file: str or None + :param context_file: + context file to consider, necessary if the identifier has been + introduced using a relative import unresolvable in the actual + context (i.e. modutils) + + :raise ImportError: if there is no such module in the directory + + :rtype: (str or None, import type) + :return: + the path to the module's file or None if it's an integrated + builtin module such as 'sys' + """ + if context_file is not None: + context = os.path.dirname(context_file) + else: + context = context_file + if modpath[0] == "xml": + # handle _xmlplus + try: + return _spec_from_modpath(["_xmlplus"] + modpath[1:], path, context) + except ImportError: + return _spec_from_modpath(modpath, path, context) + elif modpath == ["os", "path"]: + # FIXME: currently ignoring search_path... + return spec.ModuleSpec( + name="os.path", location=os.path.__file__, module_type=imp.PY_SOURCE + ) + return _spec_from_modpath(modpath, path, context) + + +def get_module_part(dotted_name, context_file=None): + """given a dotted name return the module part of the name : + + >>> get_module_part('astroid.as_string.dump') + 'astroid.as_string' + + :type dotted_name: str + :param dotted_name: full name of the identifier we are interested in + + :type context_file: str or None + :param context_file: + context file to consider, necessary if the identifier has been + introduced using a relative import unresolvable in the actual + context (i.e. modutils) + + + :raise ImportError: if there is no such module in the directory + + :rtype: str or None + :return: + the module part of the name or None if we have not been able at + all to import the given name + + XXX: deprecated, since it doesn't handle package precedence over module + (see #10066) + """ + # os.path trick + if dotted_name.startswith("os.path"): + return "os.path" + parts = dotted_name.split(".") + if context_file is not None: + # first check for builtin module which won't be considered latter + # in that case (path != None) + if parts[0] in BUILTIN_MODULES: + if len(parts) > 2: + raise ImportError(dotted_name) + return parts[0] + # don't use += or insert, we want a new list to be created ! + path = None + starti = 0 + if parts[0] == "": + assert ( + context_file is not None + ), "explicit relative import, but no context_file?" + path = [] # prevent resolving the import non-relatively + starti = 1 + while parts[starti] == "": # for all further dots: change context + starti += 1 + context_file = os.path.dirname(context_file) + for i in range(starti, len(parts)): + try: + file_from_modpath( + parts[starti : i + 1], path=path, context_file=context_file + ) + except ImportError: + if i < max(1, len(parts) - 2): + raise + return ".".join(parts[:i]) + return dotted_name + + +def get_module_files(src_directory, blacklist, list_all=False): + """given a package directory return a list of all available python + module's files in the package and its subpackages + + :type src_directory: str + :param src_directory: + path of the directory corresponding to the package + + :type blacklist: list or tuple + :param blacklist: iterable + list of files or directories to ignore. + + :type list_all: bool + :param list_all: + get files from all paths, including ones without __init__.py + + :rtype: list + :return: + the list of all available python module's files in the package and + its subpackages + """ + files = [] + for directory, dirnames, filenames in os.walk(src_directory): + if directory in blacklist: + continue + _handle_blacklist(blacklist, dirnames, filenames) + # check for __init__.py + if not list_all and "__init__.py" not in filenames: + dirnames[:] = () + continue + for filename in filenames: + if _is_python_file(filename): + src = os.path.join(directory, filename) + files.append(src) + return files + + +def get_source_file(filename, include_no_ext=False): + """given a python module's file name return the matching source file + name (the filename will be returned identically if it's already an + absolute path to a python source file...) + + :type filename: str + :param filename: python module's file name + + + :raise NoSourceFile: if no source file exists on the file system + + :rtype: str + :return: the absolute path of the source file if it exists + """ + filename = os.path.abspath(_path_from_filename(filename)) + base, orig_ext = os.path.splitext(filename) + for ext in PY_SOURCE_EXTS: + source_path = "%s.%s" % (base, ext) + if os.path.exists(source_path): + return source_path + if include_no_ext and not orig_ext and os.path.exists(base): + return base + raise NoSourceFile(filename) + + +def is_python_source(filename): + """ + rtype: bool + return: True if the filename is a python source file + """ + return os.path.splitext(filename)[1][1:] in PY_SOURCE_EXTS + + +def is_standard_module(modname, std_path=None): + """try to guess if a module is a standard python module (by default, + see `std_path` parameter's description) + + :type modname: str + :param modname: name of the module we are interested in + + :type std_path: list(str) or tuple(str) + :param std_path: list of path considered has standard + + + :rtype: bool + :return: + true if the module: + - is located on the path listed in one of the directory in `std_path` + - is a built-in module + """ + modname = modname.split(".")[0] + try: + filename = file_from_modpath([modname]) + except ImportError: + # import failed, i'm probably not so wrong by supposing it's + # not standard... + return False + # modules which are not living in a file are considered standard + # (sys and __builtin__ for instance) + if filename is None: + # we assume there are no namespaces in stdlib + return not util.is_namespace(modname) + filename = _normalize_path(filename) + for path in EXT_LIB_DIRS: + if filename.startswith(_cache_normalize_path(path)): + return False + if std_path is None: + std_path = STD_LIB_DIRS + for path in std_path: + if filename.startswith(_cache_normalize_path(path)): + return True + return False + + +def is_relative(modname, from_file): + """return true if the given module name is relative to the given + file name + + :type modname: str + :param modname: name of the module we are interested in + + :type from_file: str + :param from_file: + path of the module from which modname has been imported + + :rtype: bool + :return: + true if the module has been imported relatively to `from_file` + """ + if not os.path.isdir(from_file): + from_file = os.path.dirname(from_file) + if from_file in sys.path: + return False + try: + stream, _, _ = imp.find_module(modname.split(".")[0], [from_file]) + + # Close the stream to avoid ResourceWarnings. + if stream: + stream.close() + return True + except ImportError: + return False + + +# internal only functions ##################################################### + + +def _spec_from_modpath(modpath, path=None, context=None): + """given a mod path (i.e. split module / package name), return the + corresponding spec + + this function is used internally, see `file_from_modpath`'s + documentation for more information + """ + assert modpath + location = None + if context is not None: + try: + found_spec = spec.find_spec(modpath, [context]) + location = found_spec.location + except ImportError: + found_spec = spec.find_spec(modpath, path) + location = found_spec.location + else: + found_spec = spec.find_spec(modpath, path) + if found_spec.type == spec.ModuleType.PY_COMPILED: + try: + location = get_source_file(found_spec.location) + return found_spec._replace( + location=location, type=spec.ModuleType.PY_SOURCE + ) + except NoSourceFile: + return found_spec._replace(location=location) + elif found_spec.type == spec.ModuleType.C_BUILTIN: + # integrated builtin module + return found_spec._replace(location=None) + elif found_spec.type == spec.ModuleType.PKG_DIRECTORY: + location = _has_init(found_spec.location) + return found_spec._replace(location=location, type=spec.ModuleType.PY_SOURCE) + return found_spec + + +def _is_python_file(filename): + """return true if the given filename should be considered as a python file + + .pyc and .pyo are ignored + """ + return filename.endswith((".py", ".so", ".pyd", ".pyw")) + + +def _has_init(directory): + """if the given directory has a valid __init__ file, return its path, + else return None + """ + mod_or_pack = os.path.join(directory, "__init__") + for ext in PY_SOURCE_EXTS + ("pyc", "pyo"): + if os.path.exists(mod_or_pack + "." + ext): + return mod_or_pack + "." + ext + return None + + +def is_namespace(specobj): + return specobj.type == spec.ModuleType.PY_NAMESPACE + + +def is_directory(specobj): + return specobj.type == spec.ModuleType.PKG_DIRECTORY diff --git a/py3/lib/python3.6/site-packages/astroid/node_classes.py b/py3/lib/python3.6/site-packages/astroid/node_classes.py new file mode 100644 index 0000000..994c96b --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/node_classes.py @@ -0,0 +1,4775 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2010 Daniel Harding +# Copyright (c) 2012 FELD Boris +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2016-2017 Derek Gustafson +# Copyright (c) 2016 Jared Garst +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2016 Dave Baum +# Copyright (c) 2017-2018 Ashley Whetter +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2017 rr- +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 brendanator +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 HoverHell + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +# pylint: disable=too-many-lines; https://github.com/PyCQA/astroid/issues/465 + +"""Module for some node classes. More nodes in scoped_nodes.py +""" + +import abc +import builtins as builtins_mod +import itertools +import pprint +import sys +from functools import lru_cache, singledispatch as _singledispatch + +from astroid import as_string +from astroid import bases +from astroid import context as contextmod +from astroid import decorators +from astroid import exceptions +from astroid import manager +from astroid import mixins +from astroid import util + + +BUILTINS = builtins_mod.__name__ +MANAGER = manager.AstroidManager() +PY38 = sys.version_info[:2] >= (3, 8) + + +def _is_const(value): + return isinstance(value, tuple(CONST_CLS)) + + +@decorators.raise_if_nothing_inferred +def unpack_infer(stmt, context=None): + """recursively generate nodes inferred by the given statement. + If the inferred value is a list or a tuple, recurse on the elements + """ + if isinstance(stmt, (List, Tuple)): + for elt in stmt.elts: + if elt is util.Uninferable: + yield elt + continue + yield from unpack_infer(elt, context) + return dict(node=stmt, context=context) + # if inferred is a final node, return it and stop + inferred = next(stmt.infer(context)) + if inferred is stmt: + yield inferred + return dict(node=stmt, context=context) + # else, infer recursively, except Uninferable object that should be returned as is + for inferred in stmt.infer(context): + if inferred is util.Uninferable: + yield inferred + else: + yield from unpack_infer(inferred, context) + + return dict(node=stmt, context=context) + + +def are_exclusive( + stmt1, stmt2, exceptions=None +): # pylint: disable=redefined-outer-name + """return true if the two given statements are mutually exclusive + + `exceptions` may be a list of exception names. If specified, discard If + branches and check one of the statement is in an exception handler catching + one of the given exceptions. + + algorithm : + 1) index stmt1's parents + 2) climb among stmt2's parents until we find a common parent + 3) if the common parent is a If or TryExcept statement, look if nodes are + in exclusive branches + """ + # index stmt1's parents + stmt1_parents = {} + children = {} + node = stmt1.parent + previous = stmt1 + while node: + stmt1_parents[node] = 1 + children[node] = previous + previous = node + node = node.parent + # climb among stmt2's parents until we find a common parent + node = stmt2.parent + previous = stmt2 + while node: + if node in stmt1_parents: + # if the common parent is a If or TryExcept statement, look if + # nodes are in exclusive branches + if isinstance(node, If) and exceptions is None: + if ( + node.locate_child(previous)[1] + is not node.locate_child(children[node])[1] + ): + return True + elif isinstance(node, TryExcept): + c2attr, c2node = node.locate_child(previous) + c1attr, c1node = node.locate_child(children[node]) + if c1node is not c2node: + first_in_body_caught_by_handlers = ( + c2attr == "handlers" + and c1attr == "body" + and previous.catch(exceptions) + ) + second_in_body_caught_by_handlers = ( + c2attr == "body" + and c1attr == "handlers" + and children[node].catch(exceptions) + ) + first_in_else_other_in_handlers = ( + c2attr == "handlers" and c1attr == "orelse" + ) + second_in_else_other_in_handlers = ( + c2attr == "orelse" and c1attr == "handlers" + ) + if any( + ( + first_in_body_caught_by_handlers, + second_in_body_caught_by_handlers, + first_in_else_other_in_handlers, + second_in_else_other_in_handlers, + ) + ): + return True + elif c2attr == "handlers" and c1attr == "handlers": + return previous is not children[node] + return False + previous = node + node = node.parent + return False + + +# getitem() helpers. + +_SLICE_SENTINEL = object() + + +def _slice_value(index, context=None): + """Get the value of the given slice index.""" + + if isinstance(index, Const): + if isinstance(index.value, (int, type(None))): + return index.value + elif index is None: + return None + else: + # Try to infer what the index actually is. + # Since we can't return all the possible values, + # we'll stop at the first possible value. + try: + inferred = next(index.infer(context=context)) + except exceptions.InferenceError: + pass + else: + if isinstance(inferred, Const): + if isinstance(inferred.value, (int, type(None))): + return inferred.value + + # Use a sentinel, because None can be a valid + # value that this function can return, + # as it is the case for unspecified bounds. + return _SLICE_SENTINEL + + +def _infer_slice(node, context=None): + lower = _slice_value(node.lower, context) + upper = _slice_value(node.upper, context) + step = _slice_value(node.step, context) + if all(elem is not _SLICE_SENTINEL for elem in (lower, upper, step)): + return slice(lower, upper, step) + + raise exceptions.AstroidTypeError( + message="Could not infer slice used in subscript", + node=node, + index=node.parent, + context=context, + ) + + +def _container_getitem(instance, elts, index, context=None): + """Get a slice or an item, using the given *index*, for the given sequence.""" + try: + if isinstance(index, Slice): + index_slice = _infer_slice(index, context=context) + new_cls = instance.__class__() + new_cls.elts = elts[index_slice] + new_cls.parent = instance.parent + return new_cls + if isinstance(index, Const): + return elts[index.value] + except IndexError as exc: + raise exceptions.AstroidIndexError( + message="Index {index!s} out of range", + node=instance, + index=index, + context=context, + ) from exc + except TypeError as exc: + raise exceptions.AstroidTypeError( + message="Type error {error!r}", node=instance, index=index, context=context + ) from exc + + raise exceptions.AstroidTypeError("Could not use %s as subscript index" % index) + + +OP_PRECEDENCE = { + op: precedence + for precedence, ops in enumerate( + [ + ["Lambda"], # lambda x: x + 1 + ["IfExp"], # 1 if True else 2 + ["or"], + ["and"], + ["not"], + ["Compare"], # in, not in, is, is not, <, <=, >, >=, !=, == + ["|"], + ["^"], + ["&"], + ["<<", ">>"], + ["+", "-"], + ["*", "@", "/", "//", "%"], + ["UnaryOp"], # +, -, ~ + ["**"], + ["Await"], + ] + ) + for op in ops +} + + +class NodeNG: + """ A node of the new Abstract Syntax Tree (AST). + + This is the base class for all Astroid node classes. + """ + + is_statement = False + """Whether this node indicates a statement. + + :type: bool + """ + optional_assign = False # True for For (and for Comprehension if py <3.0) + """Whether this node optionally assigns a variable. + + This is for loop assignments because loop won't necessarily perform an + assignment if the loop has no iterations. + This is also the case from comprehensions in Python 2. + + :type: bool + """ + is_function = False # True for FunctionDef nodes + """Whether this node indicates a function. + + :type: bool + """ + is_lambda = False + # Attributes below are set by the builder module or by raw factories + lineno = None + """The line that this node appears on in the source code. + + :type: int or None + """ + col_offset = None + """The column that this node appears on in the source code. + + :type: int or None + """ + parent = None + """The parent node in the syntax tree. + + :type: NodeNG or None + """ + _astroid_fields = () + """Node attributes that contain child nodes. + + This is redefined in most concrete classes. + + :type: tuple(str) + """ + _other_fields = () + """Node attributes that do not contain child nodes. + + :type: tuple(str) + """ + _other_other_fields = () + """Attributes that contain AST-dependent fields. + + :type: tuple(str) + """ + # instance specific inference function infer(node, context) + _explicit_inference = None + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.lineno = lineno + self.col_offset = col_offset + self.parent = parent + + def infer(self, context=None, **kwargs): + """Get a generator of the inferred values. + + This is the main entry point to the inference system. + + .. seealso:: :ref:`inference` + + If the instance has some explicit inference function set, it will be + called instead of the default interface. + + :returns: The inferred values. + :rtype: iterable + """ + if context is not None: + context = context.extra_context.get(self, context) + if self._explicit_inference is not None: + # explicit_inference is not bound, give it self explicitly + try: + # pylint: disable=not-callable + return self._explicit_inference(self, context, **kwargs) + except exceptions.UseInferenceDefault: + pass + + if not context: + return self._infer(context, **kwargs) + + key = (self, context.lookupname, context.callcontext, context.boundnode) + if key in context.inferred: + return iter(context.inferred[key]) + + gen = context.cache_generator(key, self._infer(context, **kwargs)) + return util.limit_inference(gen, MANAGER.max_inferable_values) + + def _repr_name(self): + """Get a name for nice representation. + + This is either :attr:`name`, :attr:`attrname`, or the empty string. + + :returns: The nice name. + :rtype: str + """ + names = {"name", "attrname"} + if all(name not in self._astroid_fields for name in names): + return getattr(self, "name", getattr(self, "attrname", "")) + return "" + + def __str__(self): + rname = self._repr_name() + cname = type(self).__name__ + if rname: + string = "%(cname)s.%(rname)s(%(fields)s)" + alignment = len(cname) + len(rname) + 2 + else: + string = "%(cname)s(%(fields)s)" + alignment = len(cname) + 1 + result = [] + for field in self._other_fields + self._astroid_fields: + value = getattr(self, field) + width = 80 - len(field) - alignment + lines = pprint.pformat(value, indent=2, width=width).splitlines(True) + + inner = [lines[0]] + for line in lines[1:]: + inner.append(" " * alignment + line) + result.append("%s=%s" % (field, "".join(inner))) + + return string % { + "cname": cname, + "rname": rname, + "fields": (",\n" + " " * alignment).join(result), + } + + def __repr__(self): + rname = self._repr_name() + if rname: + string = "<%(cname)s.%(rname)s l.%(lineno)s at 0x%(id)x>" + else: + string = "<%(cname)s l.%(lineno)s at 0x%(id)x>" + return string % { + "cname": type(self).__name__, + "rname": rname, + "lineno": self.fromlineno, + "id": id(self), + } + + def accept(self, visitor): + """Visit this node using the given visitor.""" + func = getattr(visitor, "visit_" + self.__class__.__name__.lower()) + return func(self) + + def get_children(self): + """Get the child nodes below this node. + + :returns: The children. + :rtype: iterable(NodeNG) + """ + for field in self._astroid_fields: + attr = getattr(self, field) + if attr is None: + continue + if isinstance(attr, (list, tuple)): + yield from attr + else: + yield attr + + def last_child(self): + """An optimized version of list(get_children())[-1] + + :returns: The last child, or None if no children exist. + :rtype: NodeNG or None + """ + for field in self._astroid_fields[::-1]: + attr = getattr(self, field) + if not attr: # None or empty listy / tuple + continue + if isinstance(attr, (list, tuple)): + return attr[-1] + + return attr + return None + + def parent_of(self, node): + """Check if this node is the parent of the given node. + + :param node: The node to check if it is the child. + :type node: NodeNG + + :returns: True if this node is the parent of the given node, + False otherwise. + :rtype: bool + """ + parent = node.parent + while parent is not None: + if self is parent: + return True + parent = parent.parent + return False + + def statement(self): + """The first parent node, including self, marked as statement node. + + :returns: The first parent statement. + :rtype: NodeNG + """ + if self.is_statement: + return self + return self.parent.statement() + + def frame(self): + """The first parent frame node. + + A frame node is a :class:`Module`, :class:`FunctionDef`, + or :class:`ClassDef`. + + :returns: The first parent frame node. + :rtype: Module or FunctionDef or ClassDef + """ + return self.parent.frame() + + def scope(self): + """The first parent node defining a new scope. + + :returns: The first parent scope node. + :rtype: Module or FunctionDef or ClassDef or Lambda or GenExpr + """ + if self.parent: + return self.parent.scope() + return None + + def root(self): + """Return the root node of the syntax tree. + + :returns: The root node. + :rtype: Module + """ + if self.parent: + return self.parent.root() + return self + + def child_sequence(self, child): + """Search for the sequence that contains this child. + + :param child: The child node to search sequences for. + :type child: NodeNG + + :returns: The sequence containing the given child node. + :rtype: iterable(NodeNG) + + :raises AstroidError: If no sequence could be found that contains + the given child. + """ + for field in self._astroid_fields: + node_or_sequence = getattr(self, field) + if node_or_sequence is child: + return [node_or_sequence] + # /!\ compiler.ast Nodes have an __iter__ walking over child nodes + if ( + isinstance(node_or_sequence, (tuple, list)) + and child in node_or_sequence + ): + return node_or_sequence + + msg = "Could not find %s in %s's children" + raise exceptions.AstroidError(msg % (repr(child), repr(self))) + + def locate_child(self, child): + """Find the field of this node that contains the given child. + + :param child: The child node to search fields for. + :type child: NodeNG + + :returns: A tuple of the name of the field that contains the child, + and the sequence or node that contains the child node. + :rtype: tuple(str, iterable(NodeNG) or NodeNG) + + :raises AstroidError: If no field could be found that contains + the given child. + """ + for field in self._astroid_fields: + node_or_sequence = getattr(self, field) + # /!\ compiler.ast Nodes have an __iter__ walking over child nodes + if child is node_or_sequence: + return field, child + if ( + isinstance(node_or_sequence, (tuple, list)) + and child in node_or_sequence + ): + return field, node_or_sequence + msg = "Could not find %s in %s's children" + raise exceptions.AstroidError(msg % (repr(child), repr(self))) + + # FIXME : should we merge child_sequence and locate_child ? locate_child + # is only used in are_exclusive, child_sequence one time in pylint. + + def next_sibling(self): + """The next sibling statement node. + + :returns: The next sibling statement node. + :rtype: NodeNG or None + """ + return self.parent.next_sibling() + + def previous_sibling(self): + """The previous sibling statement. + + :returns: The previous sibling statement node. + :rtype: NodeNG or None + """ + return self.parent.previous_sibling() + + # these are lazy because they're relatively expensive to compute for every + # single node, and they rarely get looked at + + @decorators.cachedproperty + def fromlineno(self): + """The first line that this node appears on in the source code. + + :type: int or None + """ + if self.lineno is None: + return self._fixed_source_line() + + return self.lineno + + @decorators.cachedproperty + def tolineno(self): + """The last line that this node appears on in the source code. + + :type: int or None + """ + if not self._astroid_fields: + # can't have children + lastchild = None + else: + lastchild = self.last_child() + if lastchild is None: + return self.fromlineno + + return lastchild.tolineno + + def _fixed_source_line(self): + """Attempt to find the line that this node appears on. + + We need this method since not all nodes have :attr:`lineno` set. + + :returns: The line number of this node, + or None if this could not be determined. + :rtype: int or None + """ + line = self.lineno + _node = self + try: + while line is None: + _node = next(_node.get_children()) + line = _node.lineno + except StopIteration: + _node = self.parent + while _node and line is None: + line = _node.lineno + _node = _node.parent + return line + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: The line number to start the range at. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + starting at the given line number. + :rtype: tuple(int, int or None) + """ + return lineno, self.tolineno + + def set_local(self, name, stmt): + """Define that the given name is declared in the given statement node. + + This definition is stored on the parent scope node. + + .. seealso:: :meth:`scope` + + :param name: The name that is being defined. + :type name: str + + :param stmt: The statement that defines the given name. + :type stmt: NodeNG + """ + self.parent.set_local(name, stmt) + + def nodes_of_class(self, klass, skip_klass=None): + """Get the nodes (including this one or below) of the given types. + + :param klass: The types of node to search for. + :type klass: builtins.type or tuple(builtins.type) + + :param skip_klass: The types of node to ignore. This is useful to ignore + subclasses of :attr:`klass`. + :type skip_klass: builtins.type or tuple(builtins.type) + + :returns: The node of the given types. + :rtype: iterable(NodeNG) + """ + if isinstance(self, klass): + yield self + + if skip_klass is None: + for child_node in self.get_children(): + yield from child_node.nodes_of_class(klass, skip_klass) + + return + + for child_node in self.get_children(): + if isinstance(child_node, skip_klass): + continue + yield from child_node.nodes_of_class(klass, skip_klass) + + @decorators.cached + def _get_assign_nodes(self): + return [] + + def _get_name_nodes(self): + for child_node in self.get_children(): + yield from child_node._get_name_nodes() + + def _get_return_nodes_skip_functions(self): + yield from () + + def _get_yield_nodes_skip_lambdas(self): + yield from () + + def _infer_name(self, frame, name): + # overridden for ImportFrom, Import, Global, TryExcept and Arguments + pass + + def _infer(self, context=None): + """we don't know how to resolve a statement by default""" + # this method is overridden by most concrete classes + raise exceptions.InferenceError( + "No inference function for {node!r}.", node=self, context=context + ) + + def inferred(self): + """Get a list of the inferred values. + + .. seealso:: :ref:`inference` + + :returns: The inferred values. + :rtype: list + """ + return list(self.infer()) + + def instantiate_class(self): + """Instantiate an instance of the defined class. + + .. note:: + + On anything other than a :class:`ClassDef` this will return self. + + :returns: An instance of the defined class. + :rtype: object + """ + return self + + def has_base(self, node): + """Check if this node inherits from the given type. + + :param node: The node defining the base to look for. + Usually this is a :class:`Name` node. + :type node: NodeNG + """ + return False + + def callable(self): + """Whether this node defines something that is callable. + + :returns: True if this defines something that is callable, + False otherwise. + :rtype: bool + """ + return False + + def eq(self, value): + return False + + def as_string(self): + """Get the source code that this node represents. + + :returns: The source code. + :rtype: str + """ + return as_string.to_code(self) + + def repr_tree( + self, + ids=False, + include_linenos=False, + ast_state=False, + indent=" ", + max_depth=0, + max_width=80, + ): + """Get a string representation of the AST from this node. + + :param ids: If true, includes the ids with the node type names. + :type ids: bool + + :param include_linenos: If true, includes the line numbers and + column offsets. + :type include_linenos: bool + + :param ast_state: If true, includes information derived from + the whole AST like local and global variables. + :type ast_state: bool + + :param indent: A string to use to indent the output string. + :type indent: str + + :param max_depth: If set to a positive integer, won't return + nodes deeper than max_depth in the string. + :type max_depth: int + + :param max_width: Attempt to format the output string to stay + within this number of characters, but can exceed it under some + circumstances. Only positive integer values are valid, the default is 80. + :type max_width: int + + :returns: The string representation of the AST. + :rtype: str + """ + # pylint: disable=too-many-statements + @_singledispatch + def _repr_tree(node, result, done, cur_indent="", depth=1): + """Outputs a representation of a non-tuple/list, non-node that's + contained within an AST, including strings. + """ + lines = pprint.pformat( + node, width=max(max_width - len(cur_indent), 1) + ).splitlines(True) + result.append(lines[0]) + result.extend([cur_indent + line for line in lines[1:]]) + return len(lines) != 1 + + # pylint: disable=unused-variable; doesn't understand singledispatch + @_repr_tree.register(tuple) + @_repr_tree.register(list) + def _repr_seq(node, result, done, cur_indent="", depth=1): + """Outputs a representation of a sequence that's contained within an AST.""" + cur_indent += indent + result.append("[") + if not node: + broken = False + elif len(node) == 1: + broken = _repr_tree(node[0], result, done, cur_indent, depth) + elif len(node) == 2: + broken = _repr_tree(node[0], result, done, cur_indent, depth) + if not broken: + result.append(", ") + else: + result.append(",\n") + result.append(cur_indent) + broken = _repr_tree(node[1], result, done, cur_indent, depth) or broken + else: + result.append("\n") + result.append(cur_indent) + for child in node[:-1]: + _repr_tree(child, result, done, cur_indent, depth) + result.append(",\n") + result.append(cur_indent) + _repr_tree(node[-1], result, done, cur_indent, depth) + broken = True + result.append("]") + return broken + + # pylint: disable=unused-variable; doesn't understand singledispatch + @_repr_tree.register(NodeNG) + def _repr_node(node, result, done, cur_indent="", depth=1): + """Outputs a strings representation of an astroid node.""" + if node in done: + result.append( + indent + + " max_depth: + result.append("...") + return False + depth += 1 + cur_indent += indent + if ids: + result.append("%s<0x%x>(\n" % (type(node).__name__, id(node))) + else: + result.append("%s(" % type(node).__name__) + fields = [] + if include_linenos: + fields.extend(("lineno", "col_offset")) + fields.extend(node._other_fields) + fields.extend(node._astroid_fields) + if ast_state: + fields.extend(node._other_other_fields) + if not fields: + broken = False + elif len(fields) == 1: + result.append("%s=" % fields[0]) + broken = _repr_tree( + getattr(node, fields[0]), result, done, cur_indent, depth + ) + else: + result.append("\n") + result.append(cur_indent) + for field in fields[:-1]: + result.append("%s=" % field) + _repr_tree(getattr(node, field), result, done, cur_indent, depth) + result.append(",\n") + result.append(cur_indent) + result.append("%s=" % fields[-1]) + _repr_tree(getattr(node, fields[-1]), result, done, cur_indent, depth) + broken = True + result.append(")") + return broken + + result = [] + _repr_tree(self, result, set()) + return "".join(result) + + def bool_value(self): + """Determine the boolean value of this node. + + The boolean value of a node can have three + possible values: + + * False: For instance, empty data structures, + False, empty strings, instances which return + explicitly False from the __nonzero__ / __bool__ + method. + * True: Most of constructs are True by default: + classes, functions, modules etc + * Uninferable: The inference engine is uncertain of the + node's value. + + :returns: The boolean value of this node. + :rtype: bool or Uninferable + """ + return util.Uninferable + + def op_precedence(self): + # Look up by class name or default to highest precedence + return OP_PRECEDENCE.get(self.__class__.__name__, len(OP_PRECEDENCE)) + + def op_left_associative(self): + # Everything is left associative except `**` and IfExp + return True + + +class Statement(NodeNG): + """Statement node adding a few attributes""" + + is_statement = True + """Whether this node indicates a statement. + + :type: bool + """ + + def next_sibling(self): + """The next sibling statement node. + + :returns: The next sibling statement node. + :rtype: NodeNG or None + """ + stmts = self.parent.child_sequence(self) + index = stmts.index(self) + try: + return stmts[index + 1] + except IndexError: + pass + + def previous_sibling(self): + """The previous sibling statement. + + :returns: The previous sibling statement node. + :rtype: NodeNG or None + """ + stmts = self.parent.child_sequence(self) + index = stmts.index(self) + if index >= 1: + return stmts[index - 1] + return None + + +class _BaseContainer( + mixins.ParentAssignTypeMixin, NodeNG, bases.Instance, metaclass=abc.ABCMeta +): + """Base class for Set, FrozenSet, Tuple and List.""" + + _astroid_fields = ("elts",) + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.elts = [] + """The elements in the node. + + :type: list(NodeNG) + """ + + super(_BaseContainer, self).__init__(lineno, col_offset, parent) + + def postinit(self, elts): + """Do some setup after initialisation. + + :param elts: The list of elements the that node contains. + :type elts: list(NodeNG) + """ + self.elts = elts + + @classmethod + def from_elements(cls, elts=None): + """Create a node of this type from the given list of elements. + + :param elts: The list of elements that the node should contain. + :type elts: list(NodeNG) + + :returns: A new node containing the given elements. + :rtype: NodeNG + """ + node = cls() + if elts is None: + node.elts = [] + else: + node.elts = [const_factory(e) if _is_const(e) else e for e in elts] + return node + + def itered(self): + """An iterator over the elements this node contains. + + :returns: The contents of this node. + :rtype: iterable(NodeNG) + """ + return self.elts + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + :rtype: bool or Uninferable + """ + return bool(self.elts) + + @abc.abstractmethod + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + + def get_children(self): + yield from self.elts + + +class LookupMixIn: + """Mixin to look up a name in the right scope.""" + + @lru_cache(maxsize=None) + def lookup(self, name): + """Lookup where the given variable is assigned. + + The lookup starts from self's scope. If self is not a frame itself + and the name is found in the inner frame locals, statements will be + filtered to remove ignorable statements according to self's location. + + :param name: The name of the variable to find assignments for. + :type name: str + + :returns: The scope node and the list of assignments associated to the + given name according to the scope where it has been found (locals, + globals or builtin). + :rtype: tuple(str, list(NodeNG)) + """ + return self.scope().scope_lookup(self, name) + + def ilookup(self, name): + """Lookup the inferred values of the given variable. + + :param name: The variable name to find values for. + :type name: str + + :returns: The inferred values of the statements returned from + :meth:`lookup`. + :rtype: iterable + """ + frame, stmts = self.lookup(name) + context = contextmod.InferenceContext() + return bases._infer_stmts(stmts, context, frame) + + def _get_filtered_node_statements(self, nodes): + statements = [(node, node.statement()) for node in nodes] + # Next we check if we have ExceptHandlers that are parent + # of the underlying variable, in which case the last one survives + if len(statements) > 1 and all( + isinstance(stmt, ExceptHandler) for _, stmt in statements + ): + statements = [ + (node, stmt) for node, stmt in statements if stmt.parent_of(self) + ] + return statements + + def _filter_stmts(self, stmts, frame, offset): + """Filter the given list of statements to remove ignorable statements. + + If self is not a frame itself and the name is found in the inner + frame locals, statements will be filtered to remove ignorable + statements according to self's location. + + :param stmts: The statements to filter. + :type stmts: list(NodeNG) + + :param frame: The frame that all of the given statements belong to. + :type frame: NodeNG + + :param offset: The line offset to filter statements up to. + :type offset: int + + :returns: The filtered statements. + :rtype: list(NodeNG) + """ + # if offset == -1, my actual frame is not the inner frame but its parent + # + # class A(B): pass + # + # we need this to resolve B correctly + if offset == -1: + myframe = self.frame().parent.frame() + else: + myframe = self.frame() + # If the frame of this node is the same as the statement + # of this node, then the node is part of a class or + # a function definition and the frame of this node should be the + # the upper frame, not the frame of the definition. + # For more information why this is important, + # see Pylint issue #295. + # For example, for 'b', the statement is the same + # as the frame / scope: + # + # def test(b=1): + # ... + + if self.statement() is myframe and myframe.parent: + myframe = myframe.parent.frame() + mystmt = self.statement() + # line filtering if we are in the same frame + # + # take care node may be missing lineno information (this is the case for + # nodes inserted for living objects) + if myframe is frame and mystmt.fromlineno is not None: + assert mystmt.fromlineno is not None, mystmt + mylineno = mystmt.fromlineno + offset + else: + # disabling lineno filtering + mylineno = 0 + + _stmts = [] + _stmt_parents = [] + statements = self._get_filtered_node_statements(stmts) + + for node, stmt in statements: + # line filtering is on and we have reached our location, break + if stmt.fromlineno > mylineno > 0: + break + # Ignore decorators with the same name as the + # decorated function + # Fixes issue #375 + if mystmt is stmt and is_from_decorator(self): + continue + assert hasattr(node, "assign_type"), ( + node, + node.scope(), + node.scope().locals, + ) + assign_type = node.assign_type() + if node.has_base(self): + break + + _stmts, done = assign_type._get_filtered_stmts(self, node, _stmts, mystmt) + if done: + break + + optional_assign = assign_type.optional_assign + if optional_assign and assign_type.parent_of(self): + # we are inside a loop, loop var assignment is hiding previous + # assignment + _stmts = [node] + _stmt_parents = [stmt.parent] + continue + + if isinstance(assign_type, NamedExpr): + _stmts = [node] + continue + + # XXX comment various branches below!!! + try: + pindex = _stmt_parents.index(stmt.parent) + except ValueError: + pass + else: + # we got a parent index, this means the currently visited node + # is at the same block level as a previously visited node + if _stmts[pindex].assign_type().parent_of(assign_type): + # both statements are not at the same block level + continue + # if currently visited node is following previously considered + # assignment and both are not exclusive, we can drop the + # previous one. For instance in the following code :: + # + # if a: + # x = 1 + # else: + # x = 2 + # print x + # + # we can't remove neither x = 1 nor x = 2 when looking for 'x' + # of 'print x'; while in the following :: + # + # x = 1 + # x = 2 + # print x + # + # we can remove x = 1 when we see x = 2 + # + # moreover, on loop assignment types, assignment won't + # necessarily be done if the loop has no iteration, so we don't + # want to clear previous assignments if any (hence the test on + # optional_assign) + if not (optional_assign or are_exclusive(_stmts[pindex], node)): + if ( + # In case of partial function node, if the statement is different + # from the origin function then it can be deleted otherwise it should + # remain to be able to correctly infer the call to origin function. + not node.is_function + or node.qname() != "PartialFunction" + or node.name != _stmts[pindex].name + ): + del _stmt_parents[pindex] + del _stmts[pindex] + if isinstance(node, AssignName): + if not optional_assign and stmt.parent is mystmt.parent: + _stmts = [] + _stmt_parents = [] + elif isinstance(node, DelName): + _stmts = [] + _stmt_parents = [] + continue + if not are_exclusive(self, node): + _stmts.append(node) + _stmt_parents.append(stmt.parent) + return _stmts + + +# Name classes + + +class AssignName( + mixins.NoChildrenMixin, LookupMixIn, mixins.ParentAssignTypeMixin, NodeNG +): + """Variation of :class:`ast.Assign` representing assignment to a name. + + An :class:`AssignName` is the name of something that is assigned to. + This includes variables defined in a function signature or in a loop. + + >>> node = astroid.extract_node('variable = range(10)') + >>> node + + >>> list(node.get_children()) + [, ] + >>> list(node.get_children())[0].as_string() + 'variable' + """ + + _other_fields = ("name",) + + def __init__(self, name=None, lineno=None, col_offset=None, parent=None): + """ + :param name: The name that is assigned to. + :type name: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.name = name + """The name that is assigned to. + + :type: str or None + """ + + super(AssignName, self).__init__(lineno, col_offset, parent) + + +class DelName( + mixins.NoChildrenMixin, LookupMixIn, mixins.ParentAssignTypeMixin, NodeNG +): + """Variation of :class:`ast.Delete` representing deletion of a name. + + A :class:`DelName` is the name of something that is deleted. + + >>> node = astroid.extract_node("del variable #@") + >>> list(node.get_children()) + [] + >>> list(node.get_children())[0].as_string() + 'variable' + """ + + _other_fields = ("name",) + + def __init__(self, name=None, lineno=None, col_offset=None, parent=None): + """ + :param name: The name that is being deleted. + :type name: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.name = name + """The name that is being deleted. + + :type: str or None + """ + + super(DelName, self).__init__(lineno, col_offset, parent) + + +class Name(mixins.NoChildrenMixin, LookupMixIn, NodeNG): + """Class representing an :class:`ast.Name` node. + + A :class:`Name` node is something that is named, but not covered by + :class:`AssignName` or :class:`DelName`. + + >>> node = astroid.extract_node('range(10)') + >>> node + + >>> list(node.get_children()) + [, ] + >>> list(node.get_children())[0].as_string() + 'range' + """ + + _other_fields = ("name",) + + def __init__(self, name=None, lineno=None, col_offset=None, parent=None): + """ + :param name: The name that this node refers to. + :type name: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.name = name + """The name that this node refers to. + + :type: str or None + """ + + super(Name, self).__init__(lineno, col_offset, parent) + + def _get_name_nodes(self): + yield self + + for child_node in self.get_children(): + yield from child_node._get_name_nodes() + + +class Arguments(mixins.AssignTypeMixin, NodeNG): + """Class representing an :class:`ast.arguments` node. + + An :class:`Arguments` node represents that arguments in a + function definition. + + >>> node = astroid.extract_node('def foo(bar): pass') + >>> node + + >>> node.args + + """ + + # Python 3.4+ uses a different approach regarding annotations, + # each argument is a new class, _ast.arg, which exposes an + # 'annotation' attribute. In astroid though, arguments are exposed + # as is in the Arguments node and the only way to expose annotations + # is by using something similar with Python 3.3: + # - we expose 'varargannotation' and 'kwargannotation' of annotations + # of varargs and kwargs. + # - we expose 'annotation', a list with annotations for + # for each normal argument. If an argument doesn't have an + # annotation, its value will be None. + + _astroid_fields = ( + "args", + "defaults", + "kwonlyargs", + "posonlyargs", + "kw_defaults", + "annotations", + "varargannotation", + "kwargannotation", + "kwonlyargs_annotations", + "type_comment_args", + ) + varargannotation = None + """The type annotation for the variable length arguments. + + :type: NodeNG + """ + kwargannotation = None + """The type annotation for the variable length keyword arguments. + + :type: NodeNG + """ + + _other_fields = ("vararg", "kwarg") + + def __init__(self, vararg=None, kwarg=None, parent=None): + """ + :param vararg: The name of the variable length arguments. + :type vararg: str or None + + :param kwarg: The name of the variable length keyword arguments. + :type kwarg: str or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + super(Arguments, self).__init__(parent=parent) + self.vararg = vararg + """The name of the variable length arguments. + + :type: str or None + """ + + self.kwarg = kwarg + """The name of the variable length keyword arguments. + + :type: str or None + """ + + self.args = [] + """The names of the required arguments. + + :type: list(AssignName) + """ + + self.defaults = [] + """The default values for arguments that can be passed positionally. + + :type: list(NodeNG) + """ + + self.kwonlyargs = [] + """The keyword arguments that cannot be passed positionally. + + :type: list(AssignName) + """ + + self.posonlyargs = [] + """The arguments that can only be passed positionally. + + :type: list(AssignName) + """ + + self.kw_defaults = [] + """The default values for keyword arguments that cannot be passed positionally. + + :type: list(NodeNG) + """ + + self.annotations = [] + """The type annotations of arguments that can be passed positionally. + + :type: list(NodeNG) + """ + + self.posonlyargs_annotations = [] + """The type annotations of arguments that can only be passed positionally. + + :type: list(NodeNG) + """ + + self.kwonlyargs_annotations = [] + """The type annotations of arguments that cannot be passed positionally. + + :type: list(NodeNG) + """ + + self.type_comment_args = [] + """The type annotation, passed by a type comment, of each argument. + + If an argument does not have a type comment, + the value for that argument will be None. + + :type: list(NodeNG or None) + """ + + # pylint: disable=too-many-arguments + def postinit( + self, + args, + defaults, + kwonlyargs, + kw_defaults, + annotations, + posonlyargs=None, + kwonlyargs_annotations=None, + posonlyargs_annotations=None, + varargannotation=None, + kwargannotation=None, + type_comment_args=None, + ): + """Do some setup after initialisation. + + :param args: The names of the required arguments. + :type args: list(AssignName) + + :param defaults: The default values for arguments that can be passed + positionally. + :type defaults: list(NodeNG) + + :param kwonlyargs: The keyword arguments that cannot be passed + positionally. + :type kwonlyargs: list(AssignName) + + :param posonlyargs: The arguments that can only be passed + positionally. + :type kwonlyargs: list(AssignName) + + :param kw_defaults: The default values for keyword arguments that + cannot be passed positionally. + :type kw_defaults: list(NodeNG) + + :param annotations: The type annotations of arguments that can be + passed positionally. + :type annotations: list(NodeNG) + + :param kwonlyargs_annotations: The type annotations of arguments that + cannot be passed positionally. This should always be passed in + Python 3. + :type kwonlyargs_annotations: list(NodeNG) + + :param posonlyargs_annotations: The type annotations of arguments that + can only be passed positionally. This should always be passed in + Python 3. + :type posonlyargs_annotations: list(NodeNG) + + :param varargannotation: The type annotation for the variable length + arguments. + :type varargannotation: NodeNG + + :param kwargannotation: The type annotation for the variable length + keyword arguments. + :type kwargannotation: NodeNG + + :param type_comment_args: The type annotation, + passed by a type comment, of each argument. + :type type_comment_args: list(NodeNG or None) + """ + self.args = args + self.defaults = defaults + self.kwonlyargs = kwonlyargs + self.posonlyargs = posonlyargs + self.kw_defaults = kw_defaults + self.annotations = annotations + self.kwonlyargs_annotations = kwonlyargs_annotations + self.posonlyargs_annotations = posonlyargs_annotations + self.varargannotation = varargannotation + self.kwargannotation = kwargannotation + self.type_comment_args = type_comment_args + + # pylint: disable=too-many-arguments + + def _infer_name(self, frame, name): + if self.parent is frame: + return name + return None + + @decorators.cachedproperty + def fromlineno(self): + """The first line that this node appears on in the source code. + + :type: int or None + """ + lineno = super(Arguments, self).fromlineno + return max(lineno, self.parent.fromlineno or 0) + + def format_args(self): + """Get the arguments formatted as string. + + :returns: The formatted arguments. + :rtype: str + """ + result = [] + positional_only_defaults = [] + positional_or_keyword_defaults = self.defaults + if self.defaults: + args = self.args or [] + positional_or_keyword_defaults = self.defaults[-len(args) :] + positional_only_defaults = self.defaults[: len(self.defaults) - len(args)] + + if self.posonlyargs: + result.append(_format_args(self.posonlyargs, positional_only_defaults)) + result.append("/") + if self.args: + result.append( + _format_args( + self.args, + positional_or_keyword_defaults, + getattr(self, "annotations", None), + ) + ) + if self.vararg: + result.append("*%s" % self.vararg) + if self.kwonlyargs: + if not self.vararg: + result.append("*") + result.append( + _format_args( + self.kwonlyargs, self.kw_defaults, self.kwonlyargs_annotations + ) + ) + if self.kwarg: + result.append("**%s" % self.kwarg) + return ", ".join(result) + + def default_value(self, argname): + """Get the default value for an argument. + + :param argname: The name of the argument to get the default value for. + :type argname: str + + :raises NoDefault: If there is no default value defined for the + given argument. + """ + args = list(itertools.chain((self.posonlyargs or ()), self.args or ())) + index = _find_arg(argname, args)[0] + if index is not None: + idx = index - (len(args) - len(self.defaults)) + if idx >= 0: + return self.defaults[idx] + index = _find_arg(argname, self.kwonlyargs)[0] + if index is not None and self.kw_defaults[index] is not None: + return self.kw_defaults[index] + raise exceptions.NoDefault(func=self.parent, name=argname) + + def is_argument(self, name): + """Check if the given name is defined in the arguments. + + :param name: The name to check for. + :type name: str + + :returns: True if the given name is defined in the arguments, + False otherwise. + :rtype: bool + """ + if name == self.vararg: + return True + if name == self.kwarg: + return True + return ( + self.find_argname(name, rec=True)[1] is not None + or self.kwonlyargs + and _find_arg(name, self.kwonlyargs, rec=True)[1] is not None + ) + + def find_argname(self, argname, rec=False): + """Get the index and :class:`AssignName` node for given name. + + :param argname: The name of the argument to search for. + :type argname: str + + :param rec: Whether or not to include arguments in unpacked tuples + in the search. + :type rec: bool + + :returns: The index and node for the argument. + :rtype: tuple(str or None, AssignName or None) + """ + if ( + self.args or self.posonlyargs + ): # self.args may be None in some cases (builtin function) + arguments = itertools.chain(self.posonlyargs or (), self.args or ()) + return _find_arg(argname, arguments, rec) + return None, None + + def get_children(self): + yield from self.posonlyargs or () + yield from self.args or () + + yield from self.defaults + yield from self.kwonlyargs + + for elt in self.kw_defaults: + if elt is not None: + yield elt + + for elt in self.annotations: + if elt is not None: + yield elt + + if self.varargannotation is not None: + yield self.varargannotation + + if self.kwargannotation is not None: + yield self.kwargannotation + + for elt in self.kwonlyargs_annotations: + if elt is not None: + yield elt + + +def _find_arg(argname, args, rec=False): + for i, arg in enumerate(args): + if isinstance(arg, Tuple): + if rec: + found = _find_arg(argname, arg.elts) + if found[0] is not None: + return found + elif arg.name == argname: + return i, arg + return None, None + + +def _format_args(args, defaults=None, annotations=None): + values = [] + if args is None: + return "" + if annotations is None: + annotations = [] + if defaults is not None: + default_offset = len(args) - len(defaults) + packed = itertools.zip_longest(args, annotations) + for i, (arg, annotation) in enumerate(packed): + if isinstance(arg, Tuple): + values.append("(%s)" % _format_args(arg.elts)) + else: + argname = arg.name + default_sep = "=" + if annotation is not None: + argname += ": " + annotation.as_string() + default_sep = " = " + values.append(argname) + + if defaults is not None and i >= default_offset: + if defaults[i - default_offset] is not None: + values[-1] += default_sep + defaults[i - default_offset].as_string() + return ", ".join(values) + + +class AssignAttr(mixins.ParentAssignTypeMixin, NodeNG): + """Variation of :class:`ast.Assign` representing assignment to an attribute. + + >>> node = astroid.extract_node('self.attribute = range(10)') + >>> node + + >>> list(node.get_children()) + [, ] + >>> list(node.get_children())[0].as_string() + 'self.attribute' + """ + + _astroid_fields = ("expr",) + _other_fields = ("attrname",) + expr = None + """What has the attribute that is being assigned to. + + :type: NodeNG or None + """ + + def __init__(self, attrname=None, lineno=None, col_offset=None, parent=None): + """ + :param attrname: The name of the attribute being assigned to. + :type attrname: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.attrname = attrname + """The name of the attribute being assigned to. + + :type: str or None + """ + + super(AssignAttr, self).__init__(lineno, col_offset, parent) + + def postinit(self, expr=None): + """Do some setup after initialisation. + + :param expr: What has the attribute that is being assigned to. + :type expr: NodeNG or None + """ + self.expr = expr + + def get_children(self): + yield self.expr + + +class Assert(Statement): + """Class representing an :class:`ast.Assert` node. + + An :class:`Assert` node represents an assert statement. + + >>> node = astroid.extract_node('assert len(things) == 10, "Not enough things"') + >>> node + + """ + + _astroid_fields = ("test", "fail") + test = None + """The test that passes or fails the assertion. + + :type: NodeNG or None + """ + fail = None + """The message shown when the assertion fails. + + :type: NodeNG or None + """ + + def postinit(self, test=None, fail=None): + """Do some setup after initialisation. + + :param test: The test that passes or fails the assertion. + :type test: NodeNG or None + + :param fail: The message shown when the assertion fails. + :type fail: NodeNG or None + """ + self.fail = fail + self.test = test + + def get_children(self): + yield self.test + + if self.fail is not None: + yield self.fail + + +class Assign(mixins.AssignTypeMixin, Statement): + """Class representing an :class:`ast.Assign` node. + + An :class:`Assign` is a statement where something is explicitly + asssigned to. + + >>> node = astroid.extract_node('variable = range(10)') + >>> node + + """ + + _astroid_fields = ("targets", "value") + _other_other_fields = ("type_annotation",) + targets = None + """What is being assigned to. + + :type: list(NodeNG) or None + """ + value = None + """The value being assigned to the variables. + + :type: NodeNG or None + """ + type_annotation = None + """If present, this will contain the type annotation passed by a type comment + + :type: NodeNG or None + """ + + def postinit(self, targets=None, value=None, type_annotation=None): + """Do some setup after initialisation. + + :param targets: What is being assigned to. + :type targets: list(NodeNG) or None + + :param value: The value being assigned to the variables. + :type: NodeNG or None + """ + self.targets = targets + self.value = value + self.type_annotation = type_annotation + + def get_children(self): + yield from self.targets + + yield self.value + + @decorators.cached + def _get_assign_nodes(self): + return [self] + list(self.value._get_assign_nodes()) + + def _get_yield_nodes_skip_lambdas(self): + yield from self.value._get_yield_nodes_skip_lambdas() + + +class AnnAssign(mixins.AssignTypeMixin, Statement): + """Class representing an :class:`ast.AnnAssign` node. + + An :class:`AnnAssign` is an assignment with a type annotation. + + >>> node = astroid.extract_node('variable: List[int] = range(10)') + >>> node + + """ + + _astroid_fields = ("target", "annotation", "value") + _other_fields = ("simple",) + target = None + """What is being assigned to. + + :type: NodeNG or None + """ + annotation = None + """The type annotation of what is being assigned to. + + :type: NodeNG + """ + value = None + """The value being assigned to the variables. + + :type: NodeNG or None + """ + simple = None + """Whether :attr:`target` is a pure name or a complex statement. + + :type: int + """ + + def postinit(self, target, annotation, simple, value=None): + """Do some setup after initialisation. + + :param target: What is being assigned to. + :type target: NodeNG + + :param annotation: The type annotation of what is being assigned to. + :type: NodeNG + + :param simple: Whether :attr:`target` is a pure name + or a complex statement. + :type simple: int + + :param value: The value being assigned to the variables. + :type: NodeNG or None + """ + self.target = target + self.annotation = annotation + self.value = value + self.simple = simple + + def get_children(self): + yield self.target + yield self.annotation + + if self.value is not None: + yield self.value + + +class AugAssign(mixins.AssignTypeMixin, Statement): + """Class representing an :class:`ast.AugAssign` node. + + An :class:`AugAssign` is an assignment paired with an operator. + + >>> node = astroid.extract_node('variable += 1') + >>> node + + """ + + _astroid_fields = ("target", "value") + _other_fields = ("op",) + target = None + """What is being assigned to. + + :type: NodeNG or None + """ + value = None + """The value being assigned to the variable. + + :type: NodeNG or None + """ + + def __init__(self, op=None, lineno=None, col_offset=None, parent=None): + """ + :param op: The operator that is being combined with the assignment. + This includes the equals sign. + :type op: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.op = op + """The operator that is being combined with the assignment. + + This includes the equals sign. + + :type: str or None + """ + + super(AugAssign, self).__init__(lineno, col_offset, parent) + + def postinit(self, target=None, value=None): + """Do some setup after initialisation. + + :param target: What is being assigned to. + :type target: NodeNG or None + + :param value: The value being assigned to the variable. + :type: NodeNG or None + """ + self.target = target + self.value = value + + # This is set by inference.py + def _infer_augassign(self, context=None): + raise NotImplementedError + + def type_errors(self, context=None): + """Get a list of type errors which can occur during inference. + + Each TypeError is represented by a :class:`BadBinaryOperationMessage` , + which holds the original exception. + + :returns: The list of possible type errors. + :rtype: list(BadBinaryOperationMessage) + """ + try: + results = self._infer_augassign(context=context) + return [ + result + for result in results + if isinstance(result, util.BadBinaryOperationMessage) + ] + except exceptions.InferenceError: + return [] + + def get_children(self): + yield self.target + yield self.value + + +class Repr(NodeNG): + """Class representing an :class:`ast.Repr` node. + + A :class:`Repr` node represents the backtick syntax, + which is a deprecated alias for :func:`repr` removed in Python 3. + + >>> node = astroid.extract_node('`variable`') + >>> node + + """ + + _astroid_fields = ("value",) + value = None + """What is having :func:`repr` called on it. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: What is having :func:`repr` called on it. + :type value: NodeNG or None + """ + self.value = value + + +class BinOp(NodeNG): + """Class representing an :class:`ast.BinOp` node. + + A :class:`BinOp` node is an application of a binary operator. + + >>> node = astroid.extract_node('a + b') + >>> node + + """ + + _astroid_fields = ("left", "right") + _other_fields = ("op",) + left = None + """What is being applied to the operator on the left side. + + :type: NodeNG or None + """ + right = None + """What is being applied to the operator on the right side. + + :type: NodeNG or None + """ + + def __init__(self, op=None, lineno=None, col_offset=None, parent=None): + """ + :param op: The operator. + :type: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.op = op + """The operator. + + :type: str or None + """ + + super(BinOp, self).__init__(lineno, col_offset, parent) + + def postinit(self, left=None, right=None): + """Do some setup after initialisation. + + :param left: What is being applied to the operator on the left side. + :type left: NodeNG or None + + :param right: What is being applied to the operator on the right side. + :type right: NodeNG or None + """ + self.left = left + self.right = right + + # This is set by inference.py + def _infer_binop(self, context=None): + raise NotImplementedError + + def type_errors(self, context=None): + """Get a list of type errors which can occur during inference. + + Each TypeError is represented by a :class:`BadBinaryOperationMessage`, + which holds the original exception. + + :returns: The list of possible type errors. + :rtype: list(BadBinaryOperationMessage) + """ + try: + results = self._infer_binop(context=context) + return [ + result + for result in results + if isinstance(result, util.BadBinaryOperationMessage) + ] + except exceptions.InferenceError: + return [] + + def get_children(self): + yield self.left + yield self.right + + def op_precedence(self): + return OP_PRECEDENCE[self.op] + + def op_left_associative(self): + # 2**3**4 == 2**(3**4) + return self.op != "**" + + +class BoolOp(NodeNG): + """Class representing an :class:`ast.BoolOp` node. + + A :class:`BoolOp` is an application of a boolean operator. + + >>> node = astroid.extract_node('a and b') + >>> node + + """ + + _astroid_fields = ("values",) + _other_fields = ("op",) + values = None + """The values being applied to the operator. + + :type: list(NodeNG) or None + """ + + def __init__(self, op=None, lineno=None, col_offset=None, parent=None): + """ + :param op: The operator. + :type: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.op = op + """The operator. + + :type: str or None + """ + + super(BoolOp, self).__init__(lineno, col_offset, parent) + + def postinit(self, values=None): + """Do some setup after initialisation. + + :param values: The values being applied to the operator. + :type values: list(NodeNG) or None + """ + self.values = values + + def get_children(self): + yield from self.values + + def op_precedence(self): + return OP_PRECEDENCE[self.op] + + +class Break(mixins.NoChildrenMixin, Statement): + """Class representing an :class:`ast.Break` node. + + >>> node = astroid.extract_node('break') + >>> node + + """ + + +class Call(NodeNG): + """Class representing an :class:`ast.Call` node. + + A :class:`Call` node is a call to a function, method, etc. + + >>> node = astroid.extract_node('function()') + >>> node + + """ + + _astroid_fields = ("func", "args", "keywords") + func = None + """What is being called. + + :type: NodeNG or None + """ + args = None + """The positional arguments being given to the call. + + :type: list(NodeNG) or None + """ + keywords = None + """The keyword arguments being given to the call. + + :type: list(NodeNG) or None + """ + + def postinit(self, func=None, args=None, keywords=None): + """Do some setup after initialisation. + + :param func: What is being called. + :type func: NodeNG or None + + :param args: The positional arguments being given to the call. + :type args: list(NodeNG) or None + + :param keywords: The keyword arguments being given to the call. + :type keywords: list(NodeNG) or None + """ + self.func = func + self.args = args + self.keywords = keywords + + @property + def starargs(self): + """The positional arguments that unpack something. + + :type: list(Starred) + """ + args = self.args or [] + return [arg for arg in args if isinstance(arg, Starred)] + + @property + def kwargs(self): + """The keyword arguments that unpack something. + + :type: list(Keyword) + """ + keywords = self.keywords or [] + return [keyword for keyword in keywords if keyword.arg is None] + + def get_children(self): + yield self.func + + yield from self.args + + yield from self.keywords or () + + +class Compare(NodeNG): + """Class representing an :class:`ast.Compare` node. + + A :class:`Compare` node indicates a comparison. + + >>> node = astroid.extract_node('a <= b <= c') + >>> node + + >>> node.ops + [('<=', ), ('<=', )] + """ + + _astroid_fields = ("left", "ops") + left = None + """The value at the left being applied to a comparison operator. + + :type: NodeNG or None + """ + ops = None + """The remainder of the operators and their relevant right hand value. + + :type: list(tuple(str, NodeNG)) or None + """ + + def postinit(self, left=None, ops=None): + """Do some setup after initialisation. + + :param left: The value at the left being applied to a comparison + operator. + :type left: NodeNG or None + + :param ops: The remainder of the operators + and their relevant right hand value. + :type ops: list(tuple(str, NodeNG)) or None + """ + self.left = left + self.ops = ops + + def get_children(self): + """Get the child nodes below this node. + + Overridden to handle the tuple fields and skip returning the operator + strings. + + :returns: The children. + :rtype: iterable(NodeNG) + """ + yield self.left + for _, comparator in self.ops: + yield comparator # we don't want the 'op' + + def last_child(self): + """An optimized version of list(get_children())[-1] + + :returns: The last child. + :rtype: NodeNG + """ + # XXX maybe if self.ops: + return self.ops[-1][1] + # return self.left + + +class Comprehension(NodeNG): + """Class representing an :class:`ast.comprehension` node. + + A :class:`Comprehension` indicates the loop inside any type of + comprehension including generator expressions. + + >>> node = astroid.extract_node('[x for x in some_values]') + >>> list(node.get_children()) + [, ] + >>> list(node.get_children())[1].as_string() + 'for x in some_values' + """ + + _astroid_fields = ("target", "iter", "ifs") + _other_fields = ("is_async",) + target = None + """What is assigned to by the comprehension. + + :type: NodeNG or None + """ + iter = None + """What is iterated over by the comprehension. + + :type: NodeNG or None + """ + ifs = None + """The contents of any if statements that filter the comprehension. + + :type: list(NodeNG) or None + """ + is_async = None + """Whether this is an asynchronous comprehension or not. + + :type: bool or None + """ + + def __init__(self, parent=None): + """ + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + super(Comprehension, self).__init__() + self.parent = parent + + # pylint: disable=redefined-builtin; same name as builtin ast module. + def postinit(self, target=None, iter=None, ifs=None, is_async=None): + """Do some setup after initialisation. + + :param target: What is assigned to by the comprehension. + :type target: NodeNG or None + + :param iter: What is iterated over by the comprehension. + :type iter: NodeNG or None + + :param ifs: The contents of any if statements that filter + the comprehension. + :type ifs: list(NodeNG) or None + + :param is_async: Whether this is an asynchronous comprehension or not. + :type: bool or None + """ + self.target = target + self.iter = iter + self.ifs = ifs + self.is_async = is_async + + optional_assign = True + """Whether this node optionally assigns a variable. + + :type: bool + """ + + def assign_type(self): + """The type of assignment that this node performs. + + :returns: The assignment type. + :rtype: NodeNG + """ + return self + + def _get_filtered_stmts(self, lookup_node, node, stmts, mystmt): + """method used in filter_stmts""" + if self is mystmt: + if isinstance(lookup_node, (Const, Name)): + return [lookup_node], True + + elif self.statement() is mystmt: + # original node's statement is the assignment, only keeps + # current node (gen exp, list comp) + + return [node], True + + return stmts, False + + def get_children(self): + yield self.target + yield self.iter + + yield from self.ifs + + +class Const(mixins.NoChildrenMixin, NodeNG, bases.Instance): + """Class representing any constant including num, str, bool, None, bytes. + + >>> node = astroid.extract_node('(5, "This is a string.", True, None, b"bytes")') + >>> node + + >>> list(node.get_children()) + [, + , + , + , + ] + """ + + _other_fields = ("value",) + + def __init__(self, value, lineno=None, col_offset=None, parent=None): + """ + :param value: The value that the constant represents. + :type value: object + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.value = value + """The value that the constant represents. + + :type: object + """ + + super(Const, self).__init__(lineno, col_offset, parent) + + def __getattr__(self, name): + # This is needed because of Proxy's __getattr__ method. + # Calling object.__new__ on this class without calling + # __init__ would result in an infinite loop otherwise + # since __getattr__ is called when an attribute doesn't + # exist and self._proxied indirectly calls self.value + # and Proxy __getattr__ calls self.value + if name == "value": + raise AttributeError + return super().__getattr__(name) + + def getitem(self, index, context=None): + """Get an item from this node if subscriptable. + + :param index: The node to use as a subscript index. + :type index: Const or Slice + + :raises AstroidTypeError: When the given index cannot be used as a + subscript index, or if this node is not subscriptable. + """ + if isinstance(index, Const): + index_value = index.value + elif isinstance(index, Slice): + index_value = _infer_slice(index, context=context) + + else: + raise exceptions.AstroidTypeError( + "Could not use type {} as subscript index".format(type(index)) + ) + + try: + if isinstance(self.value, (str, bytes)): + return Const(self.value[index_value]) + except IndexError as exc: + raise exceptions.AstroidIndexError( + message="Index {index!r} out of range", + node=self, + index=index, + context=context, + ) from exc + except TypeError as exc: + raise exceptions.AstroidTypeError( + message="Type error {error!r}", node=self, index=index, context=context + ) from exc + + raise exceptions.AstroidTypeError("%r (value=%s)" % (self, self.value)) + + def has_dynamic_getattr(self): + """Check if the node has a custom __getattr__ or __getattribute__. + + :returns: True if the class has a custom + __getattr__ or __getattribute__, False otherwise. + For a :class:`Const` this is always ``False``. + :rtype: bool + """ + return False + + def itered(self): + """An iterator over the elements this node contains. + + :returns: The contents of this node. + :rtype: iterable(str) + + :raises TypeError: If this node does not represent something that is iterable. + """ + if isinstance(self.value, str): + return self.value + raise TypeError() + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return self._proxied.qname() + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + :rtype: bool + """ + return bool(self.value) + + +class Continue(mixins.NoChildrenMixin, Statement): + """Class representing an :class:`ast.Continue` node. + + >>> node = astroid.extract_node('continue') + >>> node + + """ + + +class Decorators(NodeNG): + """A node representing a list of decorators. + + A :class:`Decorators` is the decorators that are applied to + a method or function. + + >>> node = astroid.extract_node(''' + @property + def my_property(self): + return 3 + ''') + >>> node + + >>> list(node.get_children())[0] + + """ + + _astroid_fields = ("nodes",) + nodes = None + """The decorators that this node contains. + + :type: list(Name or Call) or None + """ + + def postinit(self, nodes): + """Do some setup after initialisation. + + :param nodes: The decorators that this node contains. + :type nodes: list(Name or Call) + """ + self.nodes = nodes + + def scope(self): + """The first parent node defining a new scope. + + :returns: The first parent scope node. + :rtype: Module or FunctionDef or ClassDef or Lambda or GenExpr + """ + # skip the function node to go directly to the upper level scope + return self.parent.parent.scope() + + def get_children(self): + yield from self.nodes + + +class DelAttr(mixins.ParentAssignTypeMixin, NodeNG): + """Variation of :class:`ast.Delete` representing deletion of an attribute. + + >>> node = astroid.extract_node('del self.attr') + >>> node + + >>> list(node.get_children())[0] + + """ + + _astroid_fields = ("expr",) + _other_fields = ("attrname",) + expr = None + """The name that this node represents. + + :type: Name or None + """ + + def __init__(self, attrname=None, lineno=None, col_offset=None, parent=None): + """ + :param attrname: The name of the attribute that is being deleted. + :type attrname: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.attrname = attrname + """The name of the attribute that is being deleted. + + :type: str or None + """ + + super(DelAttr, self).__init__(lineno, col_offset, parent) + + def postinit(self, expr=None): + """Do some setup after initialisation. + + :param expr: The name that this node represents. + :type expr: Name or None + """ + self.expr = expr + + def get_children(self): + yield self.expr + + +class Delete(mixins.AssignTypeMixin, Statement): + """Class representing an :class:`ast.Delete` node. + + A :class:`Delete` is a ``del`` statement this is deleting something. + + >>> node = astroid.extract_node('del self.attr') + >>> node + + """ + + _astroid_fields = ("targets",) + targets = None + """What is being deleted. + + :type: list(NodeNG) or None + """ + + def postinit(self, targets=None): + """Do some setup after initialisation. + + :param targets: What is being deleted. + :type targets: list(NodeNG) or None + """ + self.targets = targets + + def get_children(self): + yield from self.targets + + +class Dict(NodeNG, bases.Instance): + """Class representing an :class:`ast.Dict` node. + + A :class:`Dict` is a dictionary that is created with ``{}`` syntax. + + >>> node = astroid.extract_node('{1: "1"}') + >>> node + + """ + + _astroid_fields = ("items",) + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.items = [] + """The key-value pairs contained in the dictionary. + + :type: list(tuple(NodeNG, NodeNG)) + """ + + super(Dict, self).__init__(lineno, col_offset, parent) + + def postinit(self, items): + """Do some setup after initialisation. + + :param items: The key-value pairs contained in the dictionary. + :type items: list(tuple(NodeNG, NodeNG)) + """ + self.items = items + + @classmethod + def from_elements(cls, items=None): + """Create a :class:`Dict` of constants from a live dictionary. + + :param items: The items to store in the node. + :type items: dict + + :returns: The created dictionary node. + :rtype: Dict + """ + node = cls() + if items is None: + node.items = [] + else: + node.items = [ + (const_factory(k), const_factory(v) if _is_const(v) else v) + for k, v in items.items() + # The keys need to be constants + if _is_const(k) + ] + return node + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.dict" % BUILTINS + + def get_children(self): + """Get the key and value nodes below this node. + + Children are returned in the order that they are defined in the source + code, key first then the value. + + :returns: The children. + :rtype: iterable(NodeNG) + """ + for key, value in self.items: + yield key + yield value + + def last_child(self): + """An optimized version of list(get_children())[-1] + + :returns: The last child, or None if no children exist. + :rtype: NodeNG or None + """ + if self.items: + return self.items[-1][1] + return None + + def itered(self): + """An iterator over the keys this node contains. + + :returns: The keys of this node. + :rtype: iterable(NodeNG) + """ + return [key for (key, _) in self.items] + + def getitem(self, index, context=None): + """Get an item from this node. + + :param index: The node to use as a subscript index. + :type index: Const or Slice + + :raises AstroidTypeError: When the given index cannot be used as a + subscript index, or if this node is not subscriptable. + :raises AstroidIndexError: If the given index does not exist in the + dictionary. + """ + for key, value in self.items: + # TODO(cpopa): no support for overriding yet, {1:2, **{1: 3}}. + if isinstance(key, DictUnpack): + try: + return value.getitem(index, context) + except (exceptions.AstroidTypeError, exceptions.AstroidIndexError): + continue + for inferredkey in key.infer(context): + if inferredkey is util.Uninferable: + continue + if isinstance(inferredkey, Const) and isinstance(index, Const): + if inferredkey.value == index.value: + return value + + raise exceptions.AstroidIndexError(index) + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + :rtype: bool + """ + return bool(self.items) + + +class Expr(Statement): + """Class representing an :class:`ast.Expr` node. + + An :class:`Expr` is any expression that does not have its value used or + stored. + + >>> node = astroid.extract_node('method()') + >>> node + + >>> node.parent + + """ + + _astroid_fields = ("value",) + value = None + """What the expression does. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: What the expression does. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + yield self.value + + def _get_yield_nodes_skip_lambdas(self): + if not self.value.is_lambda: + yield from self.value._get_yield_nodes_skip_lambdas() + + +class Ellipsis(mixins.NoChildrenMixin, NodeNG): # pylint: disable=redefined-builtin + """Class representing an :class:`ast.Ellipsis` node. + + An :class:`Ellipsis` is the ``...`` syntax. + + >>> node = astroid.extract_node('...') + >>> node + + """ + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For an :class:`Ellipsis` this is always ``True``. + :rtype: bool + """ + return True + + +class EmptyNode(mixins.NoChildrenMixin, NodeNG): + """Holds an arbitrary object in the :attr:`LocalsDictNodeNG.locals`.""" + + object = None + + +class ExceptHandler(mixins.MultiLineBlockMixin, mixins.AssignTypeMixin, Statement): + """Class representing an :class:`ast.ExceptHandler`. node. + + An :class:`ExceptHandler` is an ``except`` block on a try-except. + + >>> node = astroid.extract_node(''' + try: + do_something() + except Exception as error: + print("Error!") + ''') + >>> node + + >>> >>> node.handlers + [] + """ + + _astroid_fields = ("type", "name", "body") + _multi_line_block_fields = ("body",) + type = None + """The types that the block handles. + + :type: Tuple or NodeNG or None + """ + name = None + """The name that the caught exception is assigned to. + + :type: AssignName or None + """ + body = None + """The contents of the block. + + :type: list(NodeNG) or None + """ + + def get_children(self): + if self.type is not None: + yield self.type + + if self.name is not None: + yield self.name + + yield from self.body + + # pylint: disable=redefined-builtin; had to use the same name as builtin ast module. + def postinit(self, type=None, name=None, body=None): + """Do some setup after initialisation. + + :param type: The types that the block handles. + :type type: Tuple or NodeNG or None + + :param name: The name that the caught exception is assigned to. + :type name: AssignName or None + + :param body:The contents of the block. + :type body: list(NodeNG) or None + """ + self.type = type + self.name = name + self.body = body + + @decorators.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + if self.name: + return self.name.tolineno + if self.type: + return self.type.tolineno + return self.lineno + + def catch(self, exceptions): # pylint: disable=redefined-outer-name + """Check if this node handles any of the given exceptions. + + If ``exceptions`` is empty, this will default to ``True``. + + :param exceptions: The name of the exceptions to check for. + :type exceptions: list(str) + """ + if self.type is None or exceptions is None: + return True + for node in self.type._get_name_nodes(): + if node.name in exceptions: + return True + return False + + +class Exec(Statement): + """Class representing the ``exec`` statement. + + >>> node = astroid.extract_node('exec "True"') + >>> node + + """ + + _astroid_fields = ("expr", "globals", "locals") + expr = None + """The expression to be executed. + + :type: NodeNG or None + """ + globals = None + """The globals dictionary to execute with. + + :type: NodeNG or None + """ + locals = None + """The locals dictionary to execute with. + + :type: NodeNG or None + """ + + # pylint: disable=redefined-builtin; had to use the same name as builtin ast module. + def postinit(self, expr=None, globals=None, locals=None): + """Do some setup after initialisation. + + :param expr: The expression to be executed. + :type expr: NodeNG or None + + :param globals:The globals dictionary to execute with. + :type globals: NodeNG or None + + :param locals: The locals dictionary to execute with. + :type locals: NodeNG or None + """ + self.expr = expr + self.globals = globals + self.locals = locals + + +class ExtSlice(NodeNG): + """Class representing an :class:`ast.ExtSlice` node. + + An :class:`ExtSlice` is a complex slice expression. + + >>> node = astroid.extract_node('l[1:3, 5]') + >>> node + + >>> node.slice + + """ + + _astroid_fields = ("dims",) + dims = None + """The simple dimensions that form the complete slice. + + :type: list(NodeNG) or None + """ + + def postinit(self, dims=None): + """Do some setup after initialisation. + + :param dims: The simple dimensions that form the complete slice. + :type dims: list(NodeNG) or None + """ + self.dims = dims + + +class For( + mixins.MultiLineBlockMixin, + mixins.BlockRangeMixIn, + mixins.AssignTypeMixin, + Statement, +): + """Class representing an :class:`ast.For` node. + + >>> node = astroid.extract_node('for thing in things: print(thing)') + >>> node + + """ + + _astroid_fields = ("target", "iter", "body", "orelse") + _other_other_fields = ("type_annotation",) + _multi_line_block_fields = ("body", "orelse") + target = None + """What the loop assigns to. + + :type: NodeNG or None + """ + iter = None + """What the loop iterates over. + + :type: NodeNG or None + """ + body = None + """The contents of the body of the loop. + + :type: list(NodeNG) or None + """ + orelse = None + """The contents of the ``else`` block of the loop. + + :type: list(NodeNG) or None + """ + type_annotation = None + """If present, this will contain the type annotation passed by a type comment + + :type: NodeNG or None + """ + + # pylint: disable=redefined-builtin; had to use the same name as builtin ast module. + def postinit( + self, target=None, iter=None, body=None, orelse=None, type_annotation=None + ): + """Do some setup after initialisation. + + :param target: What the loop assigns to. + :type target: NodeNG or None + + :param iter: What the loop iterates over. + :type iter: NodeNG or None + + :param body: The contents of the body of the loop. + :type body: list(NodeNG) or None + + :param orelse: The contents of the ``else`` block of the loop. + :type orelse: list(NodeNG) or None + """ + self.target = target + self.iter = iter + self.body = body + self.orelse = orelse + self.type_annotation = type_annotation + + optional_assign = True + """Whether this node optionally assigns a variable. + + This is always ``True`` for :class:`For` nodes. + + :type: bool + """ + + @decorators.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + return self.iter.tolineno + + def get_children(self): + yield self.target + yield self.iter + + yield from self.body + yield from self.orelse + + +class AsyncFor(For): + """Class representing an :class:`ast.AsyncFor` node. + + An :class:`AsyncFor` is an asynchronous :class:`For` built with + the ``async`` keyword. + + >>> node = astroid.extract_node(''' + async def func(things): + async for thing in things: + print(thing) + ''') + >>> node + + >>> node.body[0] + + """ + + +class Await(NodeNG): + """Class representing an :class:`ast.Await` node. + + An :class:`Await` is the ``await`` keyword. + + >>> node = astroid.extract_node(''' + async def func(things): + await other_func() + ''') + >>> node + + >>> node.body[0] + + >>> list(node.body[0].get_children())[0] + + """ + + _astroid_fields = ("value",) + value = None + """What to wait for. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: What to wait for. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + yield self.value + + +class ImportFrom(mixins.NoChildrenMixin, mixins.ImportFromMixin, Statement): + """Class representing an :class:`ast.ImportFrom` node. + + >>> node = astroid.extract_node('from my_package import my_module') + >>> node + + """ + + _other_fields = ("modname", "names", "level") + + def __init__( + self, fromname, names, level=0, lineno=None, col_offset=None, parent=None + ): + """ + :param fromname: The module that is being imported from. + :type fromname: str or None + + :param names: What is being imported from the module. + :type names: list(tuple(str, str or None)) + + :param level: The level of relative import. + :type level: int + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.modname = fromname + """The module that is being imported from. + + This is ``None`` for relative imports. + + :type: str or None + """ + + self.names = names + """What is being imported from the module. + + Each entry is a :class:`tuple` of the name being imported, + and the alias that the name is assigned to (if any). + + :type: list(tuple(str, str or None)) + """ + + self.level = level + """The level of relative import. + + Essentially this is the number of dots in the import. + This is always 0 for absolute imports. + + :type: int + """ + + super(ImportFrom, self).__init__(lineno, col_offset, parent) + + +class Attribute(NodeNG): + """Class representing an :class:`ast.Attribute` node.""" + + _astroid_fields = ("expr",) + _other_fields = ("attrname",) + expr = None + """The name that this node represents. + + :type: Name or None + """ + + def __init__(self, attrname=None, lineno=None, col_offset=None, parent=None): + """ + :param attrname: The name of the attribute. + :type attrname: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.attrname = attrname + """The name of the attribute. + + :type: str or None + """ + + super(Attribute, self).__init__(lineno, col_offset, parent) + + def postinit(self, expr=None): + """Do some setup after initialisation. + + :param expr: The name that this node represents. + :type expr: Name or None + """ + self.expr = expr + + def get_children(self): + yield self.expr + + +class Global(mixins.NoChildrenMixin, Statement): + """Class representing an :class:`ast.Global` node. + + >>> node = astroid.extract_node('global a_global') + >>> node + + """ + + _other_fields = ("names",) + + def __init__(self, names, lineno=None, col_offset=None, parent=None): + """ + :param names: The names being declared as global. + :type names: list(str) + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.names = names + """The names being declared as global. + + :type: list(str) + """ + + super(Global, self).__init__(lineno, col_offset, parent) + + def _infer_name(self, frame, name): + return name + + +class If(mixins.MultiLineBlockMixin, mixins.BlockRangeMixIn, Statement): + """Class representing an :class:`ast.If` node. + + >>> node = astroid.extract_node('if condition: print(True)') + >>> node + + """ + + _astroid_fields = ("test", "body", "orelse") + _multi_line_block_fields = ("body", "orelse") + test = None + """The condition that the statement tests. + + :type: NodeNG or None + """ + body = None + """The contents of the block. + + :type: list(NodeNG) or None + """ + orelse = None + """The contents of the ``else`` block. + + :type: list(NodeNG) or None + """ + + def postinit(self, test=None, body=None, orelse=None): + """Do some setup after initialisation. + + :param test: The condition that the statement tests. + :type test: NodeNG or None + + :param body: The contents of the block. + :type body: list(NodeNG) or None + + :param orelse: The contents of the ``else`` block. + :type orelse: list(NodeNG) or None + """ + self.test = test + self.body = body + self.orelse = orelse + + @decorators.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + return self.test.tolineno + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: The line number to start the range at. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + starting at the given line number. + :rtype: tuple(int, int) + """ + if lineno == self.body[0].fromlineno: + return lineno, lineno + if lineno <= self.body[-1].tolineno: + return lineno, self.body[-1].tolineno + return self._elsed_block_range(lineno, self.orelse, self.body[0].fromlineno - 1) + + def get_children(self): + yield self.test + + yield from self.body + yield from self.orelse + + def has_elif_block(self): + return len(self.orelse) == 1 and isinstance(self.orelse[0], If) + + +class IfExp(NodeNG): + """Class representing an :class:`ast.IfExp` node. + + >>> node = astroid.extract_node('value if condition else other') + >>> node + + """ + + _astroid_fields = ("test", "body", "orelse") + test = None + """The condition that the statement tests. + + :type: NodeNG or None + """ + body = None + """The contents of the block. + + :type: list(NodeNG) or None + """ + orelse = None + """The contents of the ``else`` block. + + :type: list(NodeNG) or None + """ + + def postinit(self, test=None, body=None, orelse=None): + """Do some setup after initialisation. + + :param test: The condition that the statement tests. + :type test: NodeNG or None + + :param body: The contents of the block. + :type body: list(NodeNG) or None + + :param orelse: The contents of the ``else`` block. + :type orelse: list(NodeNG) or None + """ + self.test = test + self.body = body + self.orelse = orelse + + def get_children(self): + yield self.test + yield self.body + yield self.orelse + + def op_left_associative(self): + # `1 if True else 2 if False else 3` is parsed as + # `1 if True else (2 if False else 3)` + return False + + +class Import(mixins.NoChildrenMixin, mixins.ImportFromMixin, Statement): + """Class representing an :class:`ast.Import` node. + + >>> node = astroid.extract_node('import astroid') + >>> node + + """ + + _other_fields = ("names",) + + def __init__(self, names=None, lineno=None, col_offset=None, parent=None): + """ + :param names: The names being imported. + :type names: list(tuple(str, str or None)) or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.names = names + """The names being imported. + + Each entry is a :class:`tuple` of the name being imported, + and the alias that the name is assigned to (if any). + + :type: list(tuple(str, str or None)) or None + """ + + super(Import, self).__init__(lineno, col_offset, parent) + + +class Index(NodeNG): + """Class representing an :class:`ast.Index` node. + + An :class:`Index` is a simple subscript. + + >>> node = astroid.extract_node('things[1]') + >>> node + + >>> node.slice + + """ + + _astroid_fields = ("value",) + value = None + """The value to subscript with. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: The value to subscript with. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + yield self.value + + +class Keyword(NodeNG): + """Class representing an :class:`ast.keyword` node. + + >>> node = astroid.extract_node('function(a_kwarg=True)') + >>> node + + >>> node.keywords + [] + """ + + _astroid_fields = ("value",) + _other_fields = ("arg",) + value = None + """The value being assigned to the keyword argument. + + :type: NodeNG or None + """ + + def __init__(self, arg=None, lineno=None, col_offset=None, parent=None): + """ + :param arg: The argument being assigned to. + :type arg: Name or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.arg = arg + """The argument being assigned to. + + :type: Name or None + """ + + super(Keyword, self).__init__(lineno, col_offset, parent) + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: The value being assigned to the ketword argument. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + yield self.value + + +class List(_BaseContainer): + """Class representing an :class:`ast.List` node. + + >>> node = astroid.extract_node('[1, 2, 3]') + >>> node + + """ + + _other_fields = ("ctx",) + + def __init__(self, ctx=None, lineno=None, col_offset=None, parent=None): + """ + :param ctx: Whether the list is assigned to or loaded from. + :type ctx: Context or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.ctx = ctx + """Whether the list is assigned to or loaded from. + + :type: Context or None + """ + + super(List, self).__init__(lineno, col_offset, parent) + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.list" % BUILTINS + + def getitem(self, index, context=None): + """Get an item from this node. + + :param index: The node to use as a subscript index. + :type index: Const or Slice + """ + return _container_getitem(self, self.elts, index, context=context) + + +class Nonlocal(mixins.NoChildrenMixin, Statement): + """Class representing an :class:`ast.Nonlocal` node. + + >>> node = astroid.extract_node(''' + def function(): + nonlocal var + ''') + >>> node + + >>> node.body[0] + + """ + + _other_fields = ("names",) + + def __init__(self, names, lineno=None, col_offset=None, parent=None): + """ + :param names: The names being declared as not local. + :type names: list(str) + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.names = names + """The names being declared as not local. + + :type: list(str) + """ + + super(Nonlocal, self).__init__(lineno, col_offset, parent) + + def _infer_name(self, frame, name): + return name + + +class Pass(mixins.NoChildrenMixin, Statement): + """Class representing an :class:`ast.Pass` node. + + >>> node = astroid.extract_node('pass') + >>> node + + """ + + +class Print(Statement): + """Class representing an :class:`ast.Print` node. + + >>> node = astroid.extract_node('print "A message"') + >>> node + + """ + + _astroid_fields = ("dest", "values") + dest = None + """Where to print to. + + :type: NodeNG or None + """ + values = None + """What to print. + + :type: list(NodeNG) or None + """ + + def __init__(self, nl=None, lineno=None, col_offset=None, parent=None): + """ + :param nl: Whether to print a new line. + :type nl: bool or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.nl = nl + """Whether to print a new line. + + :type: bool or None + """ + + super(Print, self).__init__(lineno, col_offset, parent) + + def postinit(self, dest=None, values=None): + """Do some setup after initialisation. + + :param dest: Where to print to. + :type dest: NodeNG or None + + :param values: What to print. + :type values: list(NodeNG) or None + """ + self.dest = dest + self.values = values + + +class Raise(Statement): + """Class representing an :class:`ast.Raise` node. + + >>> node = astroid.extract_node('raise RuntimeError("Something bad happened!")') + >>> node + + """ + + exc = None + """What is being raised. + + :type: NodeNG or None + """ + _astroid_fields = ("exc", "cause") + cause = None + """The exception being used to raise this one. + + :type: NodeNG or None + """ + + def postinit(self, exc=None, cause=None): + """Do some setup after initialisation. + + :param exc: What is being raised. + :type exc: NodeNG or None + + :param cause: The exception being used to raise this one. + :type cause: NodeNG or None + """ + self.exc = exc + self.cause = cause + + def raises_not_implemented(self): + """Check if this node raises a :class:`NotImplementedError`. + + :returns: True if this node raises a :class:`NotImplementedError`, + False otherwise. + :rtype: bool + """ + if not self.exc: + return False + for name in self.exc._get_name_nodes(): + if name.name == "NotImplementedError": + return True + return False + + def get_children(self): + if self.exc is not None: + yield self.exc + + if self.cause is not None: + yield self.cause + + +class Return(Statement): + """Class representing an :class:`ast.Return` node. + + >>> node = astroid.extract_node('return True') + >>> node + + """ + + _astroid_fields = ("value",) + value = None + """The value being returned. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: The value being returned. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + if self.value is not None: + yield self.value + + def is_tuple_return(self): + return isinstance(self.value, Tuple) + + def _get_return_nodes_skip_functions(self): + yield self + + +class Set(_BaseContainer): + """Class representing an :class:`ast.Set` node. + + >>> node = astroid.extract_node('{1, 2, 3}') + >>> node + + """ + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.set" % BUILTINS + + +class Slice(NodeNG): + """Class representing an :class:`ast.Slice` node. + + >>> node = astroid.extract_node('things[1:3]') + >>> node + + >>> node.slice + + """ + + _astroid_fields = ("lower", "upper", "step") + lower = None + """The lower index in the slice. + + :type: NodeNG or None + """ + upper = None + """The upper index in the slice. + + :type: NodeNG or None + """ + step = None + """The step to take between indexes. + + :type: NodeNG or None + """ + + def postinit(self, lower=None, upper=None, step=None): + """Do some setup after initialisation. + + :param lower: The lower index in the slice. + :value lower: NodeNG or None + + :param upper: The upper index in the slice. + :value upper: NodeNG or None + + :param step: The step to take between index. + :param step: NodeNG or None + """ + self.lower = lower + self.upper = upper + self.step = step + + def _wrap_attribute(self, attr): + """Wrap the empty attributes of the Slice in a Const node.""" + if not attr: + const = const_factory(attr) + const.parent = self + return const + return attr + + @decorators.cachedproperty + def _proxied(self): + builtins = MANAGER.builtins_module + return builtins.getattr("slice")[0] + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.slice" % BUILTINS + + def igetattr(self, attrname, context=None): + """Infer the possible values of the given attribute on the slice. + + :param attrname: The name of the attribute to infer. + :type attrname: str + + :returns: The inferred possible values. + :rtype: iterable(NodeNG) + """ + if attrname == "start": + yield self._wrap_attribute(self.lower) + elif attrname == "stop": + yield self._wrap_attribute(self.upper) + elif attrname == "step": + yield self._wrap_attribute(self.step) + else: + yield from self.getattr(attrname, context=context) + + def getattr(self, attrname, context=None): + return self._proxied.getattr(attrname, context) + + def get_children(self): + if self.lower is not None: + yield self.lower + + if self.upper is not None: + yield self.upper + + if self.step is not None: + yield self.step + + +class Starred(mixins.ParentAssignTypeMixin, NodeNG): + """Class representing an :class:`ast.Starred` node. + + >>> node = astroid.extract_node('*args') + >>> node + + """ + + _astroid_fields = ("value",) + _other_fields = ("ctx",) + value = None + """What is being unpacked. + + :type: NodeNG or None + """ + + def __init__(self, ctx=None, lineno=None, col_offset=None, parent=None): + """ + :param ctx: Whether the list is assigned to or loaded from. + :type ctx: Context or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.ctx = ctx + """Whether the starred item is assigned to or loaded from. + + :type: Context or None + """ + + super(Starred, self).__init__( + lineno=lineno, col_offset=col_offset, parent=parent + ) + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: What is being unpacked. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + yield self.value + + +class Subscript(NodeNG): + """Class representing an :class:`ast.Subscript` node. + + >>> node = astroid.extract_node('things[1:3]') + >>> node + + """ + + _astroid_fields = ("value", "slice") + _other_fields = ("ctx",) + value = None + """What is being indexed. + + :type: NodeNG or None + """ + slice = None + """The slice being used to lookup. + + :type: NodeNG or None + """ + + def __init__(self, ctx=None, lineno=None, col_offset=None, parent=None): + """ + :param ctx: Whether the subscripted item is assigned to or loaded from. + :type ctx: Context or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.ctx = ctx + """Whether the subscripted item is assigned to or loaded from. + + :type: Context or None + """ + + super(Subscript, self).__init__( + lineno=lineno, col_offset=col_offset, parent=parent + ) + + # pylint: disable=redefined-builtin; had to use the same name as builtin ast module. + def postinit(self, value=None, slice=None): + """Do some setup after initialisation. + + :param value: What is being indexed. + :type value: NodeNG or None + + :param slice: The slice being used to lookup. + :type slice: NodeNG or None + """ + self.value = value + self.slice = slice + + def get_children(self): + yield self.value + yield self.slice + + +class TryExcept(mixins.MultiLineBlockMixin, mixins.BlockRangeMixIn, Statement): + """Class representing an :class:`ast.TryExcept` node. + + >>> node = astroid.extract_node(''' + try: + do_something() + except Exception as error: + print("Error!") + ''') + >>> node + + """ + + _astroid_fields = ("body", "handlers", "orelse") + _multi_line_block_fields = ("body", "handlers", "orelse") + body = None + """The contents of the block to catch exceptions from. + + :type: list(NodeNG) or None + """ + handlers = None + """The exception handlers. + + :type: list(ExceptHandler) or None + """ + orelse = None + """The contents of the ``else`` block. + + :type: list(NodeNG) or None + """ + + def postinit(self, body=None, handlers=None, orelse=None): + """Do some setup after initialisation. + + :param body: The contents of the block to catch exceptions from. + :type body: list(NodeNG) or None + + :param handlers: The exception handlers. + :type handlers: list(ExceptHandler) or None + + :param orelse: The contents of the ``else`` block. + :type orelse: list(NodeNG) or None + """ + self.body = body + self.handlers = handlers + self.orelse = orelse + + def _infer_name(self, frame, name): + return name + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: The line number to start the range at. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + starting at the given line number. + :rtype: tuple(int, int) + """ + last = None + for exhandler in self.handlers: + if exhandler.type and lineno == exhandler.type.fromlineno: + return lineno, lineno + if exhandler.body[0].fromlineno <= lineno <= exhandler.body[-1].tolineno: + return lineno, exhandler.body[-1].tolineno + if last is None: + last = exhandler.body[0].fromlineno - 1 + return self._elsed_block_range(lineno, self.orelse, last) + + def get_children(self): + yield from self.body + + yield from self.handlers or () + yield from self.orelse or () + + +class TryFinally(mixins.MultiLineBlockMixin, mixins.BlockRangeMixIn, Statement): + """Class representing an :class:`ast.TryFinally` node. + + >>> node = astroid.extract_node(''' + try: + do_something() + except Exception as error: + print("Error!") + finally: + print("Cleanup!") + ''') + >>> node + + """ + + _astroid_fields = ("body", "finalbody") + _multi_line_block_fields = ("body", "finalbody") + body = None + """The try-except that the finally is attached to. + + :type: list(TryExcept) or None + """ + finalbody = None + """The contents of the ``finally`` block. + + :type: list(NodeNG) or None + """ + + def postinit(self, body=None, finalbody=None): + """Do some setup after initialisation. + + :param body: The try-except that the finally is attached to. + :type body: list(TryExcept) or None + + :param finalbody: The contents of the ``finally`` block. + :type finalbody: list(NodeNG) or None + """ + self.body = body + self.finalbody = finalbody + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: The line number to start the range at. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + starting at the given line number. + :rtype: tuple(int, int) + """ + child = self.body[0] + # py2.5 try: except: finally: + if ( + isinstance(child, TryExcept) + and child.fromlineno == self.fromlineno + and child.tolineno >= lineno > self.fromlineno + ): + return child.block_range(lineno) + return self._elsed_block_range(lineno, self.finalbody) + + def get_children(self): + yield from self.body + yield from self.finalbody + + +class Tuple(_BaseContainer): + """Class representing an :class:`ast.Tuple` node. + + >>> node = astroid.extract_node('(1, 2, 3)') + >>> node + + """ + + _other_fields = ("ctx",) + + def __init__(self, ctx=None, lineno=None, col_offset=None, parent=None): + """ + :param ctx: Whether the tuple is assigned to or loaded from. + :type ctx: Context or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.ctx = ctx + """Whether the tuple is assigned to or loaded from. + + :type: Context or None + """ + + super(Tuple, self).__init__(lineno, col_offset, parent) + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.tuple" % BUILTINS + + def getitem(self, index, context=None): + """Get an item from this node. + + :param index: The node to use as a subscript index. + :type index: Const or Slice + """ + return _container_getitem(self, self.elts, index, context=context) + + +class UnaryOp(NodeNG): + """Class representing an :class:`ast.UnaryOp` node. + + >>> node = astroid.extract_node('-5') + >>> node + + """ + + _astroid_fields = ("operand",) + _other_fields = ("op",) + operand = None + """What the unary operator is applied to. + + :type: NodeNG or None + """ + + def __init__(self, op=None, lineno=None, col_offset=None, parent=None): + """ + :param op: The operator. + :type: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.op = op + """The operator. + + :type: str or None + """ + + super(UnaryOp, self).__init__(lineno, col_offset, parent) + + def postinit(self, operand=None): + """Do some setup after initialisation. + + :param operand: What the unary operator is applied to. + :type operand: NodeNG or None + """ + self.operand = operand + + # This is set by inference.py + def _infer_unaryop(self, context=None): + raise NotImplementedError + + def type_errors(self, context=None): + """Get a list of type errors which can occur during inference. + + Each TypeError is represented by a :class:`BadBinaryOperationMessage`, + which holds the original exception. + + :returns: The list of possible type errors. + :rtype: list(BadBinaryOperationMessage) + """ + try: + results = self._infer_unaryop(context=context) + return [ + result + for result in results + if isinstance(result, util.BadUnaryOperationMessage) + ] + except exceptions.InferenceError: + return [] + + def get_children(self): + yield self.operand + + def op_precedence(self): + if self.op == "not": + return OP_PRECEDENCE[self.op] + + return super().op_precedence() + + +class While(mixins.MultiLineBlockMixin, mixins.BlockRangeMixIn, Statement): + """Class representing an :class:`ast.While` node. + + >>> node = astroid.extract_node(''' + while condition(): + print("True") + ''') + >>> node + + """ + + _astroid_fields = ("test", "body", "orelse") + _multi_line_block_fields = ("body", "orelse") + test = None + """The condition that the loop tests. + + :type: NodeNG or None + """ + body = None + """The contents of the loop. + + :type: list(NodeNG) or None + """ + orelse = None + """The contents of the ``else`` block. + + :type: list(NodeNG) or None + """ + + def postinit(self, test=None, body=None, orelse=None): + """Do some setup after initialisation. + + :param test: The condition that the loop tests. + :type test: NodeNG or None + + :param body: The contents of the loop. + :type body: list(NodeNG) or None + + :param orelse: The contents of the ``else`` block. + :type orelse: list(NodeNG) or None + """ + self.test = test + self.body = body + self.orelse = orelse + + @decorators.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + return self.test.tolineno + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: The line number to start the range at. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + starting at the given line number. + :rtype: tuple(int, int) + """ + return self._elsed_block_range(lineno, self.orelse) + + def get_children(self): + yield self.test + + yield from self.body + yield from self.orelse + + +class With( + mixins.MultiLineBlockMixin, + mixins.BlockRangeMixIn, + mixins.AssignTypeMixin, + Statement, +): + """Class representing an :class:`ast.With` node. + + >>> node = astroid.extract_node(''' + with open(file_path) as file_: + print(file_.read()) + ''') + >>> node + + """ + + _astroid_fields = ("items", "body") + _other_other_fields = ("type_annotation",) + _multi_line_block_fields = ("body",) + items = None + """The pairs of context managers and the names they are assigned to. + + :type: list(tuple(NodeNG, AssignName or None)) or None + """ + body = None + """The contents of the ``with`` block. + + :type: list(NodeNG) or None + """ + type_annotation = None + """If present, this will contain the type annotation passed by a type comment + + :type: NodeNG or None + """ + + def postinit(self, items=None, body=None, type_annotation=None): + """Do some setup after initialisation. + + :param items: The pairs of context managers and the names + they are assigned to. + :type items: list(tuple(NodeNG, AssignName or None)) or None + + :param body: The contents of the ``with`` block. + :type body: list(NodeNG) or None + """ + self.items = items + self.body = body + self.type_annotation = type_annotation + + @decorators.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + return self.items[-1][0].tolineno + + def get_children(self): + """Get the child nodes below this node. + + :returns: The children. + :rtype: iterable(NodeNG) + """ + for expr, var in self.items: + yield expr + if var: + yield var + yield from self.body + + +class AsyncWith(With): + """Asynchronous ``with`` built with the ``async`` keyword.""" + + +class Yield(NodeNG): + """Class representing an :class:`ast.Yield` node. + + >>> node = astroid.extract_node('yield True') + >>> node + + """ + + _astroid_fields = ("value",) + value = None + """The value to yield. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: The value to yield. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + if self.value is not None: + yield self.value + + def _get_yield_nodes_skip_lambdas(self): + yield self + + +class YieldFrom(Yield): + """Class representing an :class:`ast.YieldFrom` node.""" + + +class DictUnpack(mixins.NoChildrenMixin, NodeNG): + """Represents the unpacking of dicts into dicts using :pep:`448`.""" + + +class FormattedValue(NodeNG): + """Class representing an :class:`ast.FormattedValue` node. + + Represents a :pep:`498` format string. + + >>> node = astroid.extract_node('f"Format {type_}"') + >>> node + + >>> node.values + [, ] + """ + + _astroid_fields = ("value", "format_spec") + value = None + """The value to be formatted into the string. + + :type: NodeNG or None + """ + conversion = None + """The type of formatting to be applied to the value. + + .. seealso:: + :class:`ast.FormattedValue` + + :type: int or None + """ + format_spec = None + """The formatting to be applied to the value. + + .. seealso:: + :class:`ast.FormattedValue` + + :type: JoinedStr or None + """ + + def postinit(self, value, conversion=None, format_spec=None): + """Do some setup after initialisation. + + :param value: The value to be formatted into the string. + :type value: NodeNG + + :param conversion: The type of formatting to be applied to the value. + :type conversion: int or None + + :param format_spec: The formatting to be applied to the value. + :type format_spec: JoinedStr or None + """ + self.value = value + self.conversion = conversion + self.format_spec = format_spec + + def get_children(self): + yield self.value + + if self.format_spec is not None: + yield self.format_spec + + +class JoinedStr(NodeNG): + """Represents a list of string expressions to be joined. + + >>> node = astroid.extract_node('f"Format {type_}"') + >>> node + + """ + + _astroid_fields = ("values",) + values = None + """The string expressions to be joined. + + :type: list(FormattedValue or Const) or None + """ + + def postinit(self, values=None): + """Do some setup after initialisation. + + :param value: The string expressions to be joined. + + :type: list(FormattedValue or Const) or None + """ + self.values = values + + def get_children(self): + yield from self.values + + +class NamedExpr(mixins.AssignTypeMixin, NodeNG): + """Represents the assignment from the assignment expression + + >>> module = astroid.parse('if a := 1: pass') + >>> module.body[0].test + + """ + + _astroid_fields = ("target", "value") + target = None + """The assignment target + + :type: Name + """ + value = None + """The value that gets assigned in the expression + + :type: NodeNG + """ + + def postinit(self, target, value): + self.target = target + self.value = value + + +class Unknown(mixins.AssignTypeMixin, NodeNG): + """This node represents a node in a constructed AST where + introspection is not possible. At the moment, it's only used in + the args attribute of FunctionDef nodes where function signature + introspection failed. + """ + + name = "Unknown" + + def qname(self): + return "Unknown" + + def infer(self, context=None, **kwargs): + """Inference on an Unknown node immediately terminates.""" + yield util.Uninferable + + +# constants ############################################################## + +CONST_CLS = { + list: List, + tuple: Tuple, + dict: Dict, + set: Set, + type(None): Const, + type(NotImplemented): Const, +} +if PY38: + CONST_CLS[type(...)] = Const + + +def _update_const_classes(): + """update constant classes, so the keys of CONST_CLS can be reused""" + klasses = (bool, int, float, complex, str, bytes) + for kls in klasses: + CONST_CLS[kls] = Const + + +_update_const_classes() + + +def _two_step_initialization(cls, value): + instance = cls() + instance.postinit(value) + return instance + + +def _dict_initialization(cls, value): + if isinstance(value, dict): + value = tuple(value.items()) + return _two_step_initialization(cls, value) + + +_CONST_CLS_CONSTRUCTORS = { + List: _two_step_initialization, + Tuple: _two_step_initialization, + Dict: _dict_initialization, + Set: _two_step_initialization, + Const: lambda cls, value: cls(value), +} + + +def const_factory(value): + """return an astroid node for a python value""" + # XXX we should probably be stricter here and only consider stuff in + # CONST_CLS or do better treatment: in case where value is not in CONST_CLS, + # we should rather recall the builder on this value than returning an empty + # node (another option being that const_factory shouldn't be called with something + # not in CONST_CLS) + assert not isinstance(value, NodeNG) + + # Hack for ignoring elements of a sequence + # or a mapping, in order to avoid transforming + # each element to an AST. This is fixed in 2.0 + # and this approach is a temporary hack. + if isinstance(value, (list, set, tuple, dict)): + elts = [] + else: + elts = value + + try: + initializer_cls = CONST_CLS[value.__class__] + initializer = _CONST_CLS_CONSTRUCTORS[initializer_cls] + return initializer(initializer_cls, elts) + except (KeyError, AttributeError): + node = EmptyNode() + node.object = value + return node + + +def is_from_decorator(node): + """Return True if the given node is the child of a decorator""" + parent = node.parent + while parent is not None: + if isinstance(parent, Decorators): + return True + parent = parent.parent + return False diff --git a/py3/lib/python3.6/site-packages/astroid/nodes.py b/py3/lib/python3.6/site-packages/astroid/nodes.py new file mode 100644 index 0000000..bf6911a --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/nodes.py @@ -0,0 +1,175 @@ +# Copyright (c) 2006-2011, 2013 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2010 Daniel Harding +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Jared Garst +# Copyright (c) 2017 Ashley Whetter +# Copyright (c) 2017 rr- +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Every available node class. + +.. seealso:: + :doc:`ast documentation ` + +All nodes inherit from :class:`~astroid.node_classes.NodeNG`. +""" +# pylint: disable=unused-import,redefined-builtin + +from astroid.node_classes import ( + Arguments, + AssignAttr, + Assert, + Assign, + AnnAssign, + AssignName, + AugAssign, + Repr, + BinOp, + BoolOp, + Break, + Call, + Compare, + Comprehension, + Const, + Continue, + Decorators, + DelAttr, + DelName, + Delete, + Dict, + Expr, + Ellipsis, + EmptyNode, + ExceptHandler, + Exec, + ExtSlice, + For, + ImportFrom, + Attribute, + Global, + If, + IfExp, + Import, + Index, + Keyword, + List, + Name, + NamedExpr, + Nonlocal, + Pass, + Print, + Raise, + Return, + Set, + Slice, + Starred, + Subscript, + TryExcept, + TryFinally, + Tuple, + UnaryOp, + While, + With, + Yield, + YieldFrom, + const_factory, + AsyncFor, + Await, + AsyncWith, + FormattedValue, + JoinedStr, + # Node not present in the builtin ast module. + DictUnpack, + Unknown, +) +from astroid.scoped_nodes import ( + Module, + GeneratorExp, + Lambda, + DictComp, + ListComp, + SetComp, + FunctionDef, + ClassDef, + AsyncFunctionDef, +) + + +ALL_NODE_CLASSES = ( + AsyncFunctionDef, + AsyncFor, + AsyncWith, + Await, + Arguments, + AssignAttr, + Assert, + Assign, + AnnAssign, + AssignName, + AugAssign, + Repr, + BinOp, + BoolOp, + Break, + Call, + ClassDef, + Compare, + Comprehension, + Const, + Continue, + Decorators, + DelAttr, + DelName, + Delete, + Dict, + DictComp, + DictUnpack, + Expr, + Ellipsis, + EmptyNode, + ExceptHandler, + Exec, + ExtSlice, + For, + ImportFrom, + FunctionDef, + Attribute, + GeneratorExp, + Global, + If, + IfExp, + Import, + Index, + Keyword, + Lambda, + List, + ListComp, + Name, + NamedExpr, + Nonlocal, + Module, + Pass, + Print, + Raise, + Return, + Set, + SetComp, + Slice, + Starred, + Subscript, + TryExcept, + TryFinally, + Tuple, + UnaryOp, + While, + With, + Yield, + YieldFrom, + FormattedValue, + JoinedStr, +) diff --git a/py3/lib/python3.6/site-packages/astroid/objects.py b/py3/lib/python3.6/site-packages/astroid/objects.py new file mode 100644 index 0000000..888ca36 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/objects.py @@ -0,0 +1,282 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +""" +Inference objects are a way to represent composite AST nodes, +which are used only as inference results, so they can't be found in the +original AST tree. For instance, inferring the following frozenset use, +leads to an inferred FrozenSet: + + Call(func=Name('frozenset'), args=Tuple(...)) +""" + +import builtins + +from astroid import bases +from astroid import decorators +from astroid import exceptions +from astroid import MANAGER +from astroid import node_classes +from astroid import scoped_nodes +from astroid import util + + +BUILTINS = builtins.__name__ +objectmodel = util.lazy_import("interpreter.objectmodel") + + +class FrozenSet(node_classes._BaseContainer): + """class representing a FrozenSet composite node""" + + def pytype(self): + return "%s.frozenset" % BUILTINS + + def _infer(self, context=None): + yield self + + @decorators.cachedproperty + def _proxied(self): # pylint: disable=method-hidden + ast_builtins = MANAGER.builtins_module + return ast_builtins.getattr("frozenset")[0] + + +class Super(node_classes.NodeNG): + """Proxy class over a super call. + + This class offers almost the same behaviour as Python's super, + which is MRO lookups for retrieving attributes from the parents. + + The *mro_pointer* is the place in the MRO from where we should + start looking, not counting it. *mro_type* is the object which + provides the MRO, it can be both a type or an instance. + *self_class* is the class where the super call is, while + *scope* is the function where the super call is. + """ + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.SuperModel()) + + # pylint: disable=super-init-not-called + def __init__(self, mro_pointer, mro_type, self_class, scope): + self.type = mro_type + self.mro_pointer = mro_pointer + self._class_based = False + self._self_class = self_class + self._scope = scope + + def _infer(self, context=None): + yield self + + def super_mro(self): + """Get the MRO which will be used to lookup attributes in this super.""" + if not isinstance(self.mro_pointer, scoped_nodes.ClassDef): + raise exceptions.SuperError( + "The first argument to super must be a subtype of " + "type, not {mro_pointer}.", + super_=self, + ) + + if isinstance(self.type, scoped_nodes.ClassDef): + # `super(type, type)`, most likely in a class method. + self._class_based = True + mro_type = self.type + else: + mro_type = getattr(self.type, "_proxied", None) + if not isinstance(mro_type, (bases.Instance, scoped_nodes.ClassDef)): + raise exceptions.SuperError( + "The second argument to super must be an " + "instance or subtype of type, not {type}.", + super_=self, + ) + + if not mro_type.newstyle: + raise exceptions.SuperError( + "Unable to call super on old-style classes.", super_=self + ) + + mro = mro_type.mro() + if self.mro_pointer not in mro: + raise exceptions.SuperError( + "The second argument to super must be an " + "instance or subtype of type, not {type}.", + super_=self, + ) + + index = mro.index(self.mro_pointer) + return mro[index + 1 :] + + @decorators.cachedproperty + def _proxied(self): + ast_builtins = MANAGER.builtins_module + return ast_builtins.getattr("super")[0] + + def pytype(self): + return "%s.super" % BUILTINS + + def display_type(self): + return "Super of" + + @property + def name(self): + """Get the name of the MRO pointer.""" + return self.mro_pointer.name + + def qname(self): + return "super" + + def igetattr(self, name, context=None): + """Retrieve the inferred values of the given attribute name.""" + + if name in self.special_attributes: + yield self.special_attributes.lookup(name) + return + + try: + mro = self.super_mro() + # Don't let invalid MROs or invalid super calls + # leak out as is from this function. + except exceptions.SuperError as exc: + raise exceptions.AttributeInferenceError( + ( + "Lookup for {name} on {target!r} because super call {super!r} " + "is invalid." + ), + target=self, + attribute=name, + context=context, + super_=exc.super_, + ) from exc + except exceptions.MroError as exc: + raise exceptions.AttributeInferenceError( + ( + "Lookup for {name} on {target!r} failed because {cls!r} has an " + "invalid MRO." + ), + target=self, + attribute=name, + context=context, + mros=exc.mros, + cls=exc.cls, + ) from exc + found = False + for cls in mro: + if name not in cls.locals: + continue + + found = True + for inferred in bases._infer_stmts([cls[name]], context, frame=self): + if not isinstance(inferred, scoped_nodes.FunctionDef): + yield inferred + continue + + # We can obtain different descriptors from a super depending + # on what we are accessing and where the super call is. + if inferred.type == "classmethod": + yield bases.BoundMethod(inferred, cls) + elif self._scope.type == "classmethod" and inferred.type == "method": + yield inferred + elif self._class_based or inferred.type == "staticmethod": + yield inferred + elif bases._is_property(inferred): + # TODO: support other descriptors as well. + try: + yield from inferred.infer_call_result(self, context) + except exceptions.InferenceError: + yield util.Uninferable + else: + yield bases.BoundMethod(inferred, cls) + + if not found: + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + + def getattr(self, name, context=None): + return list(self.igetattr(name, context=context)) + + +class ExceptionInstance(bases.Instance): + """Class for instances of exceptions + + It has special treatment for some of the exceptions's attributes, + which are transformed at runtime into certain concrete objects, such as + the case of .args. + """ + + @decorators.cachedproperty + def special_attributes(self): + qname = self.qname() + instance = objectmodel.BUILTIN_EXCEPTIONS.get( + qname, objectmodel.ExceptionInstanceModel + ) + return instance()(self) + + +class DictInstance(bases.Instance): + """Special kind of instances for dictionaries + + This instance knows the underlying object model of the dictionaries, which means + that methods such as .values or .items can be properly inferred. + """ + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.DictModel()) + + +# Custom objects tailored for dictionaries, which are used to +# disambiguate between the types of Python 2 dict's method returns +# and Python 3 (where they return set like objects). +class DictItems(bases.Proxy): + __str__ = node_classes.NodeNG.__str__ + __repr__ = node_classes.NodeNG.__repr__ + + +class DictKeys(bases.Proxy): + __str__ = node_classes.NodeNG.__str__ + __repr__ = node_classes.NodeNG.__repr__ + + +class DictValues(bases.Proxy): + __str__ = node_classes.NodeNG.__str__ + __repr__ = node_classes.NodeNG.__repr__ + + +class PartialFunction(scoped_nodes.FunctionDef): + """A class representing partial function obtained via functools.partial""" + + def __init__( + self, call, name=None, doc=None, lineno=None, col_offset=None, parent=None + ): + super().__init__(name, doc, lineno, col_offset, parent) + self.filled_positionals = len(call.positional_arguments[1:]) + self.filled_args = call.positional_arguments[1:] + self.filled_keywords = call.keyword_arguments + + def infer_call_result(self, caller=None, context=None): + if context: + current_passed_keywords = { + keyword for (keyword, _) in context.callcontext.keywords + } + for keyword, value in self.filled_keywords.items(): + if keyword not in current_passed_keywords: + context.callcontext.keywords.append((keyword, value)) + + call_context_args = context.callcontext.args or [] + context.callcontext.args = self.filled_args + call_context_args + + return super().infer_call_result(caller=caller, context=context) + + def qname(self): + return self.__class__.__name__ + + +# TODO: Hack to solve the circular import problem between node_classes and objects +# This is not needed in 2.0, which has a cleaner design overall +node_classes.Dict.__bases__ = (node_classes.NodeNG, DictInstance) diff --git a/py3/lib/python3.6/site-packages/astroid/protocols.py b/py3/lib/python3.6/site-packages/astroid/protocols.py new file mode 100644 index 0000000..c1825f1 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/protocols.py @@ -0,0 +1,766 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Dmitry Pribysh +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2017-2018 Ashley Whetter +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2017 rr- +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 HoverHell + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""this module contains a set of functions to handle python protocols for nodes +where it makes sense. +""" + +import collections +import operator as operator_mod + +import itertools + +from astroid import Store +from astroid import arguments +from astroid import bases +from astroid import context as contextmod +from astroid import exceptions +from astroid import decorators +from astroid import node_classes +from astroid import helpers +from astroid import nodes +from astroid import util + +raw_building = util.lazy_import("raw_building") +objects = util.lazy_import("objects") + + +def _reflected_name(name): + return "__r" + name[2:] + + +def _augmented_name(name): + return "__i" + name[2:] + + +_CONTEXTLIB_MGR = "contextlib.contextmanager" +BIN_OP_METHOD = { + "+": "__add__", + "-": "__sub__", + "/": "__truediv__", + "//": "__floordiv__", + "*": "__mul__", + "**": "__pow__", + "%": "__mod__", + "&": "__and__", + "|": "__or__", + "^": "__xor__", + "<<": "__lshift__", + ">>": "__rshift__", + "@": "__matmul__", +} + +REFLECTED_BIN_OP_METHOD = { + key: _reflected_name(value) for (key, value) in BIN_OP_METHOD.items() +} +AUGMENTED_OP_METHOD = { + key + "=": _augmented_name(value) for (key, value) in BIN_OP_METHOD.items() +} + +UNARY_OP_METHOD = { + "+": "__pos__", + "-": "__neg__", + "~": "__invert__", + "not": None, # XXX not '__nonzero__' +} +_UNARY_OPERATORS = { + "+": operator_mod.pos, + "-": operator_mod.neg, + "~": operator_mod.invert, + "not": operator_mod.not_, +} + + +def _infer_unary_op(obj, op): + func = _UNARY_OPERATORS[op] + value = func(obj) + return nodes.const_factory(value) + + +nodes.Tuple.infer_unary_op = lambda self, op: _infer_unary_op(tuple(self.elts), op) +nodes.List.infer_unary_op = lambda self, op: _infer_unary_op(self.elts, op) +nodes.Set.infer_unary_op = lambda self, op: _infer_unary_op(set(self.elts), op) +nodes.Const.infer_unary_op = lambda self, op: _infer_unary_op(self.value, op) +nodes.Dict.infer_unary_op = lambda self, op: _infer_unary_op(dict(self.items), op) + +# Binary operations + +BIN_OP_IMPL = { + "+": lambda a, b: a + b, + "-": lambda a, b: a - b, + "/": lambda a, b: a / b, + "//": lambda a, b: a // b, + "*": lambda a, b: a * b, + "**": lambda a, b: a ** b, + "%": lambda a, b: a % b, + "&": lambda a, b: a & b, + "|": lambda a, b: a | b, + "^": lambda a, b: a ^ b, + "<<": lambda a, b: a << b, + ">>": lambda a, b: a >> b, + "@": operator_mod.matmul, +} +for _KEY, _IMPL in list(BIN_OP_IMPL.items()): + BIN_OP_IMPL[_KEY + "="] = _IMPL + + +@decorators.yes_if_nothing_inferred +def const_infer_binary_op(self, opnode, operator, other, context, _): + not_implemented = nodes.Const(NotImplemented) + if isinstance(other, nodes.Const): + try: + impl = BIN_OP_IMPL[operator] + try: + yield nodes.const_factory(impl(self.value, other.value)) + except TypeError: + # ArithmeticError is not enough: float >> float is a TypeError + yield not_implemented + except Exception: # pylint: disable=broad-except + yield util.Uninferable + except TypeError: + yield not_implemented + elif isinstance(self.value, str) and operator == "%": + # TODO(cpopa): implement string interpolation later on. + yield util.Uninferable + else: + yield not_implemented + + +nodes.Const.infer_binary_op = const_infer_binary_op + + +def _multiply_seq_by_int(self, opnode, other, context): + node = self.__class__(parent=opnode) + filtered_elts = ( + helpers.safe_infer(elt, context) or util.Uninferable + for elt in self.elts + if elt is not util.Uninferable + ) + node.elts = list(filtered_elts) * other.value + return node + + +def _filter_uninferable_nodes(elts, context): + for elt in elts: + if elt is util.Uninferable: + yield nodes.Unknown() + else: + for inferred in elt.infer(context): + if inferred is not util.Uninferable: + yield inferred + else: + yield nodes.Unknown() + + +@decorators.yes_if_nothing_inferred +def tl_infer_binary_op(self, opnode, operator, other, context, method): + not_implemented = nodes.Const(NotImplemented) + if isinstance(other, self.__class__) and operator == "+": + node = self.__class__(parent=opnode) + node.elts = list( + itertools.chain( + _filter_uninferable_nodes(self.elts, context), + _filter_uninferable_nodes(other.elts, context), + ) + ) + yield node + elif isinstance(other, nodes.Const) and operator == "*": + if not isinstance(other.value, int): + yield not_implemented + return + yield _multiply_seq_by_int(self, opnode, other, context) + elif isinstance(other, bases.Instance) and operator == "*": + # Verify if the instance supports __index__. + as_index = helpers.class_instance_as_index(other) + if not as_index: + yield util.Uninferable + else: + yield _multiply_seq_by_int(self, opnode, as_index, context) + else: + yield not_implemented + + +nodes.Tuple.infer_binary_op = tl_infer_binary_op +nodes.List.infer_binary_op = tl_infer_binary_op + + +@decorators.yes_if_nothing_inferred +def instance_class_infer_binary_op(self, opnode, operator, other, context, method): + return method.infer_call_result(self, context) + + +bases.Instance.infer_binary_op = instance_class_infer_binary_op +nodes.ClassDef.infer_binary_op = instance_class_infer_binary_op + + +# assignment ################################################################## + +"""the assigned_stmts method is responsible to return the assigned statement +(e.g. not inferred) according to the assignment type. + +The `assign_path` argument is used to record the lhs path of the original node. +For instance if we want assigned statements for 'c' in 'a, (b,c)', assign_path +will be [1, 1] once arrived to the Assign node. + +The `context` argument is the current inference context which should be given +to any intermediary inference necessary. +""" + + +def _resolve_looppart(parts, assign_path, context): + """recursive function to resolve multiple assignments on loops""" + assign_path = assign_path[:] + index = assign_path.pop(0) + for part in parts: + if part is util.Uninferable: + continue + if not hasattr(part, "itered"): + continue + try: + itered = part.itered() + except TypeError: + continue + for stmt in itered: + index_node = nodes.Const(index) + try: + assigned = stmt.getitem(index_node, context) + except ( + AttributeError, + exceptions.AstroidTypeError, + exceptions.AstroidIndexError, + ): + continue + if not assign_path: + # we achieved to resolved the assignment path, + # don't infer the last part + yield assigned + elif assigned is util.Uninferable: + break + else: + # we are not yet on the last part of the path + # search on each possibly inferred value + try: + yield from _resolve_looppart( + assigned.infer(context), assign_path, context + ) + except exceptions.InferenceError: + break + + +@decorators.raise_if_nothing_inferred +def for_assigned_stmts(self, node=None, context=None, assign_path=None): + if isinstance(self, nodes.AsyncFor) or getattr(self, "is_async", False): + # Skip inferring of async code for now + return dict(node=self, unknown=node, assign_path=assign_path, context=context) + if assign_path is None: + for lst in self.iter.infer(context): + if isinstance(lst, (nodes.Tuple, nodes.List)): + yield from lst.elts + else: + yield from _resolve_looppart(self.iter.infer(context), assign_path, context) + return dict(node=self, unknown=node, assign_path=assign_path, context=context) + + +nodes.For.assigned_stmts = for_assigned_stmts +nodes.Comprehension.assigned_stmts = for_assigned_stmts + + +def sequence_assigned_stmts(self, node=None, context=None, assign_path=None): + if assign_path is None: + assign_path = [] + try: + index = self.elts.index(node) + except ValueError as exc: + raise exceptions.InferenceError( + "Tried to retrieve a node {node!r} which does not exist", + node=self, + assign_path=assign_path, + context=context, + ) from exc + + assign_path.insert(0, index) + return self.parent.assigned_stmts( + node=self, context=context, assign_path=assign_path + ) + + +nodes.Tuple.assigned_stmts = sequence_assigned_stmts +nodes.List.assigned_stmts = sequence_assigned_stmts + + +def assend_assigned_stmts(self, node=None, context=None, assign_path=None): + return self.parent.assigned_stmts(node=self, context=context) + + +nodes.AssignName.assigned_stmts = assend_assigned_stmts +nodes.AssignAttr.assigned_stmts = assend_assigned_stmts + + +def _arguments_infer_argname(self, name, context): + # arguments information may be missing, in which case we can't do anything + # more + if not (self.args or self.vararg or self.kwarg): + yield util.Uninferable + return + # first argument of instance/class method + if self.args and getattr(self.args[0], "name", None) == name: + functype = self.parent.type + cls = self.parent.parent.scope() + is_metaclass = isinstance(cls, nodes.ClassDef) and cls.type == "metaclass" + # If this is a metaclass, then the first argument will always + # be the class, not an instance. + if is_metaclass or functype == "classmethod": + yield cls + return + if functype == "method": + yield bases.Instance(cls) + return + + if context and context.callcontext: + call_site = arguments.CallSite(context.callcontext, context.extra_context) + yield from call_site.infer_argument(self.parent, name, context) + return + + if name == self.vararg: + vararg = nodes.const_factory(()) + vararg.parent = self + yield vararg + return + if name == self.kwarg: + kwarg = nodes.const_factory({}) + kwarg.parent = self + yield kwarg + return + # if there is a default value, yield it. And then yield Uninferable to reflect + # we can't guess given argument value + try: + context = contextmod.copy_context(context) + yield from self.default_value(name).infer(context) + yield util.Uninferable + except exceptions.NoDefault: + yield util.Uninferable + + +def arguments_assigned_stmts(self, node=None, context=None, assign_path=None): + if context.callcontext: + # reset call context/name + callcontext = context.callcontext + context = contextmod.copy_context(context) + context.callcontext = None + args = arguments.CallSite(callcontext) + return args.infer_argument(self.parent, node.name, context) + return _arguments_infer_argname(self, node.name, context) + + +nodes.Arguments.assigned_stmts = arguments_assigned_stmts + + +@decorators.raise_if_nothing_inferred +def assign_assigned_stmts(self, node=None, context=None, assign_path=None): + if not assign_path: + yield self.value + return None + yield from _resolve_assignment_parts( + self.value.infer(context), assign_path, context + ) + + return dict(node=self, unknown=node, assign_path=assign_path, context=context) + + +def assign_annassigned_stmts(self, node=None, context=None, assign_path=None): + for inferred in assign_assigned_stmts(self, node, context, assign_path): + if inferred is None: + yield util.Uninferable + else: + yield inferred + + +nodes.Assign.assigned_stmts = assign_assigned_stmts +nodes.AnnAssign.assigned_stmts = assign_annassigned_stmts +nodes.AugAssign.assigned_stmts = assign_assigned_stmts + + +def _resolve_assignment_parts(parts, assign_path, context): + """recursive function to resolve multiple assignments""" + assign_path = assign_path[:] + index = assign_path.pop(0) + for part in parts: + assigned = None + if isinstance(part, nodes.Dict): + # A dictionary in an iterating context + try: + assigned, _ = part.items[index] + except IndexError: + return + + elif hasattr(part, "getitem"): + index_node = nodes.Const(index) + try: + assigned = part.getitem(index_node, context) + except (exceptions.AstroidTypeError, exceptions.AstroidIndexError): + return + + if not assigned: + return + + if not assign_path: + # we achieved to resolved the assignment path, don't infer the + # last part + yield assigned + elif assigned is util.Uninferable: + return + else: + # we are not yet on the last part of the path search on each + # possibly inferred value + try: + yield from _resolve_assignment_parts( + assigned.infer(context), assign_path, context + ) + except exceptions.InferenceError: + return + + +@decorators.raise_if_nothing_inferred +def excepthandler_assigned_stmts(self, node=None, context=None, assign_path=None): + for assigned in node_classes.unpack_infer(self.type): + if isinstance(assigned, nodes.ClassDef): + assigned = objects.ExceptionInstance(assigned) + + yield assigned + return dict(node=self, unknown=node, assign_path=assign_path, context=context) + + +nodes.ExceptHandler.assigned_stmts = excepthandler_assigned_stmts + + +def _infer_context_manager(self, mgr, context): + inferred = next(mgr.infer(context=context)) + if isinstance(inferred, bases.Generator): + # Check if it is decorated with contextlib.contextmanager. + func = inferred.parent + if not func.decorators: + raise exceptions.InferenceError( + "No decorators found on inferred generator %s", node=func + ) + + for decorator_node in func.decorators.nodes: + decorator = next(decorator_node.infer(context)) + if isinstance(decorator, nodes.FunctionDef): + if decorator.qname() == _CONTEXTLIB_MGR: + break + else: + # It doesn't interest us. + raise exceptions.InferenceError(node=func) + + # Get the first yield point. If it has multiple yields, + # then a RuntimeError will be raised. + + possible_yield_points = func.nodes_of_class(nodes.Yield) + # Ignore yields in nested functions + yield_point = next( + (node for node in possible_yield_points if node.scope() == func), None + ) + if yield_point: + if not yield_point.value: + const = nodes.Const(None) + const.parent = yield_point + const.lineno = yield_point.lineno + yield const + else: + yield from yield_point.value.infer(context=context) + elif isinstance(inferred, bases.Instance): + try: + enter = next(inferred.igetattr("__enter__", context=context)) + except (exceptions.InferenceError, exceptions.AttributeInferenceError): + raise exceptions.InferenceError(node=inferred) + if not isinstance(enter, bases.BoundMethod): + raise exceptions.InferenceError(node=enter) + yield from enter.infer_call_result(self, context) + else: + raise exceptions.InferenceError(node=mgr) + + +@decorators.raise_if_nothing_inferred +def with_assigned_stmts(self, node=None, context=None, assign_path=None): + """Infer names and other nodes from a *with* statement. + + This enables only inference for name binding in a *with* statement. + For instance, in the following code, inferring `func` will return + the `ContextManager` class, not whatever ``__enter__`` returns. + We are doing this intentionally, because we consider that the context + manager result is whatever __enter__ returns and what it is binded + using the ``as`` keyword. + + class ContextManager(object): + def __enter__(self): + return 42 + with ContextManager() as f: + pass + + # ContextManager().infer() will return ContextManager + # f.infer() will return 42. + + Arguments: + self: nodes.With + node: The target of the assignment, `as (a, b)` in `with foo as (a, b)`. + context: Inference context used for caching already inferred objects + assign_path: + A list of indices, where each index specifies what item to fetch from + the inference results. + """ + try: + mgr = next(mgr for (mgr, vars) in self.items if vars == node) + except StopIteration: + return None + if assign_path is None: + yield from _infer_context_manager(self, mgr, context) + else: + for result in _infer_context_manager(self, mgr, context): + # Walk the assign_path and get the item at the final index. + obj = result + for index in assign_path: + if not hasattr(obj, "elts"): + raise exceptions.InferenceError( + "Wrong type ({targets!r}) for {node!r} assignment", + node=self, + targets=node, + assign_path=assign_path, + context=context, + ) + try: + obj = obj.elts[index] + except IndexError as exc: + raise exceptions.InferenceError( + "Tried to infer a nonexistent target with index {index} " + "in {node!r}.", + node=self, + targets=node, + assign_path=assign_path, + context=context, + ) from exc + except TypeError as exc: + raise exceptions.InferenceError( + "Tried to unpack a non-iterable value " "in {node!r}.", + node=self, + targets=node, + assign_path=assign_path, + context=context, + ) from exc + yield obj + return dict(node=self, unknown=node, assign_path=assign_path, context=context) + + +nodes.With.assigned_stmts = with_assigned_stmts + + +@decorators.raise_if_nothing_inferred +def named_expr_assigned_stmts(self, node, context=None, assign_path=None): + """Infer names and other nodes from an assignment expression""" + if self.target == node: + yield from self.value.infer(context=context) + else: + raise exceptions.InferenceError( + "Cannot infer NamedExpr node {node!r}", + node=self, + assign_path=assign_path, + context=context, + ) + + +nodes.NamedExpr.assigned_stmts = named_expr_assigned_stmts + + +@decorators.yes_if_nothing_inferred +def starred_assigned_stmts(self, node=None, context=None, assign_path=None): + """ + Arguments: + self: nodes.Starred + node: a node related to the current underlying Node. + context: Inference context used for caching already inferred objects + assign_path: + A list of indices, where each index specifies what item to fetch from + the inference results. + """ + # pylint: disable=too-many-locals,too-many-branches,too-many-statements + def _determine_starred_iteration_lookups(starred, target, lookups): + # Determine the lookups for the rhs of the iteration + itered = target.itered() + for index, element in enumerate(itered): + if ( + isinstance(element, nodes.Starred) + and element.value.name == starred.value.name + ): + lookups.append((index, len(itered))) + break + if isinstance(element, nodes.Tuple): + lookups.append((index, len(element.itered()))) + _determine_starred_iteration_lookups(starred, element, lookups) + + stmt = self.statement() + if not isinstance(stmt, (nodes.Assign, nodes.For)): + raise exceptions.InferenceError( + "Statement {stmt!r} enclosing {node!r} " "must be an Assign or For node.", + node=self, + stmt=stmt, + unknown=node, + context=context, + ) + + if context is None: + context = contextmod.InferenceContext() + + if isinstance(stmt, nodes.Assign): + value = stmt.value + lhs = stmt.targets[0] + + if sum(1 for _ in lhs.nodes_of_class(nodes.Starred)) > 1: + raise exceptions.InferenceError( + "Too many starred arguments in the " " assignment targets {lhs!r}.", + node=self, + targets=lhs, + unknown=node, + context=context, + ) + + try: + rhs = next(value.infer(context)) + except exceptions.InferenceError: + yield util.Uninferable + return + if rhs is util.Uninferable or not hasattr(rhs, "itered"): + yield util.Uninferable + return + + try: + elts = collections.deque(rhs.itered()) + except TypeError: + yield util.Uninferable + return + + # Unpack iteratively the values from the rhs of the assignment, + # until the find the starred node. What will remain will + # be the list of values which the Starred node will represent + # This is done in two steps, from left to right to remove + # anything before the starred node and from right to left + # to remove anything after the starred node. + + for index, left_node in enumerate(lhs.elts): + if not isinstance(left_node, nodes.Starred): + if not elts: + break + elts.popleft() + continue + lhs_elts = collections.deque(reversed(lhs.elts[index:])) + for right_node in lhs_elts: + if not isinstance(right_node, nodes.Starred): + if not elts: + break + elts.pop() + continue + # We're done + packed = nodes.List( + ctx=Store, parent=self, lineno=lhs.lineno, col_offset=lhs.col_offset + ) + packed.postinit(elts=elts) + yield packed + break + + if isinstance(stmt, nodes.For): + try: + inferred_iterable = next(stmt.iter.infer(context=context)) + except exceptions.InferenceError: + yield util.Uninferable + return + if inferred_iterable is util.Uninferable or not hasattr( + inferred_iterable, "itered" + ): + yield util.Uninferable + return + try: + itered = inferred_iterable.itered() + except TypeError: + yield util.Uninferable + return + + target = stmt.target + + if not isinstance(target, nodes.Tuple): + raise exceptions.InferenceError( + "Could not make sense of this, the target must be a tuple", + context=context, + ) + + lookups = [] + _determine_starred_iteration_lookups(self, target, lookups) + if not lookups: + raise exceptions.InferenceError( + "Could not make sense of this, needs at least a lookup", context=context + ) + + # Make the last lookup a slice, since that what we want for a Starred node + last_element_index, last_element_length = lookups[-1] + is_starred_last = last_element_index == (last_element_length - 1) + + lookup_slice = slice( + last_element_index, + None if is_starred_last else (last_element_length - last_element_index), + ) + lookups[-1] = lookup_slice + + for element in itered: + + # We probably want to infer the potential values *for each* element in an + # iterable, but we can't infer a list of all values, when only a list of + # step values are expected: + # + # for a, *b in [...]: + # b + # + # *b* should now point to just the elements at that particular iteration step, + # which astroid can't know about. + + found_element = None + for lookup in lookups: + if not hasattr(element, "itered"): + break + if not isinstance(lookup, slice): + # Grab just the index, not the whole length + lookup = lookup[0] + try: + itered_inner_element = element.itered() + element = itered_inner_element[lookup] + except IndexError: + break + except TypeError: + # Most likely the itered() call failed, cannot make sense of this + yield util.Uninferable + return + else: + found_element = element + + unpacked = nodes.List( + ctx=Store, parent=self, lineno=self.lineno, col_offset=self.col_offset + ) + unpacked.postinit(elts=found_element or []) + yield unpacked + return + + yield util.Uninferable + + +nodes.Starred.assigned_stmts = starred_assigned_stmts diff --git a/py3/lib/python3.6/site-packages/astroid/raw_building.py b/py3/lib/python3.6/site-packages/astroid/raw_building.py new file mode 100644 index 0000000..d94f924 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/raw_building.py @@ -0,0 +1,468 @@ +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2012 FELD Boris +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2015 Ovidiu Sabou +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""this module contains a set of functions to create astroid trees from scratch +(build_* functions) or from living object (object_build_* functions) +""" + +import builtins +import inspect +import os +import sys +import types + +from astroid import bases +from astroid import manager +from astroid import node_classes +from astroid import nodes + + +MANAGER = manager.AstroidManager() +# the keys of CONST_CLS eg python builtin types + +_CONSTANTS = tuple(node_classes.CONST_CLS) +_BUILTINS = vars(builtins) +TYPE_NONE = type(None) +TYPE_NOTIMPLEMENTED = type(NotImplemented) +TYPE_ELLIPSIS = type(...) + + +def _io_discrepancy(member): + # _io module names itself `io`: http://bugs.python.org/issue18602 + member_self = getattr(member, "__self__", None) + return ( + member_self + and inspect.ismodule(member_self) + and member_self.__name__ == "_io" + and member.__module__ == "io" + ) + + +def _attach_local_node(parent, node, name): + node.name = name # needed by add_local_node + parent.add_local_node(node) + + +def _add_dunder_class(func, member): + """Add a __class__ member to the given func node, if we can determine it.""" + python_cls = member.__class__ + cls_name = getattr(python_cls, "__name__", None) + if not cls_name: + return + cls_bases = [ancestor.__name__ for ancestor in python_cls.__bases__] + ast_klass = build_class(cls_name, cls_bases, python_cls.__doc__) + func.instance_attrs["__class__"] = [ast_klass] + + +_marker = object() + + +def attach_dummy_node(node, name, runtime_object=_marker): + """create a dummy node and register it in the locals of the given + node with the specified name + """ + enode = nodes.EmptyNode() + enode.object = runtime_object + _attach_local_node(node, enode, name) + + +def _has_underlying_object(self): + return self.object is not None and self.object is not _marker + + +nodes.EmptyNode.has_underlying_object = _has_underlying_object + + +def attach_const_node(node, name, value): + """create a Const node and register it in the locals of the given + node with the specified name + """ + if name not in node.special_attributes: + _attach_local_node(node, nodes.const_factory(value), name) + + +def attach_import_node(node, modname, membername): + """create a ImportFrom node and register it in the locals of the given + node with the specified name + """ + from_node = nodes.ImportFrom(modname, [(membername, None)]) + _attach_local_node(node, from_node, membername) + + +def build_module(name, doc=None): + """create and initialize an astroid Module node""" + node = nodes.Module(name, doc, pure_python=False) + node.package = False + node.parent = None + return node + + +def build_class(name, basenames=(), doc=None): + """create and initialize an astroid ClassDef node""" + node = nodes.ClassDef(name, doc) + for base in basenames: + basenode = nodes.Name() + basenode.name = base + node.bases.append(basenode) + basenode.parent = node + return node + + +def build_function(name, args=None, posonlyargs=None, defaults=None, doc=None): + """create and initialize an astroid FunctionDef node""" + args, defaults, posonlyargs = args or [], defaults or [], posonlyargs or [] + # first argument is now a list of decorators + func = nodes.FunctionDef(name, doc) + func.args = argsnode = nodes.Arguments() + argsnode.args = [] + argsnode.posonlyargs = [] + for arg in args: + argsnode.args.append(nodes.Name()) + argsnode.args[-1].name = arg + argsnode.args[-1].parent = argsnode + for arg in posonlyargs: + argsnode.posonlyargs.append(nodes.Name()) + argsnode.posonlyargs[-1].name = arg + argsnode.posonlyargs[-1].parent = argsnode + argsnode.defaults = [] + for default in defaults: + argsnode.defaults.append(nodes.const_factory(default)) + argsnode.defaults[-1].parent = argsnode + argsnode.kwarg = None + argsnode.vararg = None + argsnode.parent = func + if args: + register_arguments(func) + return func + + +def build_from_import(fromname, names): + """create and initialize an astroid ImportFrom import statement""" + return nodes.ImportFrom(fromname, [(name, None) for name in names]) + + +def register_arguments(func, args=None): + """add given arguments to local + + args is a list that may contains nested lists + (i.e. def func(a, (b, c, d)): ...) + """ + if args is None: + args = func.args.args + if func.args.vararg: + func.set_local(func.args.vararg, func.args) + if func.args.kwarg: + func.set_local(func.args.kwarg, func.args) + for arg in args: + if isinstance(arg, nodes.Name): + func.set_local(arg.name, arg) + else: + register_arguments(func, arg.elts) + + +def object_build_class(node, member, localname): + """create astroid for a living class object""" + basenames = [base.__name__ for base in member.__bases__] + return _base_class_object_build(node, member, basenames, localname=localname) + + +def object_build_function(node, member, localname): + """create astroid for a living function object""" + signature = inspect.signature(member) + args = [] + defaults = [] + posonlyargs = [] + for param_name, param in signature.parameters.items(): + if param.kind == inspect.Parameter.POSITIONAL_ONLY: + posonlyargs.append(param_name) + elif param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD: + args.append(param_name) + elif param.kind == inspect.Parameter.VAR_POSITIONAL: + args.append(param_name) + elif param.kind == inspect.Parameter.VAR_KEYWORD: + args.append(param_name) + if param.default is not inspect._empty: + defaults.append(param.default) + func = build_function( + getattr(member, "__name__", None) or localname, + args, + posonlyargs, + defaults, + member.__doc__, + ) + node.add_local_node(func, localname) + + +def object_build_datadescriptor(node, member, name): + """create astroid for a living data descriptor object""" + return _base_class_object_build(node, member, [], name) + + +def object_build_methoddescriptor(node, member, localname): + """create astroid for a living method descriptor object""" + # FIXME get arguments ? + func = build_function( + getattr(member, "__name__", None) or localname, doc=member.__doc__ + ) + # set node's arguments to None to notice that we have no information, not + # and empty argument list + func.args.args = None + node.add_local_node(func, localname) + _add_dunder_class(func, member) + + +def _base_class_object_build(node, member, basenames, name=None, localname=None): + """create astroid for a living class object, with a given set of base names + (e.g. ancestors) + """ + klass = build_class( + name or getattr(member, "__name__", None) or localname, + basenames, + member.__doc__, + ) + klass._newstyle = isinstance(member, type) + node.add_local_node(klass, localname) + try: + # limit the instantiation trick since it's too dangerous + # (such as infinite test execution...) + # this at least resolves common case such as Exception.args, + # OSError.errno + if issubclass(member, Exception): + instdict = member().__dict__ + else: + raise TypeError + except TypeError: + pass + else: + for item_name, obj in instdict.items(): + valnode = nodes.EmptyNode() + valnode.object = obj + valnode.parent = klass + valnode.lineno = 1 + klass.instance_attrs[item_name] = [valnode] + return klass + + +def _build_from_function(node, name, member, module): + # verify this is not an imported function + try: + code = member.__code__ + except AttributeError: + # Some implementations don't provide the code object, + # such as Jython. + code = None + filename = getattr(code, "co_filename", None) + if filename is None: + assert isinstance(member, object) + object_build_methoddescriptor(node, member, name) + elif filename != getattr(module, "__file__", None): + attach_dummy_node(node, name, member) + else: + object_build_function(node, member, name) + + +class InspectBuilder: + """class for building nodes from living object + + this is actually a really minimal representation, including only Module, + FunctionDef and ClassDef nodes and some others as guessed. + """ + + def __init__(self): + self._done = {} + self._module = None + + def inspect_build(self, module, modname=None, path=None): + """build astroid from a living module (i.e. using inspect) + this is used when there is no python source code available (either + because it's a built-in module or because the .py is not available) + """ + self._module = module + if modname is None: + modname = module.__name__ + try: + node = build_module(modname, module.__doc__) + except AttributeError: + # in jython, java modules have no __doc__ (see #109562) + node = build_module(modname) + node.file = node.path = os.path.abspath(path) if path else path + node.name = modname + MANAGER.cache_module(node) + node.package = hasattr(module, "__path__") + self._done = {} + self.object_build(node, module) + return node + + def object_build(self, node, obj): + """recursive method which create a partial ast from real objects + (only function, class, and method are handled) + """ + if obj in self._done: + return self._done[obj] + self._done[obj] = node + for name in dir(obj): + try: + member = getattr(obj, name) + except AttributeError: + # damned ExtensionClass.Base, I know you're there ! + attach_dummy_node(node, name) + continue + if inspect.ismethod(member): + member = member.__func__ + if inspect.isfunction(member): + _build_from_function(node, name, member, self._module) + elif inspect.isbuiltin(member): + if not _io_discrepancy(member) and self.imported_member( + node, member, name + ): + continue + object_build_methoddescriptor(node, member, name) + elif inspect.isclass(member): + if self.imported_member(node, member, name): + continue + if member in self._done: + class_node = self._done[member] + if class_node not in node.locals.get(name, ()): + node.add_local_node(class_node, name) + else: + class_node = object_build_class(node, member, name) + # recursion + self.object_build(class_node, member) + if name == "__class__" and class_node.parent is None: + class_node.parent = self._done[self._module] + elif inspect.ismethoddescriptor(member): + assert isinstance(member, object) + object_build_methoddescriptor(node, member, name) + elif inspect.isdatadescriptor(member): + assert isinstance(member, object) + object_build_datadescriptor(node, member, name) + elif isinstance(member, _CONSTANTS): + attach_const_node(node, name, member) + elif inspect.isroutine(member): + # This should be called for Jython, where some builtin + # methods aren't caught by isbuiltin branch. + _build_from_function(node, name, member, self._module) + else: + # create an empty node so that the name is actually defined + attach_dummy_node(node, name, member) + return None + + def imported_member(self, node, member, name): + """verify this is not an imported class or handle it""" + # /!\ some classes like ExtensionClass doesn't have a __module__ + # attribute ! Also, this may trigger an exception on badly built module + # (see http://www.logilab.org/ticket/57299 for instance) + try: + modname = getattr(member, "__module__", None) + except TypeError: + modname = None + if modname is None: + if name in ("__new__", "__subclasshook__"): + # Python 2.5.1 (r251:54863, Sep 1 2010, 22:03:14) + # >>> print object.__new__.__module__ + # None + modname = builtins.__name__ + else: + attach_dummy_node(node, name, member) + return True + + real_name = {"gtk": "gtk_gtk", "_io": "io"}.get(modname, modname) + + if real_name != self._module.__name__: + # check if it sounds valid and then add an import node, else use a + # dummy node + try: + getattr(sys.modules[modname], name) + except (KeyError, AttributeError): + attach_dummy_node(node, name, member) + else: + attach_import_node(node, modname, name) + return True + return False + + +### astroid bootstrapping ###################################################### + +_CONST_PROXY = {} + +# TODO : find a nicer way to handle this situation; +def _set_proxied(const): + return _CONST_PROXY[const.value.__class__] + + +def _astroid_bootstrapping(): + """astroid bootstrapping the builtins module""" + # this boot strapping is necessary since we need the Const nodes to + # inspect_build builtins, and then we can proxy Const + builder = InspectBuilder() + astroid_builtin = builder.inspect_build(builtins) + + # pylint: disable=redefined-outer-name + for cls, node_cls in node_classes.CONST_CLS.items(): + if cls is TYPE_NONE: + proxy = build_class("NoneType") + proxy.parent = astroid_builtin + elif cls is TYPE_NOTIMPLEMENTED: + proxy = build_class("NotImplementedType") + proxy.parent = astroid_builtin + elif cls is TYPE_ELLIPSIS: + proxy = build_class("Ellipsis") + proxy.parent = astroid_builtin + else: + proxy = astroid_builtin.getattr(cls.__name__)[0] + if cls in (dict, list, set, tuple): + node_cls._proxied = proxy + else: + _CONST_PROXY[cls] = proxy + + # Set the builtin module as parent for some builtins. + nodes.Const._proxied = property(_set_proxied) + + _GeneratorType = nodes.ClassDef( + types.GeneratorType.__name__, types.GeneratorType.__doc__ + ) + _GeneratorType.parent = astroid_builtin + bases.Generator._proxied = _GeneratorType + builder.object_build(bases.Generator._proxied, types.GeneratorType) + + if hasattr(types, "AsyncGeneratorType"): + # pylint: disable=no-member; AsyncGeneratorType + _AsyncGeneratorType = nodes.ClassDef( + types.AsyncGeneratorType.__name__, types.AsyncGeneratorType.__doc__ + ) + _AsyncGeneratorType.parent = astroid_builtin + bases.AsyncGenerator._proxied = _AsyncGeneratorType + builder.object_build(bases.AsyncGenerator._proxied, types.AsyncGeneratorType) + builtin_types = ( + types.GetSetDescriptorType, + types.GeneratorType, + types.MemberDescriptorType, + TYPE_NONE, + TYPE_NOTIMPLEMENTED, + types.FunctionType, + types.MethodType, + types.BuiltinFunctionType, + types.ModuleType, + types.TracebackType, + ) + for _type in builtin_types: + if _type.__name__ not in astroid_builtin: + cls = nodes.ClassDef(_type.__name__, _type.__doc__) + cls.parent = astroid_builtin + builder.object_build(cls, _type) + astroid_builtin[_type.__name__] = cls + + +_astroid_bootstrapping() diff --git a/py3/lib/python3.6/site-packages/astroid/rebuilder.py b/py3/lib/python3.6/site-packages/astroid/rebuilder.py new file mode 100644 index 0000000..fb78f7b --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/rebuilder.py @@ -0,0 +1,1090 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2013-2018 Claudiu Popa +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014 Alexander Presnyakov +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016-2017 Derek Gustafson +# Copyright (c) 2016 Jared Garst +# Copyright (c) 2017 Hugo +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2017 rr- +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""this module contains utilities for rebuilding a _ast tree in +order to get a single Astroid representation +""" + +import sys + +import astroid +from astroid._ast import _parse, _get_parser_module, parse_function_type_comment +from astroid import nodes + + +CONST_NAME_TRANSFORMS = {"None": None, "True": True, "False": False} + +REDIRECT = { + "arguments": "Arguments", + "comprehension": "Comprehension", + "ListCompFor": "Comprehension", + "GenExprFor": "Comprehension", + "excepthandler": "ExceptHandler", + "keyword": "Keyword", +} +PY37 = sys.version_info >= (3, 7) +PY38 = sys.version_info >= (3, 8) + + +def _binary_operators_from_module(module): + binary_operators = { + module.Add: "+", + module.BitAnd: "&", + module.BitOr: "|", + module.BitXor: "^", + module.Div: "/", + module.FloorDiv: "//", + module.MatMult: "@", + module.Mod: "%", + module.Mult: "*", + module.Pow: "**", + module.Sub: "-", + module.LShift: "<<", + module.RShift: ">>", + } + return binary_operators + + +def _bool_operators_from_module(module): + return {module.And: "and", module.Or: "or"} + + +def _unary_operators_from_module(module): + return {module.UAdd: "+", module.USub: "-", module.Not: "not", module.Invert: "~"} + + +def _compare_operators_from_module(module): + return { + module.Eq: "==", + module.Gt: ">", + module.GtE: ">=", + module.In: "in", + module.Is: "is", + module.IsNot: "is not", + module.Lt: "<", + module.LtE: "<=", + module.NotEq: "!=", + module.NotIn: "not in", + } + + +def _contexts_from_module(module): + return { + module.Load: astroid.Load, + module.Store: astroid.Store, + module.Del: astroid.Del, + module.Param: astroid.Store, + } + + +def _visit_or_none(node, attr, visitor, parent, visit="visit", **kws): + """If the given node has an attribute, visits the attribute, and + otherwise returns None. + + """ + value = getattr(node, attr, None) + if value: + return getattr(visitor, visit)(value, parent, **kws) + + return None + + +class TreeRebuilder: + """Rebuilds the _ast tree to become an Astroid tree""" + + def __init__(self, manager, parse_python_two: bool = False): + self._manager = manager + self._global_names = [] + self._import_from_nodes = [] + self._delayed_assattr = [] + self._visit_meths = {} + + # Configure the right classes for the right module + self._parser_module = _get_parser_module(parse_python_two=parse_python_two) + self._unary_op_classes = _unary_operators_from_module(self._parser_module) + self._cmp_op_classes = _compare_operators_from_module(self._parser_module) + self._bool_op_classes = _bool_operators_from_module(self._parser_module) + self._bin_op_classes = _binary_operators_from_module(self._parser_module) + self._context_classes = _contexts_from_module(self._parser_module) + + def _get_doc(self, node): + try: + if PY37 and hasattr(node, "docstring"): + doc = node.docstring + return node, doc + if node.body and isinstance(node.body[0], self._parser_module.Expr): + + first_value = node.body[0].value + if isinstance(first_value, self._parser_module.Str) or ( + PY38 + and isinstance(first_value, self._parser_module.Constant) + and isinstance(first_value.value, str) + ): + doc = first_value.value if PY38 else first_value.s + node.body = node.body[1:] + return node, doc + except IndexError: + pass # ast built from scratch + return node, None + + def _get_context(self, node): + return self._context_classes.get(type(node.ctx), astroid.Load) + + def visit_module(self, node, modname, modpath, package): + """visit a Module node by returning a fresh instance of it""" + node, doc = self._get_doc(node) + newnode = nodes.Module( + name=modname, + doc=doc, + file=modpath, + path=[modpath], + package=package, + parent=None, + ) + newnode.postinit([self.visit(child, newnode) for child in node.body]) + return newnode + + def visit(self, node, parent): + cls = node.__class__ + if cls in self._visit_meths: + visit_method = self._visit_meths[cls] + else: + cls_name = cls.__name__ + visit_name = "visit_" + REDIRECT.get(cls_name, cls_name).lower() + visit_method = getattr(self, visit_name) + self._visit_meths[cls] = visit_method + return visit_method(node, parent) + + def _save_assignment(self, node, name=None): + """save assignement situation since node.parent is not available yet""" + if self._global_names and node.name in self._global_names[-1]: + node.root().set_local(node.name, node) + else: + node.parent.set_local(node.name, node) + + def visit_arguments(self, node, parent): + """visit an Arguments node by returning a fresh instance of it""" + vararg, kwarg = node.vararg, node.kwarg + newnode = nodes.Arguments( + vararg.arg if vararg else None, kwarg.arg if kwarg else None, parent + ) + args = [self.visit(child, newnode) for child in node.args] + defaults = [self.visit(child, newnode) for child in node.defaults] + varargannotation = None + kwargannotation = None + posonlyargs = [] + # change added in 82732 (7c5c678e4164), vararg and kwarg + # are instances of `_ast.arg`, not strings + if vararg: + if node.vararg.annotation: + varargannotation = self.visit(node.vararg.annotation, newnode) + vararg = vararg.arg + if kwarg: + if node.kwarg.annotation: + kwargannotation = self.visit(node.kwarg.annotation, newnode) + kwarg = kwarg.arg + kwonlyargs = [self.visit(child, newnode) for child in node.kwonlyargs] + kw_defaults = [ + self.visit(child, newnode) if child else None for child in node.kw_defaults + ] + annotations = [ + self.visit(arg.annotation, newnode) if arg.annotation else None + for arg in node.args + ] + kwonlyargs_annotations = [ + self.visit(arg.annotation, newnode) if arg.annotation else None + for arg in node.kwonlyargs + ] + + posonlyargs_annotations = [] + if PY38: + posonlyargs = [self.visit(child, newnode) for child in node.posonlyargs] + posonlyargs_annotations = [ + self.visit(arg.annotation, newnode) if arg.annotation else None + for arg in node.posonlyargs + ] + type_comment_args = [ + self.check_type_comment(child, parent=newnode) for child in node.args + ] + + newnode.postinit( + args=args, + defaults=defaults, + kwonlyargs=kwonlyargs, + posonlyargs=posonlyargs, + kw_defaults=kw_defaults, + annotations=annotations, + kwonlyargs_annotations=kwonlyargs_annotations, + posonlyargs_annotations=posonlyargs_annotations, + varargannotation=varargannotation, + kwargannotation=kwargannotation, + type_comment_args=type_comment_args, + ) + # save argument names in locals: + if vararg: + newnode.parent.set_local(vararg, newnode) + if kwarg: + newnode.parent.set_local(kwarg, newnode) + return newnode + + def visit_assert(self, node, parent): + """visit a Assert node by returning a fresh instance of it""" + newnode = nodes.Assert(node.lineno, node.col_offset, parent) + if node.msg: + msg = self.visit(node.msg, newnode) + else: + msg = None + newnode.postinit(self.visit(node.test, newnode), msg) + return newnode + + def check_type_comment(self, node, parent): + type_comment = getattr(node, "type_comment", None) + if not type_comment: + return None + + try: + type_comment_ast = _parse(type_comment) + except SyntaxError: + # Invalid type comment, just skip it. + return None + + type_object = self.visit(type_comment_ast.body[0], parent=parent) + if not isinstance(type_object, nodes.Expr): + return None + + return type_object.value + + def check_function_type_comment(self, node): + type_comment = getattr(node, "type_comment", None) + if not type_comment: + return None + + try: + type_comment_ast = parse_function_type_comment(type_comment) + except SyntaxError: + # Invalid type comment, just skip it. + return None + + returns = None + argtypes = [ + self.visit(elem, node) for elem in (type_comment_ast.argtypes or []) + ] + if type_comment_ast.returns: + returns = self.visit(type_comment_ast.returns, node) + + return returns, argtypes + + def visit_assign(self, node, parent): + """visit a Assign node by returning a fresh instance of it""" + newnode = nodes.Assign(node.lineno, node.col_offset, parent) + type_annotation = self.check_type_comment(node, parent=newnode) + newnode.postinit( + targets=[self.visit(child, newnode) for child in node.targets], + value=self.visit(node.value, newnode), + type_annotation=type_annotation, + ) + return newnode + + def visit_assignname(self, node, parent, node_name=None): + """visit a node and return a AssignName node""" + newnode = nodes.AssignName( + node_name, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + self._save_assignment(newnode) + return newnode + + def visit_augassign(self, node, parent): + """visit a AugAssign node by returning a fresh instance of it""" + newnode = nodes.AugAssign( + self._bin_op_classes[type(node.op)] + "=", + node.lineno, + node.col_offset, + parent, + ) + newnode.postinit( + self.visit(node.target, newnode), self.visit(node.value, newnode) + ) + return newnode + + def visit_repr(self, node, parent): + """visit a Backquote node by returning a fresh instance of it""" + newnode = nodes.Repr(node.lineno, node.col_offset, parent) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_binop(self, node, parent): + """visit a BinOp node by returning a fresh instance of it""" + newnode = nodes.BinOp( + self._bin_op_classes[type(node.op)], node.lineno, node.col_offset, parent + ) + newnode.postinit( + self.visit(node.left, newnode), self.visit(node.right, newnode) + ) + return newnode + + def visit_boolop(self, node, parent): + """visit a BoolOp node by returning a fresh instance of it""" + newnode = nodes.BoolOp( + self._bool_op_classes[type(node.op)], node.lineno, node.col_offset, parent + ) + newnode.postinit([self.visit(child, newnode) for child in node.values]) + return newnode + + def visit_break(self, node, parent): + """visit a Break node by returning a fresh instance of it""" + return nodes.Break( + getattr(node, "lineno", None), getattr(node, "col_offset", None), parent + ) + + def visit_call(self, node, parent): + """visit a CallFunc node by returning a fresh instance of it""" + newnode = nodes.Call(node.lineno, node.col_offset, parent) + starargs = _visit_or_none(node, "starargs", self, newnode) + kwargs = _visit_or_none(node, "kwargs", self, newnode) + args = [self.visit(child, newnode) for child in node.args] + + if node.keywords: + keywords = [self.visit(child, newnode) for child in node.keywords] + else: + keywords = None + if starargs: + new_starargs = nodes.Starred( + col_offset=starargs.col_offset, + lineno=starargs.lineno, + parent=starargs.parent, + ) + new_starargs.postinit(value=starargs) + args.append(new_starargs) + if kwargs: + new_kwargs = nodes.Keyword( + arg=None, + col_offset=kwargs.col_offset, + lineno=kwargs.lineno, + parent=kwargs.parent, + ) + new_kwargs.postinit(value=kwargs) + if keywords: + keywords.append(new_kwargs) + else: + keywords = [new_kwargs] + + newnode.postinit(self.visit(node.func, newnode), args, keywords) + return newnode + + def visit_classdef(self, node, parent, newstyle=None): + """visit a ClassDef node to become astroid""" + node, doc = self._get_doc(node) + newnode = nodes.ClassDef(node.name, doc, node.lineno, node.col_offset, parent) + metaclass = None + for keyword in node.keywords: + if keyword.arg == "metaclass": + metaclass = self.visit(keyword, newnode).value + break + if node.decorator_list: + decorators = self.visit_decorators(node, newnode) + else: + decorators = None + newnode.postinit( + [self.visit(child, newnode) for child in node.bases], + [self.visit(child, newnode) for child in node.body], + decorators, + newstyle, + metaclass, + [ + self.visit(kwd, newnode) + for kwd in node.keywords + if kwd.arg != "metaclass" + ], + ) + return newnode + + def visit_const(self, node, parent): + """visit a Const node by returning a fresh instance of it""" + return nodes.Const( + node.value, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + def visit_continue(self, node, parent): + """visit a Continue node by returning a fresh instance of it""" + return nodes.Continue( + getattr(node, "lineno", None), getattr(node, "col_offset", None), parent + ) + + def visit_compare(self, node, parent): + """visit a Compare node by returning a fresh instance of it""" + newnode = nodes.Compare(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.left, newnode), + [ + (self._cmp_op_classes[op.__class__], self.visit(expr, newnode)) + for (op, expr) in zip(node.ops, node.comparators) + ], + ) + return newnode + + def visit_comprehension(self, node, parent): + """visit a Comprehension node by returning a fresh instance of it""" + newnode = nodes.Comprehension(parent) + newnode.postinit( + self.visit(node.target, newnode), + self.visit(node.iter, newnode), + [self.visit(child, newnode) for child in node.ifs], + getattr(node, "is_async", None), + ) + return newnode + + def visit_decorators(self, node, parent): + """visit a Decorators node by returning a fresh instance of it""" + # /!\ node is actually a _ast.FunctionDef node while + # parent is an astroid.nodes.FunctionDef node + if PY38: + # Set the line number of the first decorator for Python 3.8+. + lineno = node.decorator_list[0].lineno + else: + lineno = node.lineno + newnode = nodes.Decorators(lineno, node.col_offset, parent) + newnode.postinit([self.visit(child, newnode) for child in node.decorator_list]) + return newnode + + def visit_delete(self, node, parent): + """visit a Delete node by returning a fresh instance of it""" + newnode = nodes.Delete(node.lineno, node.col_offset, parent) + newnode.postinit([self.visit(child, newnode) for child in node.targets]) + return newnode + + def _visit_dict_items(self, node, parent, newnode): + for key, value in zip(node.keys, node.values): + rebuilt_value = self.visit(value, newnode) + if not key: + # Python 3.5 and extended unpacking + rebuilt_key = nodes.DictUnpack( + rebuilt_value.lineno, rebuilt_value.col_offset, parent + ) + else: + rebuilt_key = self.visit(key, newnode) + yield rebuilt_key, rebuilt_value + + def visit_dict(self, node, parent): + """visit a Dict node by returning a fresh instance of it""" + newnode = nodes.Dict(node.lineno, node.col_offset, parent) + items = list(self._visit_dict_items(node, parent, newnode)) + newnode.postinit(items) + return newnode + + def visit_dictcomp(self, node, parent): + """visit a DictComp node by returning a fresh instance of it""" + newnode = nodes.DictComp(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.key, newnode), + self.visit(node.value, newnode), + [self.visit(child, newnode) for child in node.generators], + ) + return newnode + + def visit_expr(self, node, parent): + """visit a Expr node by returning a fresh instance of it""" + newnode = nodes.Expr(node.lineno, node.col_offset, parent) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + # Not used in Python 3.8+. + def visit_ellipsis(self, node, parent): + """visit an Ellipsis node by returning a fresh instance of it""" + return nodes.Ellipsis( + getattr(node, "lineno", None), getattr(node, "col_offset", None), parent + ) + + def visit_emptynode(self, node, parent): + """visit an EmptyNode node by returning a fresh instance of it""" + return nodes.EmptyNode( + getattr(node, "lineno", None), getattr(node, "col_offset", None), parent + ) + + def visit_excepthandler(self, node, parent): + """visit an ExceptHandler node by returning a fresh instance of it""" + newnode = nodes.ExceptHandler(node.lineno, node.col_offset, parent) + # /!\ node.name can be a tuple + newnode.postinit( + _visit_or_none(node, "type", self, newnode), + _visit_or_none(node, "name", self, newnode), + [self.visit(child, newnode) for child in node.body], + ) + return newnode + + def visit_exec(self, node, parent): + """visit an Exec node by returning a fresh instance of it""" + newnode = nodes.Exec(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.body, newnode), + _visit_or_none(node, "globals", self, newnode), + _visit_or_none(node, "locals", self, newnode), + ) + return newnode + + # Not used in Python 3.8+. + def visit_extslice(self, node, parent): + """visit an ExtSlice node by returning a fresh instance of it""" + newnode = nodes.ExtSlice(parent=parent) + newnode.postinit([self.visit(dim, newnode) for dim in node.dims]) + return newnode + + def _visit_for(self, cls, node, parent): + """visit a For node by returning a fresh instance of it""" + newnode = cls(node.lineno, node.col_offset, parent) + type_annotation = self.check_type_comment(node, parent=newnode) + newnode.postinit( + target=self.visit(node.target, newnode), + iter=self.visit(node.iter, newnode), + body=[self.visit(child, newnode) for child in node.body], + orelse=[self.visit(child, newnode) for child in node.orelse], + type_annotation=type_annotation, + ) + return newnode + + def visit_for(self, node, parent): + return self._visit_for(nodes.For, node, parent) + + def visit_importfrom(self, node, parent): + """visit an ImportFrom node by returning a fresh instance of it""" + names = [(alias.name, alias.asname) for alias in node.names] + newnode = nodes.ImportFrom( + node.module or "", + names, + node.level or None, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + # store From names to add them to locals after building + self._import_from_nodes.append(newnode) + return newnode + + def _visit_functiondef(self, cls, node, parent): + """visit an FunctionDef node to become astroid""" + self._global_names.append({}) + node, doc = self._get_doc(node) + + lineno = node.lineno + if PY38 and node.decorator_list: + # Python 3.8 sets the line number of a decorated function + # to be the actual line number of the function, but the + # previous versions expected the decorator's line number instead. + # We reset the function's line number to that of the + # first decorator to maintain backward compatibility. + # It's not ideal but this discrepancy was baked into + # the framework for *years*. + lineno = node.decorator_list[0].lineno + + newnode = cls(node.name, doc, lineno, node.col_offset, parent) + if node.decorator_list: + decorators = self.visit_decorators(node, newnode) + else: + decorators = None + if node.returns: + returns = self.visit(node.returns, newnode) + else: + returns = None + + type_comment_args = type_comment_returns = None + type_comment_annotation = self.check_function_type_comment(node) + if type_comment_annotation: + type_comment_returns, type_comment_args = type_comment_annotation + newnode.postinit( + args=self.visit(node.args, newnode), + body=[self.visit(child, newnode) for child in node.body], + decorators=decorators, + returns=returns, + type_comment_returns=type_comment_returns, + type_comment_args=type_comment_args, + ) + self._global_names.pop() + return newnode + + def visit_functiondef(self, node, parent): + return self._visit_functiondef(nodes.FunctionDef, node, parent) + + def visit_generatorexp(self, node, parent): + """visit a GeneratorExp node by returning a fresh instance of it""" + newnode = nodes.GeneratorExp(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.elt, newnode), + [self.visit(child, newnode) for child in node.generators], + ) + return newnode + + def visit_attribute(self, node, parent): + """visit an Attribute node by returning a fresh instance of it""" + context = self._get_context(node) + if context == astroid.Del: + # FIXME : maybe we should reintroduce and visit_delattr ? + # for instance, deactivating assign_ctx + newnode = nodes.DelAttr(node.attr, node.lineno, node.col_offset, parent) + elif context == astroid.Store: + newnode = nodes.AssignAttr(node.attr, node.lineno, node.col_offset, parent) + # Prohibit a local save if we are in an ExceptHandler. + if not isinstance(parent, astroid.ExceptHandler): + self._delayed_assattr.append(newnode) + else: + newnode = nodes.Attribute(node.attr, node.lineno, node.col_offset, parent) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_global(self, node, parent): + """visit a Global node to become astroid""" + newnode = nodes.Global( + node.names, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + if self._global_names: # global at the module level, no effect + for name in node.names: + self._global_names[-1].setdefault(name, []).append(newnode) + return newnode + + def visit_if(self, node, parent): + """visit an If node by returning a fresh instance of it""" + newnode = nodes.If(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.test, newnode), + [self.visit(child, newnode) for child in node.body], + [self.visit(child, newnode) for child in node.orelse], + ) + return newnode + + def visit_ifexp(self, node, parent): + """visit a IfExp node by returning a fresh instance of it""" + newnode = nodes.IfExp(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.test, newnode), + self.visit(node.body, newnode), + self.visit(node.orelse, newnode), + ) + return newnode + + def visit_import(self, node, parent): + """visit a Import node by returning a fresh instance of it""" + names = [(alias.name, alias.asname) for alias in node.names] + newnode = nodes.Import( + names, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + # save import names in parent's locals: + for (name, asname) in newnode.names: + name = asname or name + parent.set_local(name.split(".")[0], newnode) + return newnode + + # Not used in Python 3.8+. + def visit_index(self, node, parent): + """visit a Index node by returning a fresh instance of it""" + newnode = nodes.Index(parent=parent) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_keyword(self, node, parent): + """visit a Keyword node by returning a fresh instance of it""" + newnode = nodes.Keyword(node.arg, parent=parent) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_lambda(self, node, parent): + """visit a Lambda node by returning a fresh instance of it""" + newnode = nodes.Lambda(node.lineno, node.col_offset, parent) + newnode.postinit(self.visit(node.args, newnode), self.visit(node.body, newnode)) + return newnode + + def visit_list(self, node, parent): + """visit a List node by returning a fresh instance of it""" + context = self._get_context(node) + newnode = nodes.List( + ctx=context, lineno=node.lineno, col_offset=node.col_offset, parent=parent + ) + newnode.postinit([self.visit(child, newnode) for child in node.elts]) + return newnode + + def visit_listcomp(self, node, parent): + """visit a ListComp node by returning a fresh instance of it""" + newnode = nodes.ListComp(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.elt, newnode), + [self.visit(child, newnode) for child in node.generators], + ) + return newnode + + def visit_name(self, node, parent): + """visit a Name node by returning a fresh instance of it""" + context = self._get_context(node) + # True and False can be assigned to something in py2x, so we have to + # check first the context. + if context == astroid.Del: + newnode = nodes.DelName(node.id, node.lineno, node.col_offset, parent) + elif context == astroid.Store: + newnode = nodes.AssignName(node.id, node.lineno, node.col_offset, parent) + elif node.id in CONST_NAME_TRANSFORMS: + newnode = nodes.Const( + CONST_NAME_TRANSFORMS[node.id], + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + return newnode + else: + newnode = nodes.Name(node.id, node.lineno, node.col_offset, parent) + # XXX REMOVE me : + if context in (astroid.Del, astroid.Store): # 'Aug' ?? + self._save_assignment(newnode) + return newnode + + def visit_constant(self, node, parent): + """visit a Constant node by returning a fresh instance of Const""" + return nodes.Const( + node.value, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + # Not used in Python 3.8+. + def visit_str(self, node, parent): + """visit a String/Bytes node by returning a fresh instance of Const""" + return nodes.Const( + node.s, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + visit_bytes = visit_str + + # Not used in Python 3.8+. + def visit_num(self, node, parent): + """visit a Num node by returning a fresh instance of Const""" + return nodes.Const( + node.n, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + def visit_pass(self, node, parent): + """visit a Pass node by returning a fresh instance of it""" + return nodes.Pass(node.lineno, node.col_offset, parent) + + def visit_print(self, node, parent): + """visit a Print node by returning a fresh instance of it""" + newnode = nodes.Print(node.nl, node.lineno, node.col_offset, parent) + newnode.postinit( + _visit_or_none(node, "dest", self, newnode), + [self.visit(child, newnode) for child in node.values], + ) + return newnode + + def visit_raise(self, node, parent): + """visit a Raise node by returning a fresh instance of it""" + newnode = nodes.Raise(node.lineno, node.col_offset, parent) + # pylint: disable=too-many-function-args + newnode.postinit( + _visit_or_none(node, "type", self, newnode), + _visit_or_none(node, "inst", self, newnode), + _visit_or_none(node, "tback", self, newnode), + ) + return newnode + + def visit_return(self, node, parent): + """visit a Return node by returning a fresh instance of it""" + newnode = nodes.Return(node.lineno, node.col_offset, parent) + if node.value is not None: + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_set(self, node, parent): + """visit a Set node by returning a fresh instance of it""" + newnode = nodes.Set(node.lineno, node.col_offset, parent) + newnode.postinit([self.visit(child, newnode) for child in node.elts]) + return newnode + + def visit_setcomp(self, node, parent): + """visit a SetComp node by returning a fresh instance of it""" + newnode = nodes.SetComp(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.elt, newnode), + [self.visit(child, newnode) for child in node.generators], + ) + return newnode + + def visit_slice(self, node, parent): + """visit a Slice node by returning a fresh instance of it""" + newnode = nodes.Slice(parent=parent) + newnode.postinit( + _visit_or_none(node, "lower", self, newnode), + _visit_or_none(node, "upper", self, newnode), + _visit_or_none(node, "step", self, newnode), + ) + return newnode + + def visit_subscript(self, node, parent): + """visit a Subscript node by returning a fresh instance of it""" + context = self._get_context(node) + newnode = nodes.Subscript( + ctx=context, lineno=node.lineno, col_offset=node.col_offset, parent=parent + ) + newnode.postinit( + self.visit(node.value, newnode), self.visit(node.slice, newnode) + ) + return newnode + + def visit_tryexcept(self, node, parent): + """visit a TryExcept node by returning a fresh instance of it""" + newnode = nodes.TryExcept(node.lineno, node.col_offset, parent) + newnode.postinit( + [self.visit(child, newnode) for child in node.body], + [self.visit(child, newnode) for child in node.handlers], + [self.visit(child, newnode) for child in node.orelse], + ) + return newnode + + def visit_tryfinally(self, node, parent): + """visit a TryFinally node by returning a fresh instance of it""" + newnode = nodes.TryFinally(node.lineno, node.col_offset, parent) + newnode.postinit( + [self.visit(child, newnode) for child in node.body], + [self.visit(n, newnode) for n in node.finalbody], + ) + return newnode + + def visit_tuple(self, node, parent): + """visit a Tuple node by returning a fresh instance of it""" + context = self._get_context(node) + newnode = nodes.Tuple( + ctx=context, lineno=node.lineno, col_offset=node.col_offset, parent=parent + ) + newnode.postinit([self.visit(child, newnode) for child in node.elts]) + return newnode + + def visit_unaryop(self, node, parent): + """visit a UnaryOp node by returning a fresh instance of it""" + newnode = nodes.UnaryOp( + self._unary_op_classes[node.op.__class__], + node.lineno, + node.col_offset, + parent, + ) + newnode.postinit(self.visit(node.operand, newnode)) + return newnode + + def visit_while(self, node, parent): + """visit a While node by returning a fresh instance of it""" + newnode = nodes.While(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.test, newnode), + [self.visit(child, newnode) for child in node.body], + [self.visit(child, newnode) for child in node.orelse], + ) + return newnode + + def visit_with(self, node, parent): + newnode = nodes.With(node.lineno, node.col_offset, parent) + expr = self.visit(node.context_expr, newnode) + if node.optional_vars is not None: + optional_vars = self.visit(node.optional_vars, newnode) + else: + optional_vars = None + + type_annotation = self.check_type_comment(node, parent=newnode) + newnode.postinit( + items=[(expr, optional_vars)], + body=[self.visit(child, newnode) for child in node.body], + type_annotation=type_annotation, + ) + return newnode + + def visit_yield(self, node, parent): + """visit a Yield node by returning a fresh instance of it""" + newnode = nodes.Yield(node.lineno, node.col_offset, parent) + if node.value is not None: + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + +class TreeRebuilder3(TreeRebuilder): + """extend and overwrite TreeRebuilder for python3k""" + + def visit_arg(self, node, parent): + """visit an arg node by returning a fresh AssName instance""" + return self.visit_assignname(node, parent, node.arg) + + # Not used in Python 3.8+. + def visit_nameconstant(self, node, parent): + # in Python 3.4 we have NameConstant for True / False / None + return nodes.Const( + node.value, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + def visit_excepthandler(self, node, parent): + """visit an ExceptHandler node by returning a fresh instance of it""" + newnode = nodes.ExceptHandler(node.lineno, node.col_offset, parent) + if node.name: + name = self.visit_assignname(node, newnode, node.name) + else: + name = None + newnode.postinit( + _visit_or_none(node, "type", self, newnode), + name, + [self.visit(child, newnode) for child in node.body], + ) + return newnode + + def visit_nonlocal(self, node, parent): + """visit a Nonlocal node and return a new instance of it""" + return nodes.Nonlocal( + node.names, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + def visit_raise(self, node, parent): + """visit a Raise node by returning a fresh instance of it""" + newnode = nodes.Raise(node.lineno, node.col_offset, parent) + # no traceback; anyway it is not used in Pylint + newnode.postinit( + _visit_or_none(node, "exc", self, newnode), + _visit_or_none(node, "cause", self, newnode), + ) + return newnode + + def visit_starred(self, node, parent): + """visit a Starred node and return a new instance of it""" + context = self._get_context(node) + newnode = nodes.Starred( + ctx=context, lineno=node.lineno, col_offset=node.col_offset, parent=parent + ) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_try(self, node, parent): + # python 3.3 introduce a new Try node replacing + # TryFinally/TryExcept nodes + if node.finalbody: + newnode = nodes.TryFinally(node.lineno, node.col_offset, parent) + if node.handlers: + body = [self.visit_tryexcept(node, newnode)] + else: + body = [self.visit(child, newnode) for child in node.body] + newnode.postinit(body, [self.visit(n, newnode) for n in node.finalbody]) + return newnode + if node.handlers: + return self.visit_tryexcept(node, parent) + return None + + def visit_annassign(self, node, parent): + """visit an AnnAssign node by returning a fresh instance of it""" + newnode = nodes.AnnAssign(node.lineno, node.col_offset, parent) + annotation = _visit_or_none(node, "annotation", self, newnode) + newnode.postinit( + target=self.visit(node.target, newnode), + annotation=annotation, + simple=node.simple, + value=_visit_or_none(node, "value", self, newnode), + ) + return newnode + + def _visit_with(self, cls, node, parent): + if "items" not in node._fields: + # python < 3.3 + return super(TreeRebuilder3, self).visit_with(node, parent) + + newnode = cls(node.lineno, node.col_offset, parent) + + def visit_child(child): + expr = self.visit(child.context_expr, newnode) + var = _visit_or_none(child, "optional_vars", self, newnode) + return expr, var + + type_annotation = self.check_type_comment(node, parent=newnode) + newnode.postinit( + items=[visit_child(child) for child in node.items], + body=[self.visit(child, newnode) for child in node.body], + type_annotation=type_annotation, + ) + return newnode + + def visit_with(self, node, parent): + return self._visit_with(nodes.With, node, parent) + + def visit_yieldfrom(self, node, parent): + newnode = nodes.YieldFrom(node.lineno, node.col_offset, parent) + if node.value is not None: + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_classdef(self, node, parent, newstyle=True): + return super(TreeRebuilder3, self).visit_classdef( + node, parent, newstyle=newstyle + ) + + # Async structs added in Python 3.5 + def visit_asyncfunctiondef(self, node, parent): + return self._visit_functiondef(nodes.AsyncFunctionDef, node, parent) + + def visit_asyncfor(self, node, parent): + return self._visit_for(nodes.AsyncFor, node, parent) + + def visit_await(self, node, parent): + newnode = nodes.Await(node.lineno, node.col_offset, parent) + newnode.postinit(value=self.visit(node.value, newnode)) + return newnode + + def visit_asyncwith(self, node, parent): + return self._visit_with(nodes.AsyncWith, node, parent) + + def visit_joinedstr(self, node, parent): + newnode = nodes.JoinedStr(node.lineno, node.col_offset, parent) + newnode.postinit([self.visit(child, newnode) for child in node.values]) + return newnode + + def visit_formattedvalue(self, node, parent): + newnode = nodes.FormattedValue(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.value, newnode), + node.conversion, + _visit_or_none(node, "format_spec", self, newnode), + ) + return newnode + + def visit_namedexpr(self, node, parent): + newnode = nodes.NamedExpr(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.target, newnode), self.visit(node.value, newnode) + ) + return newnode + + +TreeRebuilder = TreeRebuilder3 diff --git a/py3/lib/python3.6/site-packages/astroid/scoped_nodes.py b/py3/lib/python3.6/site-packages/astroid/scoped_nodes.py new file mode 100644 index 0000000..d02b653 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/scoped_nodes.py @@ -0,0 +1,2836 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2010 Daniel Harding +# Copyright (c) 2011, 2013-2015 Google, Inc. +# Copyright (c) 2013-2018 Claudiu Popa +# Copyright (c) 2013 Phil Schaf +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Florian Bruhin +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Rene Zhang +# Copyright (c) 2015 Philip Lorenz +# Copyright (c) 2016-2017 Derek Gustafson +# Copyright (c) 2017-2018 Bryce Guinta +# Copyright (c) 2017-2018 Ashley Whetter +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2017 David Euresti +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Anthony Sottile +# Copyright (c) 2018 HoverHell + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +""" +This module contains the classes for "scoped" node, i.e. which are opening a +new local scope in the language definition : Module, ClassDef, FunctionDef (and +Lambda, GeneratorExp, DictComp and SetComp to some extent). +""" + +import builtins +import sys +import io +import itertools +from typing import Optional, List + +from astroid import bases +from astroid import context as contextmod +from astroid import exceptions +from astroid import decorators as decorators_mod +from astroid.interpreter import objectmodel +from astroid.interpreter import dunder_lookup +from astroid import manager +from astroid import mixins +from astroid import node_classes +from astroid import util + + +BUILTINS = builtins.__name__ +ITER_METHODS = ("__iter__", "__getitem__") +EXCEPTION_BASE_CLASSES = frozenset({"Exception", "BaseException"}) +objects = util.lazy_import("objects") + + +def _c3_merge(sequences, cls, context): + """Merges MROs in *sequences* to a single MRO using the C3 algorithm. + + Adapted from http://www.python.org/download/releases/2.3/mro/. + + """ + result = [] + while True: + sequences = [s for s in sequences if s] # purge empty sequences + if not sequences: + return result + for s1 in sequences: # find merge candidates among seq heads + candidate = s1[0] + for s2 in sequences: + if candidate in s2[1:]: + candidate = None + break # reject the current head, it appears later + else: + break + if not candidate: + # Show all the remaining bases, which were considered as + # candidates for the next mro sequence. + raise exceptions.InconsistentMroError( + message="Cannot create a consistent method resolution order " + "for MROs {mros} of class {cls!r}.", + mros=sequences, + cls=cls, + context=context, + ) + + result.append(candidate) + # remove the chosen candidate + for seq in sequences: + if seq[0] == candidate: + del seq[0] + return None + + +def clean_duplicates_mro(sequences, cls, context): + for sequence in sequences: + names = [ + (node.lineno, node.qname()) if node.name else None for node in sequence + ] + last_index = dict(map(reversed, enumerate(names))) + if names and names[0] is not None and last_index[names[0]] != 0: + raise exceptions.DuplicateBasesError( + message="Duplicates found in MROs {mros} for {cls!r}.", + mros=sequences, + cls=cls, + context=context, + ) + yield [ + node + for i, (node, name) in enumerate(zip(sequence, names)) + if name is None or last_index[name] == i + ] + + +def function_to_method(n, klass): + if isinstance(n, FunctionDef): + if n.type == "classmethod": + return bases.BoundMethod(n, klass) + if n.type != "staticmethod": + return bases.UnboundMethod(n) + return n + + +MANAGER = manager.AstroidManager() + + +def builtin_lookup(name): + """lookup a name into the builtin module + return the list of matching statements and the astroid for the builtin + module + """ + builtin_astroid = MANAGER.ast_from_module(builtins) + if name == "__dict__": + return builtin_astroid, () + try: + stmts = builtin_astroid.locals[name] + except KeyError: + stmts = () + return builtin_astroid, stmts + + +# TODO move this Mixin to mixins.py; problem: 'FunctionDef' in _scope_lookup +class LocalsDictNodeNG(node_classes.LookupMixIn, node_classes.NodeNG): + """ this class provides locals handling common to Module, FunctionDef + and ClassDef nodes, including a dict like interface for direct access + to locals information + """ + + # attributes below are set by the builder module or by raw factories + + locals = {} + """A map of the name of a local variable to the node defining the local. + + :type: dict(str, NodeNG) + """ + + def qname(self): + """Get the 'qualified' name of the node. + + For example: module.name, module.class.name ... + + :returns: The qualified name. + :rtype: str + """ + # pylint: disable=no-member; github.com/pycqa/astroid/issues/278 + if self.parent is None: + return self.name + return "%s.%s" % (self.parent.frame().qname(), self.name) + + def frame(self): + """The first parent frame node. + + A frame node is a :class:`Module`, :class:`FunctionDef`, + or :class:`ClassDef`. + + :returns: The first parent frame node. + :rtype: Module or FunctionDef or ClassDef + """ + return self + + def scope(self): + """The first parent node defining a new scope. + + :returns: The first parent scope node. + :rtype: Module or FunctionDef or ClassDef or Lambda or GenExpr + """ + return self + + def _scope_lookup(self, node, name, offset=0): + """XXX method for interfacing the scope lookup""" + try: + stmts = node._filter_stmts(self.locals[name], self, offset) + except KeyError: + stmts = () + if stmts: + return self, stmts + if self.parent: # i.e. not Module + # nested scope: if parent scope is a function, that's fine + # else jump to the module + pscope = self.parent.scope() + if not pscope.is_function: + pscope = pscope.root() + return pscope.scope_lookup(node, name) + return builtin_lookup(name) # Module + + def set_local(self, name, stmt): + """Define that the given name is declared in the given statement node. + + .. seealso:: :meth:`scope` + + :param name: The name that is being defined. + :type name: str + + :param stmt: The statement that defines the given name. + :type stmt: NodeNG + """ + # assert not stmt in self.locals.get(name, ()), (self, stmt) + self.locals.setdefault(name, []).append(stmt) + + __setitem__ = set_local + + def _append_node(self, child): + """append a child, linking it in the tree""" + # pylint: disable=no-member; depending by the class + # which uses the current class as a mixin or base class. + # It's rewritten in 2.0, so it makes no sense for now + # to spend development time on it. + self.body.append(child) + child.parent = self + + def add_local_node(self, child_node, name=None): + """Append a child that should alter the locals of this scope node. + + :param child_node: The child node that will alter locals. + :type child_node: NodeNG + + :param name: The name of the local that will be altered by + the given child node. + :type name: str or None + """ + if name != "__class__": + # add __class__ node as a child will cause infinite recursion later! + self._append_node(child_node) + self.set_local(name or child_node.name, child_node) + + def __getitem__(self, item): + """The first node the defines the given local. + + :param item: The name of the locally defined object. + :type item: str + + :raises KeyError: If the name is not defined. + """ + return self.locals[item][0] + + def __iter__(self): + """Iterate over the names of locals defined in this scoped node. + + :returns: The names of the defined locals. + :rtype: iterable(str) + """ + return iter(self.keys()) + + def keys(self): + """The names of locals defined in this scoped node. + + :returns: The names of the defined locals. + :rtype: list(str) + """ + return list(self.locals.keys()) + + def values(self): + """The nodes that define the locals in this scoped node. + + :returns: The nodes that define locals. + :rtype: list(NodeNG) + """ + return [self[key] for key in self.keys()] + + def items(self): + """Get the names of the locals and the node that defines the local. + + :returns: The names of locals and their associated node. + :rtype: list(tuple(str, NodeNG)) + """ + return list(zip(self.keys(), self.values())) + + def __contains__(self, name): + """Check if a local is defined in this scope. + + :param name: The name of the local to check for. + :type name: str + + :returns: True if this node has a local of the given name, + False otherwise. + :rtype: bool + """ + return name in self.locals + + +class Module(LocalsDictNodeNG): + """Class representing an :class:`ast.Module` node. + + >>> node = astroid.extract_node('import astroid') + >>> node + + >>> node.parent + + """ + + _astroid_fields = ("body",) + + fromlineno = 0 + """The first line that this node appears on in the source code. + + :type: int or None + """ + lineno = 0 + """The line that this node appears on in the source code. + + :type: int or None + """ + + # attributes below are set by the builder module or by raw factories + + file = None + """The path to the file that this ast has been extracted from. + + This will be ``None`` when the representation has been built from a + built-in module. + + :type: str or None + """ + file_bytes = None + """The string/bytes that this ast was built from. + + :type: str or bytes or None + """ + file_encoding = None + """The encoding of the source file. + + This is used to get unicode out of a source file. + Python 2 only. + + :type: str or None + """ + name = None + """The name of the module. + + :type: str or None + """ + pure_python = None + """Whether the ast was built from source. + + :type: bool or None + """ + package = None + """Whether the node represents a package or a module. + + :type: bool or None + """ + globals = None + """A map of the name of a global variable to the node defining the global. + + :type: dict(str, NodeNG) + """ + + # Future imports + future_imports = None + """The imports from ``__future__``. + + :type: set(str) or None + """ + special_attributes = objectmodel.ModuleModel() + """The names of special attributes that this module has. + + :type: objectmodel.ModuleModel + """ + + # names of module attributes available through the global scope + scope_attrs = {"__name__", "__doc__", "__file__", "__path__", "__package__"} + """The names of module attributes available through the global scope. + + :type: str(str) + """ + + _other_fields = ( + "name", + "doc", + "file", + "path", + "package", + "pure_python", + "future_imports", + ) + _other_other_fields = ("locals", "globals") + + def __init__( + self, + name, + doc, + file=None, + path: Optional[List[str]] = None, + package=None, + parent=None, + pure_python=True, + ): + """ + :param name: The name of the module. + :type name: str + + :param doc: The module docstring. + :type doc: str + + :param file: The path to the file that this ast has been extracted from. + :type file: str or None + + :param path: + :type path: Optional[List[str]] + + :param package: Whether the node represents a package or a module. + :type package: bool or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + + :param pure_python: Whether the ast was built from source. + :type pure_python: bool or None + """ + self.name = name + self.doc = doc + self.file = file + self.path = path + self.package = package + self.parent = parent + self.pure_python = pure_python + self.locals = self.globals = {} + """A map of the name of a local variable to the node defining the local. + + :type: dict(str, NodeNG) + """ + self.body = [] + """The contents of the module. + + :type: list(NodeNG) or None + """ + self.future_imports = set() + + # pylint: enable=redefined-builtin + + def postinit(self, body=None): + """Do some setup after initialisation. + + :param body: The contents of the module. + :type body: list(NodeNG) or None + """ + self.body = body + + def _get_stream(self): + if self.file_bytes is not None: + return io.BytesIO(self.file_bytes) + if self.file is not None: + stream = open(self.file, "rb") + return stream + return None + + def stream(self): + """Get a stream to the underlying file or bytes. + + :type: file or io.BytesIO or None + """ + return self._get_stream() + + def block_range(self, lineno): + """Get a range from where this node starts to where this node ends. + + :param lineno: Unused. + :type lineno: int + + :returns: The range of line numbers that this node belongs to. + :rtype: tuple(int, int) + """ + return self.fromlineno, self.tolineno + + def scope_lookup(self, node, name, offset=0): + """Lookup where the given variable is assigned. + + :param node: The node to look for assignments up to. + Any assignments after the given node are ignored. + :type node: NodeNG + + :param name: The name of the variable to find assignments for. + :type name: str + + :param offset: The line offset to filter statements up to. + :type offset: int + + :returns: This scope node and the list of assignments associated to the + given name according to the scope where it has been found (locals, + globals or builtin). + :rtype: tuple(str, list(NodeNG)) + """ + if name in self.scope_attrs and name not in self.locals: + try: + return self, self.getattr(name) + except exceptions.AttributeInferenceError: + return self, () + return self._scope_lookup(node, name, offset) + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.module" % BUILTINS + + def display_type(self): + """A human readable type of this node. + + :returns: The type of this node. + :rtype: str + """ + return "Module" + + def getattr(self, name, context=None, ignore_locals=False): + result = [] + name_in_locals = name in self.locals + + if name in self.special_attributes and not ignore_locals and not name_in_locals: + result = [self.special_attributes.lookup(name)] + elif not ignore_locals and name_in_locals: + result = self.locals[name] + elif self.package: + try: + result = [self.import_module(name, relative_only=True)] + except (exceptions.AstroidBuildingError, SyntaxError) as exc: + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) from exc + result = [n for n in result if not isinstance(n, node_classes.DelName)] + if result: + return result + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + + def igetattr(self, name, context=None): + """Infer the possible values of the given variable. + + :param name: The name of the variable to infer. + :type name: str + + :returns: The inferred possible values. + :rtype: iterable(NodeNG) or None + """ + # set lookup name since this is necessary to infer on import nodes for + # instance + context = contextmod.copy_context(context) + context.lookupname = name + try: + return bases._infer_stmts(self.getattr(name, context), context, frame=self) + except exceptions.AttributeInferenceError as error: + raise exceptions.InferenceError( + error.message, target=self, attribute=name, context=context + ) from error + + def fully_defined(self): + """Check if this module has been build from a .py file. + + If so, the module contains a complete representation, + including the code. + + :returns: True if the module has been built from a .py file. + :rtype: bool + """ + return self.file is not None and self.file.endswith(".py") + + def statement(self): + """The first parent node, including self, marked as statement node. + + :returns: The first parent statement. + :rtype: NodeNG + """ + return self + + def previous_sibling(self): + """The previous sibling statement. + + :returns: The previous sibling statement node. + :rtype: NodeNG or None + """ + + def next_sibling(self): + """The next sibling statement node. + + :returns: The next sibling statement node. + :rtype: NodeNG or None + """ + + _absolute_import_activated = True + + def absolute_import_activated(self): + """Whether :pep:`328` absolute import behaviour has been enabled. + + :returns: True if :pep:`328` has been enabled, False otherwise. + :rtype: bool + """ + return self._absolute_import_activated + + def import_module(self, modname, relative_only=False, level=None): + """Get the ast for a given module as if imported from this module. + + :param modname: The name of the module to "import". + :type modname: str + + :param relative_only: Whether to only consider relative imports. + :type relative_only: bool + + :param level: The level of relative import. + :type level: int or None + + :returns: The imported module ast. + :rtype: NodeNG + """ + if relative_only and level is None: + level = 0 + absmodname = self.relative_to_absolute_name(modname, level) + + try: + return MANAGER.ast_from_module_name(absmodname) + except exceptions.AstroidBuildingError: + # we only want to import a sub module or package of this module, + # skip here + if relative_only: + raise + return MANAGER.ast_from_module_name(modname) + + def relative_to_absolute_name(self, modname, level): + """Get the absolute module name for a relative import. + + The relative import can be implicit or explicit. + + :param modname: The module name to convert. + :type modname: str + + :param level: The level of relative import. + :type level: int + + :returns: The absolute module name. + :rtype: str + + :raises TooManyLevelsError: When the relative import refers to a + module too far above this one. + """ + # XXX this returns non sens when called on an absolute import + # like 'pylint.checkers.astroid.utils' + # XXX doesn't return absolute name if self.name isn't absolute name + if self.absolute_import_activated() and level is None: + return modname + if level: + if self.package: + level = level - 1 + if level and self.name.count(".") < level: + raise exceptions.TooManyLevelsError(level=level, name=self.name) + + package_name = self.name.rsplit(".", level)[0] + elif self.package: + package_name = self.name + else: + package_name = self.name.rsplit(".", 1)[0] + + if package_name: + if not modname: + return package_name + return "%s.%s" % (package_name, modname) + return modname + + def wildcard_import_names(self): + """The list of imported names when this module is 'wildcard imported'. + + It doesn't include the '__builtins__' name which is added by the + current CPython implementation of wildcard imports. + + :returns: The list of imported names. + :rtype: list(str) + """ + # We separate the different steps of lookup in try/excepts + # to avoid catching too many Exceptions + default = [name for name in self.keys() if not name.startswith("_")] + try: + all_values = self["__all__"] + except KeyError: + return default + + try: + explicit = next(all_values.assigned_stmts()) + except exceptions.InferenceError: + return default + except AttributeError: + # not an assignment node + # XXX infer? + return default + + # Try our best to detect the exported name. + inferred = [] + try: + explicit = next(explicit.infer()) + except exceptions.InferenceError: + return default + if not isinstance(explicit, (node_classes.Tuple, node_classes.List)): + return default + + str_const = lambda node: ( + isinstance(node, node_classes.Const) and isinstance(node.value, str) + ) + for node in explicit.elts: + if str_const(node): + inferred.append(node.value) + else: + try: + inferred_node = next(node.infer()) + except exceptions.InferenceError: + continue + if str_const(inferred_node): + inferred.append(inferred_node.value) + return inferred + + def public_names(self): + """The list of the names that are publicly available in this module. + + :returns: The list of publc names. + :rtype: list(str) + """ + return [name for name in self.keys() if not name.startswith("_")] + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`Module` this is always ``True``. + :rtype: bool + """ + return True + + def get_children(self): + yield from self.body + + +class ComprehensionScope(LocalsDictNodeNG): + """Scoping for different types of comprehensions.""" + + def frame(self): + """The first parent frame node. + + A frame node is a :class:`Module`, :class:`FunctionDef`, + or :class:`ClassDef`. + + :returns: The first parent frame node. + :rtype: Module or FunctionDef or ClassDef + """ + return self.parent.frame() + + scope_lookup = LocalsDictNodeNG._scope_lookup + + +class GeneratorExp(ComprehensionScope): + """Class representing an :class:`ast.GeneratorExp` node. + + >>> node = astroid.extract_node('(thing for thing in things if thing)') + >>> node + + """ + + _astroid_fields = ("elt", "generators") + _other_other_fields = ("locals",) + elt = None + """The element that forms the output of the expression. + + :type: NodeNG or None + """ + generators = None + """The generators that are looped through. + + :type: list(Comprehension) or None + """ + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.locals = {} + """A map of the name of a local variable to the node defining the local. + + :type: dict(str, NodeNG) + """ + + super(GeneratorExp, self).__init__(lineno, col_offset, parent) + + def postinit(self, elt=None, generators=None): + """Do some setup after initialisation. + + :param elt: The element that forms the output of the expression. + :type elt: NodeNG or None + + :param generators: The generators that are looped through. + :type generators: list(Comprehension) or None + """ + self.elt = elt + if generators is None: + self.generators = [] + else: + self.generators = generators + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`GeneratorExp` this is always ``True``. + :rtype: bool + """ + return True + + def get_children(self): + yield self.elt + + yield from self.generators + + +class DictComp(ComprehensionScope): + """Class representing an :class:`ast.DictComp` node. + + >>> node = astroid.extract_node('{k:v for k, v in things if k > v}') + >>> node + + """ + + _astroid_fields = ("key", "value", "generators") + _other_other_fields = ("locals",) + key = None + """What produces the keys. + + :type: NodeNG or None + """ + value = None + """What produces the values. + + :type: NodeNG or None + """ + generators = None + """The generators that are looped through. + + :type: list(Comprehension) or None + """ + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.locals = {} + """A map of the name of a local variable to the node defining the local. + + :type: dict(str, NodeNG) + """ + + super(DictComp, self).__init__(lineno, col_offset, parent) + + def postinit(self, key=None, value=None, generators=None): + """Do some setup after initialisation. + + :param key: What produces the keys. + :type key: NodeNG or None + + :param value: What produces the values. + :type value: NodeNG or None + + :param generators: The generators that are looped through. + :type generators: list(Comprehension) or None + """ + self.key = key + self.value = value + if generators is None: + self.generators = [] + else: + self.generators = generators + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`DictComp` this is always :class:`Uninferable`. + :rtype: Uninferable + """ + return util.Uninferable + + def get_children(self): + yield self.key + yield self.value + + yield from self.generators + + +class SetComp(ComprehensionScope): + """Class representing an :class:`ast.SetComp` node. + + >>> node = astroid.extract_node('{thing for thing in things if thing}') + >>> node + + """ + + _astroid_fields = ("elt", "generators") + _other_other_fields = ("locals",) + elt = None + """The element that forms the output of the expression. + + :type: NodeNG or None + """ + generators = None + """The generators that are looped through. + + :type: list(Comprehension) or None + """ + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.locals = {} + """A map of the name of a local variable to the node defining the local. + + :type: dict(str, NodeNG) + """ + + super(SetComp, self).__init__(lineno, col_offset, parent) + + def postinit(self, elt=None, generators=None): + """Do some setup after initialisation. + + :param elt: The element that forms the output of the expression. + :type elt: NodeNG or None + + :param generators: The generators that are looped through. + :type generators: list(Comprehension) or None + """ + self.elt = elt + if generators is None: + self.generators = [] + else: + self.generators = generators + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`SetComp` this is always :class:`Uninferable`. + :rtype: Uninferable + """ + return util.Uninferable + + def get_children(self): + yield self.elt + + yield from self.generators + + +class _ListComp(node_classes.NodeNG): + """Class representing an :class:`ast.ListComp` node. + + >>> node = astroid.extract_node('[thing for thing in things if thing]') + >>> node + + """ + + _astroid_fields = ("elt", "generators") + elt = None + """The element that forms the output of the expression. + + :type: NodeNG or None + """ + generators = None + """The generators that are looped through. + + :type: list(Comprehension) or None + """ + + def postinit(self, elt=None, generators=None): + """Do some setup after initialisation. + + :param elt: The element that forms the output of the expression. + :type elt: NodeNG or None + + :param generators: The generators that are looped through. + :type generators: list(Comprehension) or None + """ + self.elt = elt + self.generators = generators + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`ListComp` this is always :class:`Uninferable`. + :rtype: Uninferable + """ + return util.Uninferable + + def get_children(self): + yield self.elt + + yield from self.generators + + +class ListComp(_ListComp, ComprehensionScope): + """Class representing an :class:`ast.ListComp` node. + + >>> node = astroid.extract_node('[thing for thing in things if thing]') + >>> node + + """ + + _other_other_fields = ("locals",) + + def __init__(self, lineno=None, col_offset=None, parent=None): + self.locals = {} + """A map of the name of a local variable to the node defining it. + + :type: dict(str, NodeNG) + """ + + super(ListComp, self).__init__(lineno, col_offset, parent) + + +def _infer_decorator_callchain(node): + """Detect decorator call chaining and see if the end result is a + static or a classmethod. + """ + if not isinstance(node, FunctionDef): + return None + if not node.parent: + return None + try: + result = next(node.infer_call_result(node.parent)) + except exceptions.InferenceError: + return None + if isinstance(result, bases.Instance): + result = result._proxied + if isinstance(result, ClassDef): + if result.is_subtype_of("%s.classmethod" % BUILTINS): + return "classmethod" + if result.is_subtype_of("%s.staticmethod" % BUILTINS): + return "staticmethod" + return None + + +class Lambda(mixins.FilterStmtsMixin, LocalsDictNodeNG): + """Class representing an :class:`ast.Lambda` node. + + >>> node = astroid.extract_node('lambda arg: arg + 1') + >>> node + l.1 at 0x7f23b2e41518> + """ + + _astroid_fields = ("args", "body") + _other_other_fields = ("locals",) + name = "" + is_lambda = True + + def implicit_parameters(self): + return 0 + + # function's type, 'function' | 'method' | 'staticmethod' | 'classmethod' + @property + def type(self): + """Whether this is a method or function. + + :returns: 'method' if this is a method, 'function' otherwise. + :rtype: str + """ + # pylint: disable=no-member + if self.args.args and self.args.args[0].name == "self": + if isinstance(self.parent.scope(), ClassDef): + return "method" + return "function" + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.locals = {} + """A map of the name of a local variable to the node defining it. + + :type: dict(str, NodeNG) + """ + + self.args = [] + """The arguments that the function takes. + + :type: Arguments or list + """ + + self.body = [] + """The contents of the function body. + + :type: list(NodeNG) + """ + + super(Lambda, self).__init__(lineno, col_offset, parent) + + def postinit(self, args, body): + """Do some setup after initialisation. + + :param args: The arguments that the function takes. + :type args: Arguments + + :param body: The contents of the function body. + :type body: list(NodeNG) + """ + self.args = args + self.body = body + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + if "method" in self.type: + return "%s.instancemethod" % BUILTINS + return "%s.function" % BUILTINS + + def display_type(self): + """A human readable type of this node. + + :returns: The type of this node. + :rtype: str + """ + if "method" in self.type: + return "Method" + return "Function" + + def callable(self): + """Whether this node defines something that is callable. + + :returns: True if this defines something that is callable, + False otherwise. + For a :class:`Lambda` this is always ``True``. + :rtype: bool + """ + return True + + def argnames(self): + """Get the names of each of the arguments. + + :returns: The names of the arguments. + :rtype: list(str) + """ + # pylint: disable=no-member; github.com/pycqa/astroid/issues/291 + # args is in fact redefined later on by postinit. Can't be changed + # to None due to a strong interaction between Lambda and FunctionDef. + + if self.args.args: # maybe None with builtin functions + names = _rec_get_names(self.args.args) + else: + names = [] + if self.args.vararg: + names.append(self.args.vararg) + if self.args.kwarg: + names.append(self.args.kwarg) + return names + + def infer_call_result(self, caller, context=None): + """Infer what the function returns when called. + + :param caller: Unused + :type caller: object + """ + # pylint: disable=no-member; github.com/pycqa/astroid/issues/291 + # args is in fact redefined later on by postinit. Can't be changed + # to None due to a strong interaction between Lambda and FunctionDef. + return self.body.infer(context) + + def scope_lookup(self, node, name, offset=0): + """Lookup where the given names is assigned. + + :param node: The node to look for assignments up to. + Any assignments after the given node are ignored. + :type node: NodeNG + + :param name: The name to find assignments for. + :type name: str + + :param offset: The line offset to filter statements up to. + :type offset: int + + :returns: This scope node and the list of assignments associated to the + given name according to the scope where it has been found (locals, + globals or builtin). + :rtype: tuple(str, list(NodeNG)) + """ + # pylint: disable=no-member; github.com/pycqa/astroid/issues/291 + # args is in fact redefined later on by postinit. Can't be changed + # to None due to a strong interaction between Lambda and FunctionDef. + + if node in self.args.defaults or node in self.args.kw_defaults: + frame = self.parent.frame() + # line offset to avoid that def func(f=func) resolve the default + # value to the defined function + offset = -1 + else: + # check this is not used in function decorators + frame = self + return frame._scope_lookup(node, name, offset) + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`Lambda` this is always ``True``. + :rtype: bool + """ + return True + + def get_children(self): + yield self.args + yield self.body + + +class FunctionDef(mixins.MultiLineBlockMixin, node_classes.Statement, Lambda): + """Class representing an :class:`ast.FunctionDef`. + + >>> node = astroid.extract_node(''' + ... def my_func(arg): + ... return arg + 1 + ... ''') + >>> node + + """ + + _astroid_fields = ("decorators", "args", "returns", "body") + _multi_line_block_fields = ("body",) + returns = None + decorators = None + """The decorators that are applied to this method or function. + + :type: Decorators or None + """ + special_attributes = objectmodel.FunctionModel() + """The names of special attributes that this function has. + + :type: objectmodel.FunctionModel + """ + is_function = True + """Whether this node indicates a function. + + For a :class:`FunctionDef` this is always ``True``. + + :type: bool + """ + type_annotation = None + """If present, this will contain the type annotation passed by a type comment + + :type: NodeNG or None + """ + type_comment_args = None + """ + If present, this will contain the type annotation for arguments + passed by a type comment + """ + type_comment_returns = None + """If present, this will contain the return type annotation, passed by a type comment""" + # attributes below are set by the builder module or by raw factories + _other_fields = ("name", "doc") + _other_other_fields = ( + "locals", + "_type", + "type_comment_returns", + "type_comment_args", + ) + _type = None + + def __init__(self, name=None, doc=None, lineno=None, col_offset=None, parent=None): + """ + :param name: The name of the function. + :type name: str or None + + :param doc: The function's docstring. + :type doc: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.name = name + """The name of the function. + + :type name: str or None + """ + + self.doc = doc + """The function's docstring. + + :type doc: str or None + """ + + self.instance_attrs = {} + super(FunctionDef, self).__init__(lineno, col_offset, parent) + if parent: + frame = parent.frame() + frame.set_local(name, self) + + # pylint: disable=arguments-differ; different than Lambdas + def postinit( + self, + args, + body, + decorators=None, + returns=None, + type_comment_returns=None, + type_comment_args=None, + ): + """Do some setup after initialisation. + + :param args: The arguments that the function takes. + :type args: Arguments or list + + :param body: The contents of the function body. + :type body: list(NodeNG) + + :param decorators: The decorators that are applied to this + method or function. + :type decorators: Decorators or None + :params type_comment_returns: + The return type annotation passed via a type comment. + :params type_comment_args: + The args type annotation passed via a type comment. + """ + self.args = args + self.body = body + self.decorators = decorators + self.returns = returns + self.type_comment_returns = type_comment_returns + self.type_comment_args = type_comment_args + + @decorators_mod.cachedproperty + def extra_decorators(self): + """The extra decorators that this function can have. + + Additional decorators are considered when they are used as + assignments, as in ``method = staticmethod(method)``. + The property will return all the callables that are used for + decoration. + + :type: list(NodeNG) + """ + frame = self.parent.frame() + if not isinstance(frame, ClassDef): + return [] + + decorators = [] + for assign in frame._get_assign_nodes(): + if isinstance(assign.value, node_classes.Call) and isinstance( + assign.value.func, node_classes.Name + ): + for assign_node in assign.targets: + if not isinstance(assign_node, node_classes.AssignName): + # Support only `name = callable(name)` + continue + + if assign_node.name != self.name: + # Interested only in the assignment nodes that + # decorates the current method. + continue + try: + meth = frame[self.name] + except KeyError: + continue + else: + # Must be a function and in the same frame as the + # original method. + if ( + isinstance(meth, FunctionDef) + and assign_node.frame() == frame + ): + decorators.append(assign.value) + return decorators + + @decorators_mod.cachedproperty + def type(self): # pylint: disable=invalid-overridden-method + """The function type for this node. + + Possible values are: method, function, staticmethod, classmethod. + + :type: str + """ + builtin_descriptors = {"classmethod", "staticmethod"} + + for decorator in self.extra_decorators: + if decorator.func.name in builtin_descriptors: + return decorator.func.name + + frame = self.parent.frame() + type_name = "function" + if isinstance(frame, ClassDef): + if self.name == "__new__": + return "classmethod" + if sys.version_info >= (3, 6) and self.name == "__init_subclass__": + return "classmethod" + + type_name = "method" + + if not self.decorators: + return type_name + + for node in self.decorators.nodes: + if isinstance(node, node_classes.Name): + if node.name in builtin_descriptors: + return node.name + + if isinstance(node, node_classes.Call): + # Handle the following case: + # @some_decorator(arg1, arg2) + # def func(...) + # + try: + current = next(node.func.infer()) + except exceptions.InferenceError: + continue + _type = _infer_decorator_callchain(current) + if _type is not None: + return _type + + try: + for inferred in node.infer(): + # Check to see if this returns a static or a class method. + _type = _infer_decorator_callchain(inferred) + if _type is not None: + return _type + + if not isinstance(inferred, ClassDef): + continue + for ancestor in inferred.ancestors(): + if not isinstance(ancestor, ClassDef): + continue + if ancestor.is_subtype_of("%s.classmethod" % BUILTINS): + return "classmethod" + if ancestor.is_subtype_of("%s.staticmethod" % BUILTINS): + return "staticmethod" + except exceptions.InferenceError: + pass + return type_name + + @decorators_mod.cachedproperty + def fromlineno(self): + """The first line that this node appears on in the source code. + + :type: int or None + """ + # lineno is the line number of the first decorator, we want the def + # statement lineno + lineno = self.lineno + if self.decorators is not None: + lineno += sum( + node.tolineno - node.lineno + 1 for node in self.decorators.nodes + ) + + return lineno + + @decorators_mod.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + return self.args.tolineno + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: Unused. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + :rtype: tuple(int, int) + """ + return self.fromlineno, self.tolineno + + def getattr(self, name, context=None): + """this method doesn't look in the instance_attrs dictionary since it's + done by an Instance proxy at inference time. + """ + if name in self.instance_attrs: + return self.instance_attrs[name] + if name in self.special_attributes: + return [self.special_attributes.lookup(name)] + raise exceptions.AttributeInferenceError(target=self, attribute=name) + + def igetattr(self, name, context=None): + """Inferred getattr, which returns an iterator of inferred statements.""" + try: + return bases._infer_stmts(self.getattr(name, context), context, frame=self) + except exceptions.AttributeInferenceError as error: + raise exceptions.InferenceError( + error.message, target=self, attribute=name, context=context + ) from error + + def is_method(self): + """Check if this function node represents a method. + + :returns: True if this is a method, False otherwise. + :rtype: bool + """ + # check we are defined in a ClassDef, because this is usually expected + # (e.g. pylint...) when is_method() return True + return self.type != "function" and isinstance(self.parent.frame(), ClassDef) + + @decorators_mod.cached + def decoratornames(self): + """Get the qualified names of each of the decorators on this function. + + :returns: The names of the decorators. + :rtype: set(str) + """ + result = set() + decoratornodes = [] + if self.decorators is not None: + decoratornodes += self.decorators.nodes + decoratornodes += self.extra_decorators + for decnode in decoratornodes: + try: + for infnode in decnode.infer(): + result.add(infnode.qname()) + except exceptions.InferenceError: + continue + return result + + def is_bound(self): + """Check if the function is bound to an instance or class. + + :returns: True if the function is bound to an instance or class, + False otherwise. + :rtype: bool + """ + return self.type == "classmethod" + + def is_abstract(self, pass_is_abstract=True): + """Check if the method is abstract. + + A method is considered abstract if any of the following is true: + * The only statement is 'raise NotImplementedError' + * The only statement is 'pass' and pass_is_abstract is True + * The method is annotated with abc.astractproperty/abc.abstractmethod + + :returns: True if the method is abstract, False otherwise. + :rtype: bool + """ + if self.decorators: + for node in self.decorators.nodes: + try: + inferred = next(node.infer()) + except exceptions.InferenceError: + continue + if inferred and inferred.qname() in ( + "abc.abstractproperty", + "abc.abstractmethod", + ): + return True + + for child_node in self.body: + if isinstance(child_node, node_classes.Raise): + if child_node.raises_not_implemented(): + return True + return pass_is_abstract and isinstance(child_node, node_classes.Pass) + # empty function is the same as function with a single "pass" statement + if pass_is_abstract: + return True + + def is_generator(self): + """Check if this is a generator function. + + :returns: True is this is a generator function, False otherwise. + :rtype: bool + """ + return next(self._get_yield_nodes_skip_lambdas(), False) + + def infer_call_result(self, caller=None, context=None): + """Infer what the function returns when called. + + :returns: What the function returns. + :rtype: iterable(NodeNG or Uninferable) or None + """ + if self.is_generator(): + if isinstance(self, AsyncFunctionDef): + generator_cls = bases.AsyncGenerator + else: + generator_cls = bases.Generator + result = generator_cls(self) + yield result + return + # This is really a gigantic hack to work around metaclass generators + # that return transient class-generating functions. Pylint's AST structure + # cannot handle a base class object that is only used for calling __new__, + # but does not contribute to the inheritance structure itself. We inject + # a fake class into the hierarchy here for several well-known metaclass + # generators, and filter it out later. + if ( + self.name == "with_metaclass" + and len(self.args.args) == 1 + and self.args.vararg is not None + ): + metaclass = next(caller.args[0].infer(context)) + if isinstance(metaclass, ClassDef): + class_bases = [next(arg.infer(context)) for arg in caller.args[1:]] + new_class = ClassDef(name="temporary_class") + new_class.hide = True + new_class.parent = self + new_class.postinit( + bases=[base for base in class_bases if base != util.Uninferable], + body=[], + decorators=[], + metaclass=metaclass, + ) + yield new_class + return + returns = self._get_return_nodes_skip_functions() + + first_return = next(returns, None) + if not first_return: + if self.body and isinstance(self.body[-1], node_classes.Assert): + yield node_classes.Const(None) + return + + raise exceptions.InferenceError( + "The function does not have any return statements" + ) + + for returnnode in itertools.chain((first_return,), returns): + if returnnode.value is None: + yield node_classes.Const(None) + else: + try: + yield from returnnode.value.infer(context) + except exceptions.InferenceError: + yield util.Uninferable + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`FunctionDef` this is always ``True``. + :rtype: bool + """ + return True + + def get_children(self): + if self.decorators is not None: + yield self.decorators + + yield self.args + + if self.returns is not None: + yield self.returns + + yield from self.body + + def scope_lookup(self, node, name, offset=0): + """Lookup where the given name is assigned.""" + if name == "__class__": + # __class__ is an implicit closure reference created by the compiler + # if any methods in a class body refer to either __class__ or super. + # In our case, we want to be able to look it up in the current scope + # when `__class__` is being used. + frame = self.parent.frame() + if isinstance(frame, ClassDef): + return self, [frame] + return super().scope_lookup(node, name, offset) + + +class AsyncFunctionDef(FunctionDef): + """Class representing an :class:`ast.FunctionDef` node. + + A :class:`AsyncFunctionDef` is an asynchronous function + created with the `async` keyword. + + >>> node = astroid.extract_node(''' + async def func(things): + async for thing in things: + print(thing) + ''') + >>> node + + >>> node.body[0] + + """ + + +def _rec_get_names(args, names=None): + """return a list of all argument names""" + if names is None: + names = [] + for arg in args: + if isinstance(arg, node_classes.Tuple): + _rec_get_names(arg.elts, names) + else: + names.append(arg.name) + return names + + +def _is_metaclass(klass, seen=None): + """ Return if the given class can be + used as a metaclass. + """ + if klass.name == "type": + return True + if seen is None: + seen = set() + for base in klass.bases: + try: + for baseobj in base.infer(): + baseobj_name = baseobj.qname() + if baseobj_name in seen: + continue + + seen.add(baseobj_name) + if isinstance(baseobj, bases.Instance): + # not abstract + return False + if baseobj is util.Uninferable: + continue + if baseobj is klass: + continue + if not isinstance(baseobj, ClassDef): + continue + if baseobj._type == "metaclass": + return True + if _is_metaclass(baseobj, seen): + return True + except exceptions.InferenceError: + continue + return False + + +def _class_type(klass, ancestors=None): + """return a ClassDef node type to differ metaclass and exception + from 'regular' classes + """ + # XXX we have to store ancestors in case we have an ancestor loop + if klass._type is not None: + return klass._type + if _is_metaclass(klass): + klass._type = "metaclass" + elif klass.name.endswith("Exception"): + klass._type = "exception" + else: + if ancestors is None: + ancestors = set() + klass_name = klass.qname() + if klass_name in ancestors: + # XXX we are in loop ancestors, and have found no type + klass._type = "class" + return "class" + ancestors.add(klass_name) + for base in klass.ancestors(recurs=False): + name = _class_type(base, ancestors) + if name != "class": + if name == "metaclass" and not _is_metaclass(klass): + # don't propagate it if the current class + # can't be a metaclass + continue + klass._type = base.type + break + if klass._type is None: + klass._type = "class" + return klass._type + + +def get_wrapping_class(node): + """Get the class that wraps the given node. + + We consider that a class wraps a node if the class + is a parent for the said node. + + :returns: The class that wraps the given node + :rtype: ClassDef or None + """ + + klass = node.frame() + while klass is not None and not isinstance(klass, ClassDef): + if klass.parent is None: + klass = None + else: + klass = klass.parent.frame() + return klass + + +class ClassDef(mixins.FilterStmtsMixin, LocalsDictNodeNG, node_classes.Statement): + """Class representing an :class:`ast.ClassDef` node. + + >>> node = astroid.extract_node(''' + class Thing: + def my_meth(self, arg): + return arg + self.offset + ''') + >>> node + + """ + + # some of the attributes below are set by the builder module or + # by a raw factories + + # a dictionary of class instances attributes + _astroid_fields = ("decorators", "bases", "body") # name + + decorators = None + """The decorators that are applied to this class. + + :type: Decorators or None + """ + special_attributes = objectmodel.ClassModel() + """The names of special attributes that this class has. + + :type: objectmodel.ClassModel + """ + + _type = None + _metaclass_hack = False + hide = False + type = property( + _class_type, + doc=( + "The class type for this node.\n\n" + "Possible values are: class, metaclass, exception.\n\n" + ":type: str" + ), + ) + _other_fields = ("name", "doc") + _other_other_fields = ("locals", "_newstyle") + _newstyle = None + + def __init__(self, name=None, doc=None, lineno=None, col_offset=None, parent=None): + """ + :param name: The name of the class. + :type name: str or None + + :param doc: The function's docstring. + :type doc: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.instance_attrs = {} + self.locals = {} + """A map of the name of a local variable to the node defining it. + + :type: dict(str, NodeNG) + """ + + self.keywords = [] + """The keywords given to the class definition. + + This is usually for :pep:`3115` style metaclass declaration. + + :type: list(Keyword) or None + """ + + self.bases = [] + """What the class inherits from. + + :type: list(NodeNG) + """ + + self.body = [] + """The contents of the class body. + + :type: list(NodeNG) + """ + + self.name = name + """The name of the class. + + :type name: str or None + """ + + self.doc = doc + """The class' docstring. + + :type doc: str or None + """ + + super(ClassDef, self).__init__(lineno, col_offset, parent) + if parent is not None: + parent.frame().set_local(name, self) + + for local_name, node in self.implicit_locals(): + self.add_local_node(node, local_name) + + def implicit_parameters(self): + return 1 + + def implicit_locals(self): + """Get implicitly defined class definition locals. + + :returns: the the name and Const pair for each local + :rtype: tuple(tuple(str, node_classes.Const), ...) + """ + locals_ = (("__module__", self.special_attributes.attr___module__),) + # __qualname__ is defined in PEP3155 + locals_ += (("__qualname__", self.special_attributes.attr___qualname__),) + return locals_ + + # pylint: disable=redefined-outer-name + def postinit( + self, bases, body, decorators, newstyle=None, metaclass=None, keywords=None + ): + """Do some setup after initialisation. + + :param bases: What the class inherits from. + :type bases: list(NodeNG) + + :param body: The contents of the class body. + :type body: list(NodeNG) + + :param decorators: The decorators that are applied to this class. + :type decorators: Decorators or None + + :param newstyle: Whether this is a new style class or not. + :type newstyle: bool or None + + :param metaclass: The metaclass of this class. + :type metaclass: NodeNG or None + + :param keywords: The keywords given to the class definition. + :type keywords: list(Keyword) or None + """ + self.keywords = keywords + self.bases = bases + self.body = body + self.decorators = decorators + if newstyle is not None: + self._newstyle = newstyle + if metaclass is not None: + self._metaclass = metaclass + + def _newstyle_impl(self, context=None): + if context is None: + context = contextmod.InferenceContext() + if self._newstyle is not None: + return self._newstyle + for base in self.ancestors(recurs=False, context=context): + if base._newstyle_impl(context): + self._newstyle = True + break + klass = self.declared_metaclass() + # could be any callable, we'd need to infer the result of klass(name, + # bases, dict). punt if it's not a class node. + if klass is not None and isinstance(klass, ClassDef): + self._newstyle = klass._newstyle_impl(context) + if self._newstyle is None: + self._newstyle = False + return self._newstyle + + _newstyle = None + newstyle = property( + _newstyle_impl, + doc=("Whether this is a new style class or not\n\n" ":type: bool or None"), + ) + + @decorators_mod.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + if self.bases: + return self.bases[-1].tolineno + + return self.fromlineno + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: Unused. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + :rtype: tuple(int, int) + """ + return self.fromlineno, self.tolineno + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + if self.newstyle: + return "%s.type" % BUILTINS + return "%s.classobj" % BUILTINS + + def display_type(self): + """A human readable type of this node. + + :returns: The type of this node. + :rtype: str + """ + return "Class" + + def callable(self): + """Whether this node defines something that is callable. + + :returns: True if this defines something that is callable, + False otherwise. + For a :class:`ClassDef` this is always ``True``. + :rtype: bool + """ + return True + + def is_subtype_of(self, type_name, context=None): + """Whether this class is a subtype of the given type. + + :param type_name: The name of the type of check against. + :type type_name: str + + :returns: True if this class is a subtype of the given type, + False otherwise. + :rtype: bool + """ + if self.qname() == type_name: + return True + for anc in self.ancestors(context=context): + if anc.qname() == type_name: + return True + return False + + def _infer_type_call(self, caller, context): + name_node = next(caller.args[0].infer(context)) + if isinstance(name_node, node_classes.Const) and isinstance( + name_node.value, str + ): + name = name_node.value + else: + return util.Uninferable + + result = ClassDef(name, None) + + # Get the bases of the class. + class_bases = next(caller.args[1].infer(context)) + if isinstance(class_bases, (node_classes.Tuple, node_classes.List)): + result.bases = class_bases.itered() + else: + # There is currently no AST node that can represent an 'unknown' + # node (Uninferable is not an AST node), therefore we simply return Uninferable here + # although we know at least the name of the class. + return util.Uninferable + + # Get the members of the class + try: + members = next(caller.args[2].infer(context)) + except exceptions.InferenceError: + members = None + + if members and isinstance(members, node_classes.Dict): + for attr, value in members.items: + if isinstance(attr, node_classes.Const) and isinstance(attr.value, str): + result.locals[attr.value] = [value] + + result.parent = caller.parent + return result + + def infer_call_result(self, caller, context=None): + """infer what a class is returning when called""" + if ( + self.is_subtype_of("%s.type" % (BUILTINS,), context) + and len(caller.args) == 3 + ): + result = self._infer_type_call(caller, context) + yield result + return + + dunder_call = None + try: + metaclass = self.metaclass(context=context) + if metaclass is not None: + dunder_call = next(metaclass.igetattr("__call__", context)) + except exceptions.AttributeInferenceError: + pass + + if dunder_call and dunder_call.qname() != "builtins.type.__call__": + # Call type.__call__ if not set metaclass + # (since type is the default metaclass) + context = contextmod.bind_context_to_node(context, self) + yield from dunder_call.infer_call_result(caller, context) + else: + if any(cls.name in EXCEPTION_BASE_CLASSES for cls in self.mro()): + # Subclasses of exceptions can be exception instances + yield objects.ExceptionInstance(self) + else: + yield bases.Instance(self) + + def scope_lookup(self, node, name, offset=0): + """Lookup where the given name is assigned. + + :param node: The node to look for assignments up to. + Any assignments after the given node are ignored. + :type node: NodeNG + + :param name: The name to find assignments for. + :type name: str + + :param offset: The line offset to filter statements up to. + :type offset: int + + :returns: This scope node and the list of assignments associated to the + given name according to the scope where it has been found (locals, + globals or builtin). + :rtype: tuple(str, list(NodeNG)) + """ + # If the name looks like a builtin name, just try to look + # into the upper scope of this class. We might have a + # decorator that it's poorly named after a builtin object + # inside this class. + lookup_upper_frame = ( + isinstance(node.parent, node_classes.Decorators) + and name in MANAGER.builtins_module + ) + if ( + any(node == base or base.parent_of(node) for base in self.bases) + or lookup_upper_frame + ): + # Handle the case where we have either a name + # in the bases of a class, which exists before + # the actual definition or the case where we have + # a Getattr node, with that name. + # + # name = ... + # class A(name): + # def name(self): ... + # + # import name + # class A(name.Name): + # def name(self): ... + + frame = self.parent.frame() + # line offset to avoid that class A(A) resolve the ancestor to + # the defined class + offset = -1 + else: + frame = self + return frame._scope_lookup(node, name, offset) + + @property + def basenames(self): + """The names of the parent classes + + Names are given in the order they appear in the class definition. + + :type: list(str) + """ + return [bnode.as_string() for bnode in self.bases] + + def ancestors(self, recurs=True, context=None): + """Iterate over the base classes in prefixed depth first order. + + :param recurs: Whether to recurse or return direct ancestors only. + :type recurs: bool + + :returns: The base classes + :rtype: iterable(NodeNG) + """ + # FIXME: should be possible to choose the resolution order + # FIXME: inference make infinite loops possible here + yielded = {self} + if context is None: + context = contextmod.InferenceContext() + if not self.bases and self.qname() != "builtins.object": + yield builtin_lookup("object")[1][0] + return + + for stmt in self.bases: + with context.restore_path(): + try: + for baseobj in stmt.infer(context): + if not isinstance(baseobj, ClassDef): + if isinstance(baseobj, bases.Instance): + baseobj = baseobj._proxied + else: + continue + if not baseobj.hide: + if baseobj in yielded: + continue + yielded.add(baseobj) + yield baseobj + if not recurs: + continue + for grandpa in baseobj.ancestors(recurs=True, context=context): + if grandpa is self: + # This class is the ancestor of itself. + break + if grandpa in yielded: + continue + yielded.add(grandpa) + yield grandpa + except exceptions.InferenceError: + continue + + def local_attr_ancestors(self, name, context=None): + """Iterate over the parents that define the given name. + + :param name: The name to find definitions for. + :type name: str + + :returns: The parents that define the given name. + :rtype: iterable(NodeNG) + """ + # Look up in the mro if we can. This will result in the + # attribute being looked up just as Python does it. + try: + ancestors = self.mro(context)[1:] + except exceptions.MroError: + # Fallback to use ancestors, we can't determine + # a sane MRO. + ancestors = self.ancestors(context=context) + for astroid in ancestors: + if name in astroid: + yield astroid + + def instance_attr_ancestors(self, name, context=None): + """Iterate over the parents that define the given name as an attribute. + + :param name: The name to find definitions for. + :type name: str + + :returns: The parents that define the given name as + an instance attribute. + :rtype: iterable(NodeNG) + """ + for astroid in self.ancestors(context=context): + if name in astroid.instance_attrs: + yield astroid + + def has_base(self, node): + """Whether this class directly inherits from the given node. + + :param node: The node to check for. + :type node: NodeNG + + :returns: True if this class directly inherits from the given node. + :rtype: bool + """ + return node in self.bases + + def local_attr(self, name, context=None): + """Get the list of assign nodes associated to the given name. + + Assignments are looked for in both this class and in parents. + + :returns: The list of assignments to the given name. + :rtype: list(NodeNG) + + :raises AttributeInferenceError: If no attribute with this name + can be found in this class or parent classes. + """ + result = [] + if name in self.locals: + result = self.locals[name] + else: + class_node = next(self.local_attr_ancestors(name, context), None) + if class_node: + result = class_node.locals[name] + result = [n for n in result if not isinstance(n, node_classes.DelAttr)] + if result: + return result + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + + def instance_attr(self, name, context=None): + """Get the list of nodes associated to the given attribute name. + + Assignments are looked for in both this class and in parents. + + :returns: The list of assignments to the given name. + :rtype: list(NodeNG) + + :raises AttributeInferenceError: If no attribute with this name + can be found in this class or parent classes. + """ + # Return a copy, so we don't modify self.instance_attrs, + # which could lead to infinite loop. + values = list(self.instance_attrs.get(name, [])) + # get all values from parents + for class_node in self.instance_attr_ancestors(name, context): + values += class_node.instance_attrs[name] + values = [n for n in values if not isinstance(n, node_classes.DelAttr)] + if values: + return values + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + + def instantiate_class(self): + """Get an :class:`Instance` of the :class:`ClassDef` node. + + :returns: An :class:`Instance` of the :class:`ClassDef` node, + or self if this is not possible. + :rtype: Instance or ClassDef + """ + return bases.Instance(self) + + def getattr(self, name, context=None, class_context=True): + """Get an attribute from this class, using Python's attribute semantic. + + This method doesn't look in the :attr:`instance_attrs` dictionary + since it is done by an :class:`Instance` proxy at inference time. + It may return an :class:`Uninferable` object if + the attribute has not been + found, but a ``__getattr__`` or ``__getattribute__`` method is defined. + If ``class_context`` is given, then it is considered that the + attribute is accessed from a class context, + e.g. ClassDef.attribute, otherwise it might have been accessed + from an instance as well. If ``class_context`` is used in that + case, then a lookup in the implicit metaclass and the explicit + metaclass will be done. + + :param name: The attribute to look for. + :type name: str + + :param class_context: Whether the attribute can be accessed statically. + :type class_context: bool + + :returns: The attribute. + :rtype: list(NodeNG) + + :raises AttributeInferenceError: If the attribute cannot be inferred. + """ + values = self.locals.get(name, []) + if name in self.special_attributes and class_context and not values: + result = [self.special_attributes.lookup(name)] + if name == "__bases__": + # Need special treatment, since they are mutable + # and we need to return all the values. + result += values + return result + + # don't modify the list in self.locals! + values = list(values) + for classnode in self.ancestors(recurs=True, context=context): + values += classnode.locals.get(name, []) + + if class_context: + values += self._metaclass_lookup_attribute(name, context) + + if not values: + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + + # Look for AnnAssigns, which are not attributes in the purest sense. + for value in values: + if isinstance(value, node_classes.AssignName): + stmt = value.statement() + if isinstance(stmt, node_classes.AnnAssign) and stmt.value is None: + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + return values + + def _metaclass_lookup_attribute(self, name, context): + """Search the given name in the implicit and the explicit metaclass.""" + attrs = set() + implicit_meta = self.implicit_metaclass() + metaclass = self.metaclass() + for cls in {implicit_meta, metaclass}: + if cls and cls != self and isinstance(cls, ClassDef): + cls_attributes = self._get_attribute_from_metaclass(cls, name, context) + attrs.update(set(cls_attributes)) + return attrs + + def _get_attribute_from_metaclass(self, cls, name, context): + try: + attrs = cls.getattr(name, context=context, class_context=True) + except exceptions.AttributeInferenceError: + return + + for attr in bases._infer_stmts(attrs, context, frame=cls): + if not isinstance(attr, FunctionDef): + yield attr + continue + + if bases._is_property(attr): + yield from attr.infer_call_result(self, context) + continue + if attr.type == "classmethod": + # If the method is a classmethod, then it will + # be bound to the metaclass, not to the class + # from where the attribute is retrieved. + # get_wrapping_class could return None, so just + # default to the current class. + frame = get_wrapping_class(attr) or self + yield bases.BoundMethod(attr, frame) + elif attr.type == "staticmethod": + yield attr + else: + yield bases.BoundMethod(attr, self) + + def igetattr(self, name, context=None, class_context=True): + """Infer the possible values of the given variable. + + :param name: The name of the variable to infer. + :type name: str + + :returns: The inferred possible values. + :rtype: iterable(NodeNG or Uninferable) + """ + # set lookup name since this is necessary to infer on import nodes for + # instance + context = contextmod.copy_context(context) + context.lookupname = name + try: + attr = self.getattr(name, context, class_context=class_context)[0] + for inferred in bases._infer_stmts([attr], context, frame=self): + # yield Uninferable object instead of descriptors when necessary + if not isinstance(inferred, node_classes.Const) and isinstance( + inferred, bases.Instance + ): + try: + inferred._proxied.getattr("__get__", context) + except exceptions.AttributeInferenceError: + yield inferred + else: + yield util.Uninferable + else: + yield function_to_method(inferred, self) + except exceptions.AttributeInferenceError as error: + if not name.startswith("__") and self.has_dynamic_getattr(context): + # class handle some dynamic attributes, return a Uninferable object + yield util.Uninferable + else: + raise exceptions.InferenceError( + error.message, target=self, attribute=name, context=context + ) + + def has_dynamic_getattr(self, context=None): + """Check if the class has a custom __getattr__ or __getattribute__. + + If any such method is found and it is not from + builtins, nor from an extension module, then the function + will return True. + + :returns: True if the class has a custom + __getattr__ or __getattribute__, False otherwise. + :rtype: bool + """ + + def _valid_getattr(node): + root = node.root() + return root.name != BUILTINS and getattr(root, "pure_python", None) + + try: + return _valid_getattr(self.getattr("__getattr__", context)[0]) + except exceptions.AttributeInferenceError: + # if self.newstyle: XXX cause an infinite recursion error + try: + getattribute = self.getattr("__getattribute__", context)[0] + return _valid_getattr(getattribute) + except exceptions.AttributeInferenceError: + pass + return False + + def getitem(self, index, context=None): + """Return the inference of a subscript. + + This is basically looking up the method in the metaclass and calling it. + + :returns: The inferred value of a subscript to this class. + :rtype: NodeNG + + :raises AstroidTypeError: If this class does not define a + ``__getitem__`` method. + """ + try: + methods = dunder_lookup.lookup(self, "__getitem__") + except exceptions.AttributeInferenceError as exc: + raise exceptions.AstroidTypeError(node=self, context=context) from exc + + method = methods[0] + + # Create a new callcontext for providing index as an argument. + new_context = contextmod.bind_context_to_node(context, self) + new_context.callcontext = contextmod.CallContext(args=[index]) + + try: + return next(method.infer_call_result(self, new_context)) + except exceptions.InferenceError: + return util.Uninferable + + def methods(self): + """Iterate over all of the method defined in this class and its parents. + + :returns: The methods defined on the class. + :rtype: iterable(FunctionDef) + """ + done = {} + for astroid in itertools.chain(iter((self,)), self.ancestors()): + for meth in astroid.mymethods(): + if meth.name in done: + continue + done[meth.name] = None + yield meth + + def mymethods(self): + """Iterate over all of the method defined in this class only. + + :returns: The methods defined on the class. + :rtype: iterable(FunctionDef) + """ + for member in self.values(): + if isinstance(member, FunctionDef): + yield member + + def implicit_metaclass(self): + """Get the implicit metaclass of the current class. + + For newstyle classes, this will return an instance of builtins.type. + For oldstyle classes, it will simply return None, since there's + no implicit metaclass there. + + :returns: The metaclass. + :rtype: builtins.type or None + """ + if self.newstyle: + return builtin_lookup("type")[1][0] + return None + + _metaclass = None + + def declared_metaclass(self, context=None): + """Return the explicit declared metaclass for the current class. + + An explicit declared metaclass is defined + either by passing the ``metaclass`` keyword argument + in the class definition line (Python 3) or (Python 2) by + having a ``__metaclass__`` class attribute, or if there are + no explicit bases but there is a global ``__metaclass__`` variable. + + :returns: The metaclass of this class, + or None if one could not be found. + :rtype: NodeNG or None + """ + for base in self.bases: + try: + for baseobj in base.infer(context=context): + if isinstance(baseobj, ClassDef) and baseobj.hide: + self._metaclass = baseobj._metaclass + self._metaclass_hack = True + break + except exceptions.InferenceError: + pass + + if self._metaclass: + # Expects this from Py3k TreeRebuilder + try: + return next( + node + for node in self._metaclass.infer(context=context) + if node is not util.Uninferable + ) + except (exceptions.InferenceError, StopIteration): + return None + + return None + + def _find_metaclass(self, seen=None, context=None): + if seen is None: + seen = set() + seen.add(self) + + klass = self.declared_metaclass(context=context) + if klass is None: + for parent in self.ancestors(context=context): + if parent not in seen: + klass = parent._find_metaclass(seen) + if klass is not None: + break + return klass + + def metaclass(self, context=None): + """Get the metaclass of this class. + + If this class does not define explicitly a metaclass, + then the first defined metaclass in ancestors will be used + instead. + + :returns: The metaclass of this class. + :rtype: NodeNG or None + """ + return self._find_metaclass(context=context) + + def has_metaclass_hack(self): + return self._metaclass_hack + + def _islots(self): + """ Return an iterator with the inferred slots. """ + if "__slots__" not in self.locals: + return None + for slots in self.igetattr("__slots__"): + # check if __slots__ is a valid type + for meth in ITER_METHODS: + try: + slots.getattr(meth) + break + except exceptions.AttributeInferenceError: + continue + else: + continue + + if isinstance(slots, node_classes.Const): + # a string. Ignore the following checks, + # but yield the node, only if it has a value + if slots.value: + yield slots + continue + if not hasattr(slots, "itered"): + # we can't obtain the values, maybe a .deque? + continue + + if isinstance(slots, node_classes.Dict): + values = [item[0] for item in slots.items] + else: + values = slots.itered() + if values is util.Uninferable: + continue + if not values: + # Stop the iteration, because the class + # has an empty list of slots. + return values + + for elt in values: + try: + for inferred in elt.infer(): + if inferred is util.Uninferable: + continue + if not isinstance( + inferred, node_classes.Const + ) or not isinstance(inferred.value, str): + continue + if not inferred.value: + continue + yield inferred + except exceptions.InferenceError: + continue + + return None + + def _slots(self): + if not self.newstyle: + raise NotImplementedError( + "The concept of slots is undefined for old-style classes." + ) + + slots = self._islots() + try: + first = next(slots) + except StopIteration as exc: + # The class doesn't have a __slots__ definition or empty slots. + if exc.args and exc.args[0] not in ("", None): + return exc.args[0] + return None + return [first] + list(slots) + + # Cached, because inferring them all the time is expensive + @decorators_mod.cached + def slots(self): + """Get all the slots for this node. + + :returns: The names of slots for this class. + If the class doesn't define any slot, through the ``__slots__`` + variable, then this function will return a None. + Also, it will return None in the case the slots were not inferred. + :rtype: list(str) or None + """ + + def grouped_slots(): + # Not interested in object, since it can't have slots. + for cls in self.mro()[:-1]: + try: + cls_slots = cls._slots() + except NotImplementedError: + continue + if cls_slots is not None: + yield from cls_slots + else: + yield None + + if not self.newstyle: + raise NotImplementedError( + "The concept of slots is undefined for old-style classes." + ) + + slots = list(grouped_slots()) + if not all(slot is not None for slot in slots): + return None + + return sorted(slots, key=lambda item: item.value) + + def _inferred_bases(self, context=None): + # Similar with .ancestors, but the difference is when one base is inferred, + # only the first object is wanted. That's because + # we aren't interested in superclasses, as in the following + # example: + # + # class SomeSuperClass(object): pass + # class SomeClass(SomeSuperClass): pass + # class Test(SomeClass): pass + # + # Inferring SomeClass from the Test's bases will give + # us both SomeClass and SomeSuperClass, but we are interested + # only in SomeClass. + + if context is None: + context = contextmod.InferenceContext() + if not self.bases and self.qname() != "builtins.object": + yield builtin_lookup("object")[1][0] + return + + for stmt in self.bases: + try: + baseobj = next(stmt.infer(context=context)) + except exceptions.InferenceError: + continue + if isinstance(baseobj, bases.Instance): + baseobj = baseobj._proxied + if not isinstance(baseobj, ClassDef): + continue + if not baseobj.hide: + yield baseobj + else: + yield from baseobj.bases + + def _compute_mro(self, context=None): + inferred_bases = list(self._inferred_bases(context=context)) + bases_mro = [] + for base in inferred_bases: + if base is self: + continue + + try: + mro = base._compute_mro(context=context) + bases_mro.append(mro) + except NotImplementedError: + # Some classes have in their ancestors both newstyle and + # old style classes. For these we can't retrieve the .mro, + # although in Python it's possible, since the class we are + # currently working is in fact new style. + # So, we fallback to ancestors here. + ancestors = list(base.ancestors(context=context)) + bases_mro.append(ancestors) + + unmerged_mro = [[self]] + bases_mro + [inferred_bases] + unmerged_mro = list(clean_duplicates_mro(unmerged_mro, self, context)) + return _c3_merge(unmerged_mro, self, context) + + def mro(self, context=None) -> List["ClassDef"]: + """Get the method resolution order, using C3 linearization. + + :returns: The list of ancestors, sorted by the mro. + :rtype: list(NodeNG) + :raises DuplicateBasesError: Duplicate bases in the same class base + :raises InconsistentMroError: A class' MRO is inconsistent + """ + return self._compute_mro(context=context) + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`ClassDef` this is always ``True``. + :rtype: bool + """ + return True + + def get_children(self): + if self.decorators is not None: + yield self.decorators + + yield from self.bases + yield from self.body + + @decorators_mod.cached + def _get_assign_nodes(self): + children_assign_nodes = ( + child_node._get_assign_nodes() for child_node in self.body + ) + return list(itertools.chain.from_iterable(children_assign_nodes)) diff --git a/py3/lib/python3.6/site-packages/astroid/test_utils.py b/py3/lib/python3.6/site-packages/astroid/test_utils.py new file mode 100644 index 0000000..6c965ef --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/test_utils.py @@ -0,0 +1,73 @@ +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2018 Anthony Sottile + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Utility functions for test code that uses astroid ASTs as input.""" +import contextlib +import functools +import sys +import warnings + +import pytest + +from astroid import nodes + + +def require_version(minver=None, maxver=None): + """ Compare version of python interpreter to the given one. Skip the test + if older. + """ + + def parse(string, default=None): + string = string or default + try: + return tuple(int(v) for v in string.split(".")) + except ValueError as exc: + raise ValueError( + "{string} is not a correct version : should be X.Y[.Z].".format( + string=string + ) + ) from exc + + def check_require_version(f): + current = sys.version_info[:3] + if parse(minver, "0") < current <= parse(maxver, "4"): + return f + + str_version = ".".join(str(v) for v in sys.version_info) + + @functools.wraps(f) + def new_f(*args, **kwargs): + if minver is not None: + pytest.skip( + "Needs Python > %s. Current version is %s." % (minver, str_version) + ) + elif maxver is not None: + pytest.skip( + "Needs Python <= %s. Current version is %s." % (maxver, str_version) + ) + + return new_f + + return check_require_version + + +def get_name_node(start_from, name, index=0): + return [n for n in start_from.nodes_of_class(nodes.Name) if n.name == name][index] + + +@contextlib.contextmanager +def enable_warning(warning): + warnings.simplefilter("always", warning) + try: + yield + finally: + # Reset it to default value, so it will take + # into account the values from the -W flag. + warnings.simplefilter("default", warning) diff --git a/py3/lib/python3.6/site-packages/astroid/transforms.py b/py3/lib/python3.6/site-packages/astroid/transforms.py new file mode 100644 index 0000000..e5506cc --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/transforms.py @@ -0,0 +1,90 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2016 Ceridwen +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +import collections +from functools import lru_cache + + +class TransformVisitor: + """A visitor for handling transforms. + + The standard approach of using it is to call + :meth:`~visit` with an *astroid* module and the class + will take care of the rest, walking the tree and running the + transforms for each encountered node. + """ + + TRANSFORM_MAX_CACHE_SIZE = 10000 + + def __init__(self): + self.transforms = collections.defaultdict(list) + + @lru_cache(maxsize=TRANSFORM_MAX_CACHE_SIZE) + def _transform(self, node): + """Call matching transforms for the given node if any and return the + transformed node. + """ + cls = node.__class__ + if cls not in self.transforms: + # no transform registered for this class of node + return node + + transforms = self.transforms[cls] + for transform_func, predicate in transforms: + if predicate is None or predicate(node): + ret = transform_func(node) + # if the transformation function returns something, it's + # expected to be a replacement for the node + if ret is not None: + node = ret + if ret.__class__ != cls: + # Can no longer apply the rest of the transforms. + break + return node + + def _visit(self, node): + if hasattr(node, "_astroid_fields"): + for name in node._astroid_fields: + value = getattr(node, name) + visited = self._visit_generic(value) + if visited != value: + setattr(node, name, visited) + return self._transform(node) + + def _visit_generic(self, node): + if isinstance(node, list): + return [self._visit_generic(child) for child in node] + if isinstance(node, tuple): + return tuple(self._visit_generic(child) for child in node) + if not node or isinstance(node, str): + return node + + return self._visit(node) + + def register_transform(self, node_class, transform, predicate=None): + """Register `transform(node)` function to be applied on the given + astroid's `node_class` if `predicate` is None or returns true + when called with the node as argument. + + The transform function may return a value which is then used to + substitute the original node in the tree. + """ + self.transforms[node_class].append((transform, predicate)) + + def unregister_transform(self, node_class, transform, predicate=None): + """Unregister the given transform.""" + self.transforms[node_class].remove((transform, predicate)) + + def visit(self, module): + """Walk the given astroid *tree* and transform each encountered node + + Only the nodes which have transforms registered will actually + be replaced or changed. + """ + module.body = [self._visit(child) for child in module.body] + return self._transform(module) diff --git a/py3/lib/python3.6/site-packages/astroid/util.py b/py3/lib/python3.6/site-packages/astroid/util.py new file mode 100644 index 0000000..3ab7561 --- /dev/null +++ b/py3/lib/python3.6/site-packages/astroid/util.py @@ -0,0 +1,164 @@ +# Copyright (c) 2015-2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +import warnings +from itertools import islice + +import importlib +import lazy_object_proxy + + +def lazy_descriptor(obj): + class DescriptorProxy(lazy_object_proxy.Proxy): + def __get__(self, instance, owner=None): + return self.__class__.__get__(self, instance) + + return DescriptorProxy(obj) + + +def lazy_import(module_name): + return lazy_object_proxy.Proxy( + lambda: importlib.import_module("." + module_name, "astroid") + ) + + +@object.__new__ +class Uninferable: + """Special inference object, which is returned when inference fails.""" + + def __repr__(self): + return "Uninferable" + + __str__ = __repr__ + + def __getattribute__(self, name): + if name == "next": + raise AttributeError("next method should not be called") + if name.startswith("__") and name.endswith("__"): + return object.__getattribute__(self, name) + if name == "accept": + return object.__getattribute__(self, name) + return self + + def __call__(self, *args, **kwargs): + return self + + def __bool__(self): + return False + + __nonzero__ = __bool__ + + def accept(self, visitor): + func = getattr(visitor, "visit_uninferable") + return func(self) + + +class BadOperationMessage: + """Object which describes a TypeError occurred somewhere in the inference chain + + This is not an exception, but a container object which holds the types and + the error which occurred. + """ + + +class BadUnaryOperationMessage(BadOperationMessage): + """Object which describes operational failures on UnaryOps.""" + + def __init__(self, operand, op, error): + self.operand = operand + self.op = op + self.error = error + + @property + def _object_type_helper(self): + helpers = lazy_import("helpers") + return helpers.object_type + + def _object_type(self, obj): + # pylint: disable=not-callable; can't infer lazy_import + objtype = self._object_type_helper(obj) + if objtype is Uninferable: + return None + + return objtype + + def __str__(self): + if hasattr(self.operand, "name"): + operand_type = self.operand.name + else: + object_type = self._object_type(self.operand) + if hasattr(object_type, "name"): + operand_type = object_type.name + else: + # Just fallback to as_string + operand_type = object_type.as_string() + + msg = "bad operand type for unary {}: {}" + return msg.format(self.op, operand_type) + + +class BadBinaryOperationMessage(BadOperationMessage): + """Object which describes type errors for BinOps.""" + + def __init__(self, left_type, op, right_type): + self.left_type = left_type + self.right_type = right_type + self.op = op + + def __str__(self): + msg = "unsupported operand type(s) for {}: {!r} and {!r}" + return msg.format(self.op, self.left_type.name, self.right_type.name) + + +def _instancecheck(cls, other): + wrapped = cls.__wrapped__ + other_cls = other.__class__ + is_instance_of = wrapped is other_cls or issubclass(other_cls, wrapped) + warnings.warn( + "%r is deprecated and slated for removal in astroid " + "2.0, use %r instead" % (cls.__class__.__name__, wrapped.__name__), + PendingDeprecationWarning, + stacklevel=2, + ) + return is_instance_of + + +def proxy_alias(alias_name, node_type): + """Get a Proxy from the given name to the given node type.""" + proxy = type( + alias_name, + (lazy_object_proxy.Proxy,), + { + "__class__": object.__dict__["__class__"], + "__instancecheck__": _instancecheck, + }, + ) + return proxy(lambda: node_type) + + +def limit_inference(iterator, size): + """Limit inference amount. + + Limit inference amount to help with performance issues with + exponentially exploding possible results. + + :param iterator: Inference generator to limit + :type iterator: Iterator(NodeNG) + + :param size: Maximum mount of nodes yielded plus an + Uninferable at the end if limit reached + :type size: int + + :yields: A possibly modified generator + :rtype param: Iterable + """ + yield from islice(iterator, size) + has_more = next(iterator, False) + if has_more is not False: + yield Uninferable + return diff --git a/py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/LICENSE.txt b/py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/LICENSE.txt deleted file mode 100644 index 802b53f..0000000 --- a/py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -This packge contains a modified version of ca-bundle.crt: - -ca-bundle.crt -- Bundle of CA Root Certificates - -Certificate data from Mozilla as of: Thu Nov 3 19:04:19 2011# -This is a bundle of X.509 certificates of public Certificate Authorities -(CA). These were automatically extracted from Mozilla's root certificates -file (certdata.txt). This file can be found in the mozilla source tree: -http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1# -It contains the certificates in PEM format and therefore -can be directly used with curl / libcurl / php_curl, or with -an Apache+mod_ssl webserver for SSL client authentication. -Just configure this file as the SSLCACertificateFile.# - -***** BEGIN LICENSE BLOCK ***** -This Source Code Form is subject to the terms of the Mozilla Public License, -v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain -one at http://mozilla.org/MPL/2.0/. - -***** END LICENSE BLOCK ***** -@(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $ diff --git a/py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/RECORD b/py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/RECORD deleted file mode 100644 index 2835d0c..0000000 --- a/py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/RECORD +++ /dev/null @@ -1,15 +0,0 @@ -certifi/__init__.py,sha256=phsMyKTQP7MMe1wAHfhXPbQVxL3wXixOomxzNh5Cwa4,52 -certifi/__main__.py,sha256=FiOYt1Fltst7wk9DRa6GCoBr8qBUxlNQu_MKJf04E6s,41 -certifi/cacert.pem,sha256=DddOv7pQyMB8zNNgiXSSFrPVn7EN8qbe7P6h_IYyuek,282085 -certifi/core.py,sha256=EuFc2BsToG5O1-qsx4BSjQ1r1-7WRtH87b1WflZOWhI,218 -certifi-2019.6.16.dist-info/DESCRIPTION.rst,sha256=aLNHONztn2ZiBpSTivVFy6EDIWmuNYSsEQwx4NWbvB4,1580 -certifi-2019.6.16.dist-info/LICENSE.txt,sha256=anCkv2sBABbVmmS4rkrY3H9e8W8ftFPMLs13HFo0ETE,1048 -certifi-2019.6.16.dist-info/METADATA,sha256=bmxei5fIjQJCT_5_2k2ReQ1IDvrguA5Qan26BXRcbN0,2522 -certifi-2019.6.16.dist-info/RECORD,, -certifi-2019.6.16.dist-info/WHEEL,sha256=5wvfB7GvgZAbKBSE9uX9Zbi6LCL-_KgezgHblXhCRnM,113 -certifi-2019.6.16.dist-info/metadata.json,sha256=soH2Ke2dIXqmSFFz1swsK3Uno_9ed57OqPIXuOxFXYA,1048 -certifi-2019.6.16.dist-info/top_level.txt,sha256=KMu4vUCfsjLrkPbSNdgdekS-pVJzBAJFO__nI8NF6-U,8 -certifi-2019.6.16.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -certifi/__pycache__/core.cpython-36.pyc,, -certifi/__pycache__/__main__.cpython-36.pyc,, -certifi/__pycache__/__init__.cpython-36.pyc,, diff --git a/py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/DESCRIPTION.rst b/py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/DESCRIPTION.rst similarity index 100% rename from py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/DESCRIPTION.rst rename to py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/DESCRIPTION.rst diff --git a/py3/lib/python3.6/site-packages/python_dateutil-2.8.0.dist-info/INSTALLER b/py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/INSTALLER similarity index 100% rename from py3/lib/python3.6/site-packages/python_dateutil-2.8.0.dist-info/INSTALLER rename to py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/INSTALLER diff --git a/py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/METADATA b/py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/METADATA similarity index 99% rename from py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/METADATA rename to py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/METADATA index 29540e3..6ecc70c 100644 --- a/py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/METADATA +++ b/py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.0 Name: certifi -Version: 2019.6.16 +Version: 2019.9.11 Summary: Python package for providing Mozilla's CA Bundle. Home-page: https://certifi.io/ Author: Kenneth Reitz diff --git a/py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/RECORD b/py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/RECORD new file mode 100644 index 0000000..ab6a91f --- /dev/null +++ b/py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/RECORD @@ -0,0 +1,14 @@ +certifi/__init__.py,sha256=WFoavXHhpX-BZ5kbvyinZTbhLsqPJypLKIZu29nUsQg,52 +certifi/__main__.py,sha256=FiOYt1Fltst7wk9DRa6GCoBr8qBUxlNQu_MKJf04E6s,41 +certifi/cacert.pem,sha256=cVC1b0T-OcQzgdcRql2yMxT7O08O6pcJHnuO9nbLLn0,278533 +certifi/core.py,sha256=EuFc2BsToG5O1-qsx4BSjQ1r1-7WRtH87b1WflZOWhI,218 +certifi-2019.9.11.dist-info/DESCRIPTION.rst,sha256=aLNHONztn2ZiBpSTivVFy6EDIWmuNYSsEQwx4NWbvB4,1580 +certifi-2019.9.11.dist-info/METADATA,sha256=M0Gen7rhgJKIvggZuENXqcZexg74gXdjGC679bMeoDw,2522 +certifi-2019.9.11.dist-info/RECORD,, +certifi-2019.9.11.dist-info/WHEEL,sha256=5wvfB7GvgZAbKBSE9uX9Zbi6LCL-_KgezgHblXhCRnM,113 +certifi-2019.9.11.dist-info/metadata.json,sha256=NppG2TtVr6va5nwyG9pxGhktdvudS-IfpTkaQaWKlBE,1022 +certifi-2019.9.11.dist-info/top_level.txt,sha256=KMu4vUCfsjLrkPbSNdgdekS-pVJzBAJFO__nI8NF6-U,8 +certifi-2019.9.11.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +certifi/__pycache__/core.cpython-36.pyc,, +certifi/__pycache__/__main__.cpython-36.pyc,, +certifi/__pycache__/__init__.cpython-36.pyc,, diff --git a/py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/WHEEL b/py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/WHEEL similarity index 100% rename from py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/WHEEL rename to py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/WHEEL diff --git a/py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/metadata.json b/py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/metadata.json similarity index 73% rename from py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/metadata.json rename to py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/metadata.json index afe3503..7f155f5 100644 --- a/py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/metadata.json +++ b/py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/metadata.json @@ -1 +1 @@ -{"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7"], "extensions": {"python.details": {"contacts": [{"email": "me@kennethreitz.com", "name": "Kenneth Reitz", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "https://certifi.io/"}}}, "generator": "bdist_wheel (0.30.0.a0)", "license": "MPL-2.0", "metadata_version": "2.0", "name": "certifi", "summary": "Python package for providing Mozilla's CA Bundle.", "version": "2019.6.16"} \ No newline at end of file +{"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7"], "extensions": {"python.details": {"contacts": [{"email": "me@kennethreitz.com", "name": "Kenneth Reitz", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://certifi.io/"}}}, "generator": "bdist_wheel (0.30.0.a0)", "license": "MPL-2.0", "metadata_version": "2.0", "name": "certifi", "summary": "Python package for providing Mozilla's CA Bundle.", "version": "2019.9.11"} \ No newline at end of file diff --git a/py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/top_level.txt b/py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/top_level.txt similarity index 100% rename from py3/lib/python3.6/site-packages/certifi-2019.6.16.dist-info/top_level.txt rename to py3/lib/python3.6/site-packages/certifi-2019.9.11.dist-info/top_level.txt diff --git a/py3/lib/python3.6/site-packages/certifi/__init__.py b/py3/lib/python3.6/site-packages/certifi/__init__.py index 8ccb14e..8e358e4 100644 --- a/py3/lib/python3.6/site-packages/certifi/__init__.py +++ b/py3/lib/python3.6/site-packages/certifi/__init__.py @@ -1,3 +1,3 @@ from .core import where -__version__ = "2019.06.16" +__version__ = "2019.09.11" diff --git a/py3/lib/python3.6/site-packages/certifi/cacert.pem b/py3/lib/python3.6/site-packages/certifi/cacert.pem index 9ca290f..70fa91f 100644 --- a/py3/lib/python3.6/site-packages/certifi/cacert.pem +++ b/py3/lib/python3.6/site-packages/certifi/cacert.pem @@ -771,36 +771,6 @@ vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep +OkuE6N36B9K -----END CERTIFICATE----- -# Issuer: CN=Class 2 Primary CA O=Certplus -# Subject: CN=Class 2 Primary CA O=Certplus -# Label: "Certplus Class 2 Primary CA" -# Serial: 177770208045934040241468760488327595043 -# MD5 Fingerprint: 88:2c:8c:52:b8:a2:3c:f3:f7:bb:03:ea:ae:ac:42:0b -# SHA1 Fingerprint: 74:20:74:41:72:9c:dd:92:ec:79:31:d8:23:10:8d:c2:81:92:e2:bb -# SHA256 Fingerprint: 0f:99:3c:8a:ef:97:ba:af:56:87:14:0e:d5:9a:d1:82:1b:b4:af:ac:f0:aa:9a:58:b5:d5:7a:33:8a:3a:fb:cb ------BEGIN CERTIFICATE----- -MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw -PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz -cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 -MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz -IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ -ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR -VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL -kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd -EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas -H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 -HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud -DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 -QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu -Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ -AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 -yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR -FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA -ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB -kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 -l7+ijrRU ------END CERTIFICATE----- - # Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co. # Subject: CN=DST Root CA X3 O=Digital Signature Trust Co. # Label: "DST Root CA X3" @@ -1219,36 +1189,6 @@ t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== -----END CERTIFICATE----- -# Issuer: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center -# Subject: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center -# Label: "Deutsche Telekom Root CA 2" -# Serial: 38 -# MD5 Fingerprint: 74:01:4a:91:b1:08:c4:58:ce:47:cd:f0:dd:11:53:08 -# SHA1 Fingerprint: 85:a4:08:c0:9c:19:3e:5d:51:58:7d:cd:d6:13:30:fd:8c:de:37:bf -# SHA256 Fingerprint: b6:19:1a:50:d0:c3:97:7f:7d:a9:9b:cd:aa:c8:6a:22:7d:ae:b9:67:9e:c7:0b:a3:b0:c9:d9:22:71:c1:70:d3 ------BEGIN CERTIFICATE----- -MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc -MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj -IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB -IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE -RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl -U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290 -IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU -ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC -QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr -rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S -NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc -QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH -txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP -BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC -AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp -tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa -IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl -6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+ -xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU -Cm26OWMohpLzGITY+9HPBVZkVw== ------END CERTIFICATE----- - # Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc # Subject: CN=Cybertrust Global Root O=Cybertrust, Inc # Label: "Cybertrust Global Root" diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/.libs_cffi_backend/libffi-ae16d830.so.6.0.4 b/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/.libs_cffi_backend/libffi-ae16d830.so.6.0.4 deleted file mode 100644 index 3e4e43897da7bd38da28b442ec3eb0c71a4402e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 149064 zcmeFa3wRVo)<4`mmt-clZbE_q5*SE;fFg;45&_LX0zF~EO>W*%FyiYCVFIk{B`^ut zHY4%Q-ri+*)kW8J@v;KCYC@0%LG>$2(+MvM;A}u|&w%)5H{81?zJhR!)+NrIAu1e)FV0 zg4W$p^7G8}n@yaZg0nzO{WLT$;pgOM#Hdz@3n}kfOXRL;o<(P;q~$dQ?J+-pt^j|Q zj<)#Osa=m~A?E_Kp0vPcW~{WyBD~jYm0SIzwpg#=b`xK4yH8~7wApIUPCX`>(5Gmx z*wS~ESx>T3%~G13N|s_~|L6K&*MK!dXH1+J@%cSYE&i2LlG0B_3CIPzIURof8R%EQ z98O37w=>XRdj>qk^PNVX181P0b_RUkGsyGw8R+jk1OBZu;Mbl3-*N{0J7>UWok31c zzticV?hJhTp8>z{4EW2=fcKmM|KJ($jc34Lcn16xXXw{?XTaZk20oXZ0UrdP{Qgd&Uu&+h`M+<-0!rT6m?k`>PO2Ii6 zp_SZV@t3;rZx;68krr5;7;4eKfRydlUS=Y!YSI%HeSy!!XM-=VPjItebLJ3|B)eZ* zt#<3WwA&{1gLeHU{ne>v`kKYRrJo6h%|vop`1RQ)VmA2l3R(CCmSV0p(b9z|r#x%t zmHS69fJOZ-iDa?th3BiwdAjwW8uw2`m>F{_Eh{53-9ZK zpDg6h_*s7sgI=_2Da;Z}Y6Dx!U))80pWv@bbGqPzLjIqxgI`(tS=--~(;lz?^+o$X z4g5y~|IxsIH1L1YfN)C=sq>#C^3FI6%S>!16)~MS8T+^YjeiojI;2wJyG4Ui#*H^3 zf^bTUEL>%;8?gg*NOu7im*tmjKYQ5P&wIMy*IW34F8Eq&J)F`7zt+Mp=z?Ew;j6mf ziwBzG+}j0Tf1Qb6(*?gE&&03og5P1$ukV7l={I)4H(B&eUGO%2a~J$Bi@v1`-j+Yw z1;5{-Z|j2h4KU@Gto^>N{{t4i+68aZXLZ3pWzpw%!P~I3$R`@&ae&7=%ALQ1#$TJ^Q@(Dc#jC4&LJ~hhGBIPhu;^6?-qw|iNmMI;iGZ*3*zvH#o>$M@V+?wusD2v9Nv!QSzHi@_s7wXjKf>5R+JXU;d{l=YjJpM3nNOW#NjWD zqn{mzx3+SkbWR-J+DZug{5ZU|wGsFQad@A=m_JM7@crWORdM)>;_&yz;q&A0TKEf3 z^lzBaT6l}6p|hZU#Pe7Br1k+X;#cWgj2z+lB#5=N;~MZZVY-P}vw;6dn64pKC*WTb z=G2d^7x06GIpt$(1$-Z2PU%>!fR_{IRE|{%_zuD}qu2rgFCj-lS$BG4fIblxSSb>125$2SQ`2<`>m{T>T3V1AGPSKbo;EM=zYQ_$q1Y*E>ggNzM zEdm}wm{Tj(Ea3ixIi+HC0`5haE3J(aJ^=rz5{6RYHz+OHVX`tzEu*g*hJ(ztJluB zRMUSDN~vjAs!5_5x2amqm!Tzvby}lX3JZ5v=o6r|yQGbrw^~hmWm)VVrOfP{xe|$s2+X(KYQA`Z!Ohj~2c} zs@xb|1i5PJYD3R*JVZNJT-8uft8A##z%d+^wKbX-gH;Efo0W&_l$Ywr1;nK5(1(9| zWM=zDx|12<6A71U#+7-##YtCO<-f8)>02U6fpC!&(0|k~)bwjSCHe$cP@k+eP7t9| zXqrD#++JE!r$ugV@KmO@4ymZs!VMm+s5R7AGe!wXzlv^ynZtBGz2Yh%rr<338%y%C z(5e*FKVxgL?l3m!C#dg?t`QX~ca|C@d9DB?^0YqMIeuSc1@vwDuAuJ9^XtupyQ4+W z1p1W)fni_aFS3GqN?y5M@7J63T`zM4qCISq+JN2`TX%v@nf7bUa$($z$sQ=}7rk50 z(~JwWaJ?8CE&O&O2PaZeATK>jGYTuhcPFJ*{tG%qdA+C+`?f(?Scg7?#srUX4|rnG zhqX?stq31iLc=wE_~w9-f}z217+x(LleO@+L~ud+QJW^eUDUX^A1Ra#fh5#Pt=y^^ zXYX_ zJL|4&7@HK1x+}tMNy^GEpa$4RU~Wl`6qKW!j8#BM0mGFiI;{KK!f!yD22TJs;xD?@ zwd55JjQ=YC)p7RHK|dFh#oyNYW*0t&iGI=6ZwI~dx>@pTxDMKt)vmI^M2EZZ(UjLj zLF@($9s1Kj|B{L3TEy|T@tWCiY-9(1c%EjYYcQwxkHbFndd+Z>h%+PH1l40C!YxpJ zeat25nD#(-;-3}J-}BE5=tuoC0{UCj@Q;_$u;yuoYXDuNrk6Gq)Z23hOxj5!V}BS+x47ORH~jb(Ll{IBWX* zLH$Tj{|drHuVx2~(tVxMq(Yh&OB%?MN?GFlC!2pqi)6loISSd{3hMRrh|%fCILRwL zL49t4rr$Ku@*waXZLyJHV)w^fPbQmlB>c6!bd(ku@td)b+32Qhn3fd&+*uJmk+Ni% zvSGJ2H{(%FK0?PYMbAeAwCix4Dkk68@-KGSOA+h|cu(u0irTpO7a9^bp;DF%z_dzU zlz?An$|4imO#y>!w5!F&w|`= zf1$EYe;PF83V(QMQreOMrOJllq{(w#%gW^@e|w8rKWHSt&wI)Zc)GD|6}7?)>2J1r ziYB<0)WMsG`C-$|6?CopZ2ejIQbP^u)7o0=Y&uLYGHm^u)eoBv^Go0#I|Z+r?H_Kf zvgp3`E2{LZ(rs*8?7uJ@;`?LDi|I%{v7j}-I{3e2;)h%K|Eu})duaII&z~HO`v2|x zx$OJ@t@-o&@4C#NKJ381n?G-%#{X#kWPtEY^JhLY#W5*hQW>Cn$ni1G?1W5$4IxV=3zvcvw3q04{^L_$NQ=uYshsZ**S zL#tY2oe)*b7e))1(vYjsJ>C+lur3%G@YjG3njZQR60<#o1jT`fYl~(q^|Y&cgErUQ z6BURyroSQ8><;CGf51*=4B})x=UKP_{XlF9TC&C=YWyH%sCfZ0fU! zC5HPK!fyoh*e1r>FY~AY<{LfuHIxD^2lOpUwZR@>lca$@a4J2IE=d2pMX%`%N_7Ot zz~C)GdFUcgPtxb*x0#;8>N(t=dn!uc`ikM9wrW1fa5ZBHejnYB=)QH0txt%o=e!rB z6~2r?LFayr1fo=)WsG?p_~?CXcdpwBZZVP=W7YvpA2kIfLA@n*FR)g?l!Fm5#;mjm zhOw%?FLnb6qSv8a4%R;b=sEL164Q|7Y>L}|`e*rP`e*p3!w>v)skZEkHRxz~%m`4o zhpvD#3nM3m28YM=7bu^me;sY&J{&{0YzwK;pdFX{uW5kSy9|`kJenYAe@oiPm{QeA_ z$Cv1^6mCmZs;`Dsgxh4LdImDFTZN5a077{x8k~;9L#@%32PQ~M@;uB$?*=clnYQfC zJatw3oyV2x?JSRs=t=U(m_bN_;NS_sE56P{rD!Xguc?F8RF0250gPqGMt0t7K30YU z`7?y#e7jDIER_W|`mlwXtVI@J%Qj~JNLtnLZ=Vc}4eB4gOx7X*|2q1zN%@PvYR2fi z=rdn%Y(I;-fE6oZ;ch+iFJ&0K_c(Zn{|>b7XPaS*@B^fUbz)oD`mUYXVO4Eyu*a91 zGBL-snxjhfUJ4!_^Ae{j1|BMe)gN_V4A`O6XqY$JvY!rvNLkq+NPp^~tmp|E8~|W1 z@hJ{fKF8^ZQ{QEbcpAb5Bkn&T(GTy5u5&8Y?}5Rw=5Px-o`S(B@p>@jvCPd@HRDpO z)6Git;}~9TRAvooDa-FyD8>|3)5m6E2EBzQ0XJh`gku<?5BHZAuA2=E-_Nu=$Nd|l-6uhYVL+##zOoF z@kQ@0xr6N+IbRYS9EJV$RaO*}B$9D9H*ev$oY*nrEW`agN%YJHk(6Owb2+f#@QBD1 z;}se64d+7!#*?%0ag1VNopqu^KW=2+&YF#HK)QCcym$px{R*OrqRI-sMh7u&B@8ii zcaXVo6Eq7sgb)o-TV^@Y`dGAnQ`=GZVzh{H`~YoHG1Z?j6UnUQBs7w=qW6~|PJ*aK zZ!S#MjA@9Ic2^!M+>M#6ImhBSgIjP0P4N@k)}t||9?nfG`bpDIC@c1YGrPstj{L$1 z_q3GiyZn1T+Qj~p%G*lx?Z@_)c(?c4tT!Lq*RNUmN1amI6r8(lqG=Zyb((QG>|z}3 zVzW~HHQco}%6$vkP?j%F1)z^b2d89}#o2{DAp3+P`dpK72C^Ndaw%lSHfpnPMYbSkF%MT{CL?cTR%5~xZu7s=mkerl zE7clm2J~oQd*KIxJuR(C);N{R&@1dA-0~w0r|9q^MX;=g=fUBnrtc|-s*JJu0UUA$ z!kb-XM#gT;%upi8G^MnSHu18so{uO6j*k?^i>-xLKM+~qXeo|=f?)dtus*P;{1BOZ zX5JM{r~$-KHRF9~zReU#S@9)$5j2M018kt^U&_iFbTSCb4ixQIRxA}g9+wp~t|-uo zun1qC0zu$F0!8mCD=%j${RR9+dCdo*yEJ3sNEmr<@Cru!Wo4tXVNMH0mCQb(fj!Fd zJk$z|y27Va&xLIT^l=n1@!R9MM?N%UuES4&Q|#=O+Osxy3RLUmr^s2D$q~F&SDxKQ-moiDb@ciX1IH}n82I0 zWBZS~H^4%%to@xsTr{*lN|crBsHw=!?h6C`-VGFesjOfO7Q_NOs*T(bJl?5AW~)aV z5|!$w+38~+gg;J1n2J+FIS6k(c)uoNbuMes^z-4l9GGODQXf<}5gVJ5?oo7}3uSkD zeQ6PDx??5Kq;n|eOK{ZC-c0nNDM%J4B9n{^U9wWM3K1E6)#K|4d`t8BF ztFp2QPBYr$5WL<8jS>WtVpoE`#K>F>_NBDo6vBG*%XApW_LZ0}qGYqSCSX+8O+odb zp<%K%1i~Nv7#JLD&7mE}8F#R#X;DG|K3U%*oc0vh-)`F96b#nx%6Egtm_BGLP;@|9 zndb$&$Z#0ghsuhx0KoCUz-}@PtU*`+4eUK-<#7*6I}Gg0&|=fTrj`XpWn%$bB4{(W zj3eiFmF3$(9vF2MEGveRfL>}_REbX37eg8?GTriR8O6;N1L{R70{(hS`a&VP@>{d!Q7k3J|jjVZiae0jzWZefW9G%BloOGDZwS zEwT8BSOd-W0AkOrUWc3GzgD@!z!$E(^PQEie1GCiN_~3Js^$f zaEbo@o|ck+O|fARJKBbzH8xw!-UHD$xrN4jQ>q6FpS@pmW*&oiA(&}nqGxj6EXD-N zj1o3RJm*Ie$xP>LWAOD9WQG&1hSDUICuznVo?ygP6fAuajFe=xVWM6G z4q{5qL`I8@Mv#=*0OmY@QwARrhMBTBy`3)w?v)`#rJW)^cJr%7bpn~($ykh&Y08|9Le zn$d2siHt1>G_s43B=b)wqrMs?%mR2WJTob(UvgM0+8eq_8+-&C&>ol=BBl$^@toB3 zN$@$lG+}%=mc=AoIom;|?oF3KuE=z+#~Aah$YwN)5MobDO`B5loD0U*rn?_v5n@Pv zA*R*>OtJAuXQDHiI!lT^S5|yVJ2!G3AUqgH3YoVt$M7ZMGJ`wa9TIGCrp1u*IBn0k zBP&oeQmHvh1a(VQO}-qZj>6qthYe3IBU9DF_M@9Qn)-X@5NYyG#E$s^1V4l8;ZB81 zDMEkedz9)eT+&93Id(C0Ree8w4xZrnk2Y{qkO;39{`kkB{=QI((8wh~28~%5ttAlZ zh*G_go+}dc!l2y`fJ-2f(iFflT2sw}Q6nB9=jB}U0*Ix8h^>P1fpYnMwiDF1p@EYe zf*>C5A>blvlAe;(+2BgSKjihi4ttmOe8vC{Tlj%sTT;`g)J#QriMJ81Lm$%($e%@T zSR-Q}K#lhN6H_b*ot9IlwVdQdZ!61Jip*9ed^a=l0cXpyA1~kKCkZxaBVG~2IlpDXA=PJco$X^=sW%OQPm%A!DG+*J)cEZO4wop6K-+o^(As0P^%@J z$<)Wx@JEh4pUGGdo9n+;2Jeha&eZlqBf(3uh1R$)lbguHNd0CsHh2T8_q5lbG<-HhE?hTjU!;F|SOE70RZ|=^5U^xDg zq}VIM55I?lPkm49N(9%DjZ_cptsj`xf31c;^XSL-v_xu!em+;j2VMFu`2;Zc#;K=8 z-i1AEeN-9T6wxwEB3DY;+MdtD2jzggXQJ`&KK53`*I!^53SpQ(^i`@KhT#PDedc<% zD>}G7wj7v%{>?^6R`v3khps7p=(>njB5yvOY)5R_A|CBBvNveEHYlO-qpfhI! z$N3Lh7>u4-N4EBQN5^SCXFl!=L^7H+$bws~{8YmNqlH_w!rfR{xcD#&f4Bo@H zFyMD|_w}OvobgP=_8XC5V@Z~^rnpavN#~w`;@E@qu93`SL0VVlJ+7xZMQuE3i?}vx z`eL-Zm0e zx0wdWiT1fU(O|7dv^@v0B(?S@eb;%0Z8T%)S2zMZxxk7MKKLV6H_o%vK41+T=2^Y6 zlCJ@AYqOjy2m>JoM0PL)D>CPq264+Gn7&2smXQ#5Wem=$Odk&4dUt`Xyx3684#9X- z=F6lC^ATF?wRpca&KFyQ)9!#A69KGwq*E3SCVS*qJ`UGjgN~%a4`Q=KgXl+5=53q&{e8yxpb`u+09unT}c3A2p z>~ayExknLSy;X$alScwE1PCp18MY;(_k|W=unU3Un!Ef$c4O2Xz7XCYSO{$(_Pn3< zxWM&B8J6DyH0=Z9P&ZM-ZDM_(XGuOvuVE90Q2Z-G+$TQq7|k70(F&@ z%h8C|NSlCu;MiY-k+$#I+Hb^o6vy7i^H*?3y~)t@(aL9Ihfv<3862^C1m_ z5v<&%`$y`7AX0fGy9p6d7K%%1wkp-!W(17k+v!=_#nSz?=~392w&%0fzQT^tmL|6& z(7FW9*%dTgZ(~?O^Me>R1CcPd-bLFg-$wwxdpH`VAA`ZJe1{f{{m1e*nGwfiJT9}2 z%4}b<0#2dCyEUL^Y!B*}7w9AIAP>v&$M`rIo0_+^qA`nsS61F5cxAke*cqP2TpnU$ zK^1hSmWY~}Gms!S#Ma_`BE(Wq=3%TD>uD0^nuNmzVQMClfCwzhJh5X~@$B`;J|8!q ze}un)&0=dO4uivE9>q+;+`8tlQoRG-;HWzX2*kn@;G2VnyXkxgfrF{#hr}tk@`i9iiwt)vHHR<=c+h$HXuYh|#IQrq2EU0IEKsyhS@{&{N9BaUOsP)g zkp%Y~V%L8UDUD0vA1;M|fT#P4@wqV(2NX@p$_1h!^JG#?)GE;mPr=4yQZ(}vtWl|+ ziY*T&XBLoRB42=-fl-(Hltvh_0 z4o_wLl3EI7h?39ATfZZpCEQ=}U}djpZ<2@It=xGA0VFJ0S$-aB21eZu9n3&UK%Yt-DAhsMr}In~eZbCFFN@Q|kL04;dRUA) zaH?6N4xH+Tq7<$cjup%P`a&Ow@vH#P35u{Mz)73#a#rHK1@~Pjimj(YB4c*JHlyFY zV;-bGA(qZ!=weHL+*6Fs^8y}le}qjEw-nr>^32iPmSq+bd*G|t*UjKiEk6bjF}j`kQy)k$K!xXa!^oDg29Gp=cb7lQjS;~Kmmhy4Q@ zf*)#hX-39LF)ZSEL*ENyu;Q9#v40pZSYwBPz30j~G!E_`W-%jray5Fw-YmlYVO#;_ zYQ5MzzmDd92tPgq>z#F;9dUm&400k?_P(u;c%OMa8#`!Mv!-7GrCdQ)1+_=rJu!3Ss=#!PRc!EX!IX{{M*%oEyH_x47EgLhuy2C`b!@mB<2MC|B9F%JSGXzY zx;pH#mxjo6Yf&)Q2(dJ5=L!?M8A4h8G495$93d{libNPFHo6GBBdI@}>yyeNDfOJZ zHKiVCYSf5!;FRS)0{Rm4^=>s*V%s4f*crbBpA$;;ESy{gxw{9S7fe3eI9X~wM+1SP zHf7~MITd(jqt8-fhq=VkSR*%keDrwYEu3i4KZU8+JVy-<9{MsYF!luU<~kH{okYla z3nf~4zu=Y)T`elGM2K!C=wB^Hj34j4;Q89V=JPPS7bC^DJiDYTjHfsmuHCbX)5fz zGN$1b<17u^YLMZ1N;LHYQ&-}#m?-0J`XiohVV^Y={EXBhCWG;qbg=tY&W8x38(d#l zSA2A(O`F-aDq7!FB{K)NP+Nf+CSn=<^K$SlM8Q@s@ydF~jxiWZrq%1Qs zJsn3HQE}SSEKbL9+*~hJH>|waoj`@=L6wtBnuw4*#?{qH{9CIEN3Fqqq=EQ<#E@rXE5MFoG zhsW1tGN zZGAQ4;mu;7olbjJi%`P|;`I?8?Ld>(!Is!><4tF=E`4{a28 zOMoV z*!PM37tU6!O>#f?PXi(7&8Xd>^HyTUqGku?ePE!4uUJsT&gu=ZbFeLoj&4GCikg=k zW&BXx4YNAt#19@CybRif2gH{8CGL?Q$4>>mH@PP%OBUgGUAOh`;DY5 zWy9noZEniF2>shzaNeiXJVt7~yaoT+@mg?JXM}|}4W-5eIBG`8S>i}EuCQ}HIPq0Q zn@d^2uM?5;C@W5yxfEsPi^w%5&@>vy^Kbh|;+vz^M>S)Z7XHbntUMoOctI#ptN+r; zF{<9px{<47(O%)v)?{nnjB^bH3YrXoUj!da_4g}dL1T%EwN7j%htdl5PffX$4HG=U z$Q|(iUx{y`0^Y_zxDgLL_@ph$gGAw1XjAx#1D;qGXZBbtoQO~4BYq?J>W}3S*Tba- zK8o2E>Wz1os(%k^yu=hr3m;EXYKqX_CIs}7U-#g!0DF&mrFu0b(@!A0Zrwyb+?bFE z4EpY20n}(~Q0M_K@`X=0E6?+X@62;0R1VpQ;7Jm1uC``c`bCe?(@=$Y>!ZmZ9{plM z=<|wN@%~i@Gw`wIcZt3&PMn(CVdViMA%M>epeFQQb0Pr3BUrwzhyif;jf^~H}~ZuL;7KAcqtik5bl802fE-<;Ya@MOIe)3T1v9SOp+5^|%q zVgg$6hhvGTq57{v0DW`bWGA@+oR! z`Qsa*!d^|AH>H1)ToNFF)tg5Fi+5&Yn;|)#z{jeA>GHnljB@=Aesr^AhW>8hZtP{h z6|Wp;fD)D)x~=eNX<=Py;qLJ07rdMn!hG><%0v}MV?&IL7XouL9>C*deno@z%+HSu zBeP&j+e70tZj0Vy&Bc48yBp{~{Fni)A9lw3#mY->z+CZ;zIgMtmifXu3xZ!L)id%+ z^-`&IzcrpX`)s#fapn7unr7Ui!VALw%=9NlsV9g^9z2TIKZ2JiGe(b$ zuE6kd#eYsi@oSv9cwK9xvH@W`zA20NF=dW>G$ptd&rf7B*1Y?`6EEVZa^*AJHw5&r zF*=@Q!Mtq#eF~6;-%JcQ$SBM9>(^xY^$FR~rDp5Wf3=vqi1*n;Y5^O_ymLf21;H53 zenTUHP}$H%Hq}YB3d7$ZtgVVTIFRgArH1=EBa~MVnfViDp7JOnwl+tosCxHCyoM!( zJo>(>9r*aPE`W#0_UNE%`ri6ODS9X`+lwZ|_s@7x5Wqx+*u%q7XSmI|3XDV zg8Jcd{Se+vhTTszMi0aZV=c_a0Hsm6Mlc1nBCzzCqMr4>(kvhgRO&o;*;Dk&dZCMDxU{qwpOBxW@5?U zD&|38Ez1b8;*b98CWcO@3X(os{==PTYyc@Ieq9D>FXof$*AAej*V55~q3lgWj)$ zk=qapd>xSg6@4BR`RQwL)b&+LO*TD%X@Mn1gc8#HOhnMAnF55iY^!Ns5n8Thyvh+X zresIgL3lWh&Tl-GnoKI^)bBh^d8_Wpmf#7+)J9DC5hNC0sn+$u{^qdwfYUT^(MI?Q zCWrAxr;tW8Y)%mHM+5(FW`{X-bdT5()mkGMnA;uW|Au5M_(ce4`b%?!1IlZs54|vbZ|LvM=rxV=w_{YL9S4;kJbC^}o{!x_B>Ric3U4HA_j!rLI)$ zgZ1VTWy6vrdX+w8*XgkQ%7(3Yu{2N7Yi>rJK={+c@JThpO^-)5ckyDBtGxoOa?W@L>!h;!1X~F6JC6kv0PBWPxn8M08$kFgoC;fZ?i`?l6$jCTWb5A*LCFr2^!9@XkSTKyq>%|EJ}%q08?3d9gN2G-}} zebOnIpKk>86XkjXUW^SG7X^%k*xTSG8>1|%+!*UC$Jq#H76XPrceru> z4UW4I%iW@uC@<~8`wiT_O`eoiNCdx*nq!bfI|+Z_@f+pBJi&ZST~_Hq73Eu?mDrd_6UDJxCHNvhw{Ft z2q<@N=FgkQ>hZVlBuy!84&Y^8KyVbu?M4pUb>eX2MQnTyFw;{XOZoQkh6=xO+t>pB zmKF1N+7$j?K8L^8E#U9dRgjjM=WDIZ%WIK|@vD9<@_61zC|}b@=V^!qq3`K9qvM%; z5V12J&;|4ImF2rYAH++Jkr(sCDu@qNBdhY7fsHQRh}z4xG$9Z5Hvde$qft$ z4u7lM9n3rYl%>t>6`FEu{ZrJYs15~hZm6wL?kUMDz;7_G7{Al=rr`I=ygB%tm$v}F z&*W7>5M*A=6Pi=*`A6PbU}E1;bNpx-5kvzJ_N7`Gm7{fy*C+ z*Gbt~KdloPm+LG?(0H1wvpo4UrRM)NzycTkw({w&PWkW<@H7|nD=r6@<#q;U;=T!o#i~A`uWvaernlz1Q%;?SK*$IdkXH6xLd5-gR}`Z(^Uvj9{)Et z%XwE@G)(hfGw*ds*I4-$q)oW1aL>m*8+S2omfJL0$S;%@-X`68+x1JYpDPVpbp6dY z-ded-8n$5JZF7g+a$DuCp+%B~tXSlerk77C2~3lQExvZ)u+S|Fq+#=}Up#El{97b# za(SsV?D`NYg|5Ahy?+Pa#PQC+2YjP(---N{NdMjauvNYT@8maGcND386VLbc?Yj!6 zn)`72$$KO2rB*8Uc8=ozEin*sWW9jCBj5BAbb)lu2GAna;5TUI^O0sDy%%W#(lzua zNTW#SAl0xcEJeBwp&^4hj$0Hd$14lds12!x)bkI}Bb|@53TYG4HAtfvpY=$WLf0)w zJ+HU7t1#q|NQ;qbNM|G6h;%8^e8ltXk$URe+nb3;D#6_LZH9bEJvcd;!W7>Wu0Sz+gdG@m1ql$JFwJ_k3Sx}qG} z{jSo8yL1))LQ0}zUJ^#cpG^8^Ku=o^pF)4Xvozw;R=G7ab)89!a?<}3^y@%Bl=MQs z6RBT}OV~BTRxitNv7adzXVS;(g*wdxel74^Q=v!Ifidt*F#S5~m7u%@<(ISEQASJQ z;{oYP;PWx3vZ){IqFnr2`vsU||I>ay4*FWq|4;kPXUc~`|3B@w3v-q9UHhF4d=&Vb zDLeYT2;B}OUy9$-?MAZ)!X`O0{+7juf|L<>-l_9;z- zK38<=llplWDFyeyF`7!B2iAX~m9D!4EBT z;in}#&zDczlJF~RCmX(Y-FvWm?k`T)PN&=@X>**0G`tb(m6z-TW5(Jkj>{;~jPbJB-(h(7!d#RkE`$ zI|rZJWuyf^&XX^|Z)2>zUHl&s9rJ3nbL#!BhRUmxI87nx5AO+7z>K6j(1F} zHrHCd^SB@HHeba4YM2R0n0Ow?-)tIS|8xCE1OL&${|_`^|GxnC{{zrfWS@mlB}L?F zLpH`Nu=n>Kt9)&jaywSRN3x>A`Yz@6-`BVQKLC>};to0_Tsy8aQ~TG(+kfA`E8hM) z{x;s`Z~wi18*l&Jef#h7)0OeE@%G=}xAFP6`$V}7^Z#PtWuH3e7Mx->i4;qRxC*#NieaT9Xb&qLXr&ie>3A!hX{8lby4XrrSm~oy`lOY7!Qqq?Nv8rCY6ZuazFM(xXb~9TTIgX8%15`w^Ek zVcfWjeEAb5%^2((es1Bp=lRYnC>U9AVZm@;{LLH=BNeIAp+n(4P2R>X`J`z%7~l*Y`IG`mo?Mmr4K0l{S6zB$H^j?HIe% zG3npB(WbZmU$=F(_9Fm)i9E(Sxn)~l? zc+PjYV^46oZ@e`mB_2mU%eCMT63<2~hpvUIk#*$a_zTrsi&)^u^>~7?a97BLl01*I ztny1yrb-S+;#45Ko^OHhdj5c4_X+&C7BidVa_!}w*)@ckaM7j9F4_@98%WH47fKzj zL_dIJpX0j6Ag-Hnp#06R}v3Q5;8gmk$s&kCfjk4Q$zcy8i4$TyH2xvD3PWgnZA zS)Q42ysl47C>x@Y%IjgD-F(N=6)j{nmunQX2KE1jkerZ-qEt^>f$JjKfvj>nTfao) zA&ffr#tO;hm(x+?$jwqKDsPosW91?N`h??mjg$E_&ykxib$bCBlBV-q=`6JVYoy)f z^MT4BK7*7Q0%Q&ZOuQZ*p=N%MA6KdT4`3X!hbKo6FO7-A-HVAQ@j}#bc-%{n^pJUW zCf_7e-SU?xKZ~-;H?f_ws8RVQYBcLRmfuXZWbqVIzC~o6%-$-p)Tw+MwUt#UvQ&0Y z>Q=s;1iip&p~x%c0=aO#u6UgiI?kxxh+;NJ+N+5|ANVks(`=AzP6lTah8#2_&Xe zHzAWpJ_Fdu0JbrJ{0By?PRN&nVvsz;`K>$yWPNV1@a%T}nmE9uxlED<%Og=H9~9cP z|9i+C7Uc$TlTSeAY%$&kIo?i8^=vWb2dmM!HyJpE|K?bEV9SkKfy^L@$(q8~OqsT-nJzQ%N zJ$zvA>kawwtt+KHzNITxb&attN5<9`d7TefY$U(EPJ{voP zv;hk%*;qem%Pefm9EuEiD@Yr(uyu0;QcC9kuk4&;Vb|K&H;J8WVXJKHW5ix-VdvP` z+ljs2#xC$lypq$|T7`uzwy__OcD{x6Sy<^#cmjuXtkYcg!*S4D?f-07{P#NmT_AD1 zib6+VBtWMXPVGfojinWkps`kgy}NVnJtQWkPmjbPP~aAkl^b3~lHI*XBRK|=YJV@3Iy)mP&O$4)V&^*}t6~&%Mph*2 zjI5p(kR4f>ly+ogLX50P<@NB>0*4t{O+Yr)<4TZa3`^QF42vsKz67nNb!XlqGYVBI zZVpKi(vNkxl{-PVKmSu!1H z7V%l6%o3oG)azm5_0;0GyA`|f)xeBm*Bp5etlJdl`cuWZLAJ!nyb(Uzb(?I9!!IaZ z3v6*rVM8*XjXQD+Okpdn(vc8rEDGYp5}+kkz7UHNbpI8#v_x(I#%YF>&>%xfrxjBE z5(MsBFJ~(on7!>VWTQ)}uu?vM2tY>!7dT6kx{1)@@Tg7 z6ClYa&tXgV$@YI@?%}(jxSqu3P(Iwz)O~E~NyPmo@B7HxjfK%{`98Kh2_TzV#irit zW;GRIQ~huf)$cPdu(*z4wUzp>V6%H=)oSiBE1d;O`5ly*J>1J?-vqAjv+UAdj`Wc3 z0QoM1{2ryy36ih;9!sMDvxPd|r%)5HH_D!Svn1~))4KrW`mLs(L-BGT^W+(hJAt2T z;i=yzJMek(bjLlQnd(@C_%>wGY(1s?Zo9mn-HpDO<(MLq(1cIk28Qwu+5T_bbFJA-liTN0+{=a zB_EAX#OI=K=mTRcs}s2nO8~yt!BY%V0qp2qq9g3iGfxY>ngibkV3u&Bix5d|AtqR(UpMmWBDff`-o)lguF;*LQ@4)K1}>h9dAgM_8RpIHwB0Lv4QYUrensqV1Fp z&{R_{jD!{Ko-1cjE_PLxv(P2e*@_$&0N79;V22gR+_gcrLU|T4uGf&I224*#Tj})D z(s><0ve4NtNGE=%{w(@klbEfd0q*Xk$FQ4lNE|LJT;@k$H7KwTqt^8Yfa_|E*?;1X z|HL1dM%|afMqE8*uDc=@S%Hili!dJ-i|}*-=SX%e@~Qw&AB&K*ODsYY%_813Tmf3v z%f##XEq?7-q!@V-i*RdX$0DbQbAxP&W5*)4IH!+Arqkq47mLun$B89CODr=Mp#*j; zveOjn7xMNFvF?^n5o_70V(IcJV%>LYh;+Z)8ZXxBxDe^nQ^gXXB^Ki}uZI$JpUA;` zK(0Xk--Sp&u@y5!;@`#id5Dxu>}f+JM-TW^cW5NMhU06r=3dGu84>M;z&Op*yq-VO zuN{@;--3-9E*<6I^cL&=Q6YBrf1|S811_%tL^;AM_Yk`3BdB_azDs@OzmsmLh{$ZW z^|s~ef6tA20owA3>OrE)nYXa zt`dvRF*X*In=R}RAF#MC2C2NRqoE)hx(_&?Sh#~6j0S)MM2HroCHF&Y$95+%ZrVQF)p)cn%vWmE|cG_xG&yFev5YC>$c1DHWqI52BncMxs=V zL<3-s2Syo|X+@PkF|7sc<-9z~)#^7hT;+Sj1~H1l)Td-f0p6 z+bj`k$x}wGvYNXAePAaS;a5a#=z!O0TNwJmi0xcEV)J^w!MI!?cV`D~HaoD^;$+7n zw0X`7A^*)n{^@Anl>ZhXe}u4*|5hRYR=}qGw+VUM0bgkIllPh`X57{(BjYwxIt+^y zw~drlkS2s2GEBe<%`WN;&Dd3QVW4?*E?Uy4Q$w?dNhf|dU$f}%PYKPqf0dT`;XkDb zAhklXUf2iJpkTeFj<0TTxF2dp>fH-xYGx4;NJ%_OYQdd+ z3w~tD$q3i|&?W%RXR%#%uOG^6JvMUg7e)4Yi0 zUPe2MkWajXS+wJwM5x$=JgAuiyz_mqO7t_E@|R?Iy~IgdS@RC;b`z&iFxGr51JKlK z1myDaL2lwSv&`e=U;9g(ZkDBZZz8+dW|`{!7#tHXH=zvgBM>t2ilC4tOG?d83?4>4 z?JA0O{VZl*!j3tyLSX*^ttH;TE=o!4B1YWQ&mf!(K@*AdDQBuH@xO+k#H@L<$cmb` zuu-!n|Co=^tW$Ds!U~soYcepWK0{Mn>1FF6y80=Ek4)_)SpxMsK3}5Pm)CGtiG$eHxTW>O&aYWOW2i22#|gK$)uk3CmlW`WN68bvzqU zC&FO6sY9`aN>}-4w7WV8G#P3U`k$$Ghn{+YqWGrGAEdPjxQxz0?Ju@2yS- zw`_GLMkz=A1UAw~y}BDVimHwled?_!?WfkDt^TS9UCveca6C_a33Ugkm!RE&YH!Fq zNbL<(=BxOgSsJW90Gc7{SCHXsbu{M5IcfmC7^?O_{#^Bbte3;oi$PzY-Uv*gx)}1D zr~V#%&R0J~t>Nkc$T>pY0ZA@U?|^15RF?rWQk@0LBK3YyUZlPT*+!`oAo*yu4wR!+ zzJ@bKJqn%|t0Pc)iP{Rgsgu+KG*&OEzd@fiOX?m}X^_+dNVZ67H#GQ$q<#X)w@T`r zI1y=-)PJIOlcXL;L)#>EHIUmSbrsmZDXAmS_Z^aY5XoDT`Z#*?wxnJF%AH^as992P zgs{6L^+6=NCA9`Z?~&9$prLm#qafKwH2zN9`4lKqnU zJfIIGwH{jjCxpk~{7X{5M7<9o3y=qZgb*!~+K94`P#wuZNxcop$C7$Cl20Tx4?=t@ zse_=!Lz21_%K1!E&&P;HCG{1M#3c1wwD&oB3x%{w>gA~Lg``eK*_V>K7kc?hQeQ{) zuO;PVKSSJOD8o3kN$R^u zj!WtojKc{@oeyRGfc~MIKT2vX%bVya4?J~Q9fIUOS$zh5H)Qn<^nI1AwxeD| zR*N9+{U}3))v|gY^jRybmxA>JvRaLX9+cG#bnGEn{RWf|%W4^rkI3q3jOL@Vx(#wZ zCaX`Qg*CDoMD<_E>Pl4jwX7zfW51ErIyCfKS^Xng_?@g?jOza_tGR%FFRK@z-db7x z0bKqdtIZJbkFpwp>i#6FUW~)zvU(+Cc|ukj(B6}>x(3z%EUP}$TPLfZKs`^%Y8uq~ zw5%?HTK^)eA7fOWk=5B~;jgkf4%gmY7R8NSyrc^n++Ho2(bkuoPV;)Q=+Z1+JcTX$|~RN zZiRs0`32T7zJu>M_XUu2;%jwrrkYRE& z$eg)hIsKPx`h2-X!1v1O-;jQ^{H&m_mDA_K@Vuq+F9p0tPX8~$<1KitoPImu2^PFg zPG3q`v*7h|`aOgL@_12yqnv({@=X-dJ9F#g^h%0fE*}!@Z^1{M9+GyKVGrKtQvL!< z&GK%bV!V?%I2%nJN!~w^?+li1nSl6RR|_D*y=WQ5)M` zO1ThoC_m|fS!mBY750`i(zF=KdmIW$Dzfay`wz0b$b?kyZ!j;CMww8S*9|jF8f^;U z^Ii<&Ng889c~Z(10GB5BJjn*i&_HtU;pivhpB)q<+k`ycr_exhpH@+(dWXUZB=e2P$(=mQr=t}nfk z;6$smApI>&4M#9>8H9D@j)d4xAeY1@3vgTUbdMCM+A&2`>LEk5j;SKwZ7v4c=UAQi zAVnMwD|gf;S~iu=mmC}q*dnG+!Pq$-6qJxL{YzM!<8O(hgl4HO4J>*bp>VGzihLm^ zvEwyS;jC?-Uhi~ddR~Me>3u0|4^KqMET#X*^ehW>rRP!BEHT6IFgE=biqX>o)%4Nq zZ!eE!&YANTOOD>28wDp{X6UvBk|Wy!^V9dRYK~R4ApJUaypIKrO#dY-^%W91a*Nad z&JOuJThO{Qx7n5c1pC`hPy@b88c&BnnCHVody)geZB(hWkoAk}yvlLp&`&C3x1Ou-m1mQQ#Qv znS?%@(vPsDm(m05%mo(cNq?V;zt95J^sCwPkrtShUJ1wHD6&9bdWfQ5Bt+-q-mEM+ zEZ4A&Ctwb8jr<68oGWFDSJqa@VKK&@^bB}2d8OskRjH@Qk+v5pAT)XO?!jSS>=A|X z+rVVsLYO_xUbKkW$I-W(MHs0iA}jU&hN`{EBeOtuVC7(yn?#j9V=2o`V!TD2o6S0X zN3+8_Q)GFJMZYseGy%3dQ>f}bw^0W>Q#j*%M>x2Am{!jZHgGX^~F{PxC#&9ir}lY&al!mn`+& z1w}bNMCS|8M=I+>(fOPkB}YpNT|vK`>u$VNavV&dRYImR4jt&(lw5&IeXce!l-q1O zMHJ@1C(3CeEA^IX4i1OelO3!jdg5?&_Qc`n?1{tC*%PP8XOo+m?ISwnbaZygE!arC z-+{gyt5eKY3Sp`2&}wruZ@rFLF@*W(iKABJ`{mpMk_S^Ld_Qw+A2x}^m_H)&Ik1FB zg(Xk{z3BOWuo~%)zO#`ZL?eC1(SQFSxb;~{qcQW@Z2ZR#UOx$5z6CH2$4N6UT5C5c zZpXw=rQP|$oLzD%g&z1ay5rkP$&&;^8py4o?@=1HYGIbbl6^iJXb-cJ3`EX&xJ1D( zXKY6w_C0nvA*;*`(W=6K;g|RG4vOt?PBY6Sa#5NF?5E%#% zFqR>NCD>p>ZXkvbhb0&S31Km0A(+Gv$U?v*gplO&{->%=_o#c|^6q{2e!uVg-hik7 zb?VfqQ>RXyTDqr2sTEXkn#}OCka2|ph7bWE2S^Ci7%S8u)y7ICp{_(qwXsSyh#f1$ z+NIL}L_%sPgKRWmTrEMGJ;zm8sEiRYL?}V67$?ZWvcsY3xI)UH)__T9AexFK#v;M~ zCI#8^K7k*5(ue5!o9G(q`1BzZE5;w7zDyq?#(?OgbfMAsYKlkcLnyTSenh=FP4M`> zPm})iArz*3B^2gnNcxwkJ7e{g3HqfCDLMwE z^mKBEY)J;gY=L~Mss1@bXq2UogkHX1q3NDwA`=#X3kD^laLg)MaU5|VB*^J&P=@*; zV)b4`WRUG7B4YFOU%Q zUL>LSBolQW%_7ug>xamo@F)f-b=!K;ZDL%mm(~_Nc)ql@=)tI@UqZuugXqEZ#V9?l zwE^WDhfv_s(wm9W*#LVzEZIlWWcoeTAiRyl^N0`$)*YfSO!&66a{AYaK%Mp{(NhzA zB4T)kk`tk|J|SwzQ1VfVKtqR8Oc>XRzXc%>nzn>`@w}m83eac4ji_no4JD8C{e-;A zCrbOuXgx4ts5M(o6mWu1EYl{73VmXYHbwG_1zNgfqN=Bf3Vp&CrVEw{<8VjEGixYy zZu(KEAtJ|Yk*3HYQF<%oz$Ii-OTUWJp&$|L$RV+ElG#J;$f3khQ=VWV|H~Un zK`i~RLIX-#aUgFf#{q@lG7>3I%9F|pvWNqtVKMTgJfWM61CojQ1D`R|5pg}s<(#Hp zuk5{C*n4b89ku|=rTv8MS4draSHM9%6*A)q=;^5xSoD0A>WDCTO^u*aJs)Cr_FOSk zy6h47FZJscvL2dBu8HCgpta5m2kf(OO6QL$gbDLnTKrA7G! zT1eb0RPY_5cy?Hj!FeTdioy@d!jOtZzVNhk585m|>W8u=@F`C)=bDRJacN&qxTr^?_XCO6dPIq%9#H~_Y1yi<=6O$K5V4$&~%O~{h^%GOzBM@&zF76P-RpCq2^=*`%-PwRg2@1tBSr5*+ zSY>@_G5v%j;^{`Yx%G;uORD(Q3^H-|F`{YnXyenPI9hOzmOd|`Lj7$t+P?v*`9ZMM z;FEJ)@g0QtN@T-;sm6xwJ}}{vb5do0AK7j0>{BZHB(g7++4z}A&IbwP12(xp>GEfA zA7^1Fw)sR=P#-;)L-(2KLlR%LiZ0-0q%EP$sp}Ag_3_dv_!s0OaCezLvu7gDGamO- zHZ|jySmVVm^)3*7mys*^^x?>xRf|5=CkX%OKMQwV#4bywwOK8g81#wad@~oB8Gd-v zlS;8es6x-zAI8wlrKec6%%%A51e>3-0&9@E8>yT(Re?!R`F3!_vbdeC&G|slb3s=$ za9^*e)u6thxOaknOwn6G|BEGs9API)SJA_$3%KRifJdGUQWM2#!a!{RnPTca)bv%- zVEmK#CFx+tCnW=U*PRFd@4y@guDu{W3}W7el&%r!RKrwWoR>}3snuzJn`&r^n%%3+ zuPLcv2%Jf~yjEf4j7;=QD}G<8x9N0pnX>;-@9xzC*@94L;kr|-63~?b#W`CeVV0BosNFQ<1NB2 z`N~`usA~{*(ue!d8QU=xf{QxiNf2kz-y_1`aHRCVkj^PlC6?slv;hTR1$q`iTe3!F zh~ch{xo0TK-7jm?{a_S3`3FSpTK)m_VuvbFhZsno*;y!YWCC3K7;^9RBar7bo=TzCu7m@fSsJTA^Ff#AMcV0He4z=Z!VtN6>^%wP*K=Km~Oa?j$ zt_4#Nlj%c~;DQRJ2PM$Z+f?bAeB8J537_bUEM)VBo__5IM@C?9J5LWb}pd8&*^tu2K?C2DD_*bls0FsqJIQB zNkRzJmeXn7Zv};krn3wYzNp*pbg-DfH}-Lv_Oj5D*9^|zN_?w@CP9~ zXQPrg4_rGS5tXJIhc=>Ge9)O>5H06ximMh}cQV&KHdm@)2Z)q}rp+0gq&-^B-Ks-r z#J(xT2`_$5(P_e_pVSIvd@2fSIWH#^OOx56*l!h`Ci402VxyGuG>|Tk*>WIJ*sap% zlP%1N)Abrp>Zce_n5h>`<|1gXHYQ^vma=2Ka*y)?g5>z2x}cD^PB}0N_(m^|=V-S* z$9oZo<7n$M*Gu{7*P*~TvA@A%5m*`e?nV!Ja=f(XNdG(Z83*3QUa@1wMpYtlvQsFC zw3Y-%xy7LnwjdJ8_3}zl8|`5#WHn-IQz@#E`uu2!(;i{g~fJm-rX zv4TBc$fAvgBvL_%&@|}(JcP;myJh`o!B$Z`{V}QsN^a+RHg)5uXSZNOn`Eggtx{JB zHY#wnETCyC^wZd}>2>lfmPh|)>Jxn4f|Kh{Ar#CIKTNF?OWW6SkQPhXIxHga)XqXE zA%1mUFP63$6gDnUPT7NA)Hi!NAS3fi&>sY|pNIuFAXSKk4tCUN?;+tw*iU|K~6r& zDFa2kZNdKn)w>$WyaH(9O+jiCQa4a4pHdx2J%?0a2f(zY0Q&&W2cS<0ZSVi)mx)Wj z?`iO6{s6SQz>xV2z|=xWqMX3XNZo)`;MV|Y%K+X1xS7CT08)zp{vBWwhDi1_Os(`O zP}jea+GmZ%LTWjv{ufB#I3%YcS?ueFhcC$FwBz3kN?<;~8vxl~Qsr+@*CoV8H!N;j z0XfATDA`S<4v?M%sr2WHaTum)`UEaQ&Lt%PmjQeO0M#EyvA`;%e}r`D2J|g`zNW5$ zjmVi;Dro-qiItw1t^vXC?~l~&NIgKQ4V1bMsoxrnY3PMjI zy(0t0x(Y%|=q6E-66ha@vi*i;7J?Qh84Uoh0hHGQWUj>5KS(0+1v-!#zZzf%Kofz> z08SFP7GO&azyW|`0L48hF#(Y;aO-f~*{&snlZ<tuFuJ}ORw!2&-+a}KYEDwlv#L(TaOD1QYd z@JE1|=L38M&;_8CexSzkTvc7b1ED`hmOE!Ca{fuB&jl!s!V5i%W#wbk^*dA>J-zT# zT3dI6BNPmQM>1&F07%R98IiWh@ z#HZLh7$KdSy%XdwgB-XV;Ex3M15DfqrtEPAf>|q8*L76j2e83~lwHbXo?Qb+kaZhn z;Zu@{-U=$;%SUY0yI#61>ipfHZf4QHIazy z4Rh&&jf%QHjPij2BN1IF-+zkO&qnekBm?IGEZqz+6QF-H`Y(To-1Y_*f$}~mfg*tP z3jits)&Xe#4lo7QBKb`uWvU6O_lRo?z0v7N}Da}lWi<5cb{B)^Jeac~%pZn8nS8I<|hss_FZ@CHD(FH4Bg z=Bn$nB z0XYxgeSqu-7szU+EtJ>CNh-bXX5*Kj#Pg2az-r{&i=03m!0tT&7XthX0D?DAh1-yB z*axr&;1+=59+3Y?V)uhG@KSJ=hI3_YUs2bTZTJkO99~ZZ&dg$NH2=(k@mZ+?#ny>};{Ord$6{ zdF8EtdZt8Tx-%?M`sJ1sV$#yTN$HT_wC@Z*lR^sTck%Y3_(%&G> z#ohZ?z@npUP z8fE&4Q1Av)hl(Ue!S9ght&jdd@*+{DfU@kXplmoBt3{%$0_9Us{6qA#r4E7=Xb?)!I~aJ9^uDBw?pLlad8g{ zKbHgckHCH(*o*z=V9P+1sc^L!H=qKd1ZE@k4pM=|06TA_mKRE?i_~>F6-ch_n@?E|5yUq8MLL*T5d+?E5-cz5;L;04jT*DqD~Avq+adTrTVQSX~3n$VtCh z68*k3@D2cF9Vmfe0N*4q24K)F#8XU@?+2vB?Vw!&THr9i4+wl0;IG70+ykcD7l8CQ zNQ)0Z38Dmkg4E4O1zrPKb1N86fxLzoe+SANpp>3cp149;IB*6zTMmNdp8!7~(0?9& zY1T{H_`T;MJp$?dNC(CNJPlBs5Ar?|I}4Oahrn4nQ_0<|u7Mn6eTlO0Degdl-($uK zyogS_;}FITJ?eA8a*>PU2!!U>y_t(a^WKIf(+Yso0Dj5|M3B1tc4{_KLl=QUzliwS zHvn1z-XpLbVA>s6j?pyq6(#otl3O*jcp*g6n!gMTnY8YI2*6LdVhZ{cDNK&HAmit% z@o+7BglAC9!&ftiYvE^$Fz98KJ1s z$s;NIAKu*`mZ3H6Qk5m9ysn{Q&!OFk`f1M*BS3qO8vy*oBG$8yBZW^1Js;Mi%I71~ zbMes3pMdrjaT6i%8dBf83*ag^Sv{2Y`(7+~#vut;8sP*Pi^uFoz)?ndN} zyB`_F$5B$JlJtv$e2_{HDaO~-HE<(x{)wEx?EvQ;C2@Xwt4*L2>7_`Q=BS~!jfdba z7a9yzeglc#I#Fs$~JOXh21E~BGWL-{K&w|qb+mJMD%(lv2d21O!fFJe7)qVsXc#Z(ETpNT}t4)J$ZHHBK^eu!&Kuq*Y=O$pqk<- z!c-$oNf=mxp*S6l5RV1)*Ycw19R17s5|C1jOFCpd1I|S0T#o(_<r~m(R6QjG$lplvN`=t zdNd-ePsI=zxK2EOqQ6Nj;%hI7>~H=KgaO1C(H|cRebFScg+4GJjKm{lh4sr|>wz^g zb0TF@m5{yD1KpGIC@4ls1M#FRz<0lt zPm$X{<#yl!DKFvMOgV<{)RbOu4%9|(#077Jp&ImW<7><~~j>s8~uNSqD&dE%b? zy@DFleDos03D;3QCvT(Nlhm$PMeeGJVk`X`y{cP3e-d7`^mFR9^XM@?{TFwF+t`0} zx9PW|DAM#WBht5_?A4TxQk!IY%)jWQzBO>-F;e z;6cS#QY~BjDJl?)hAi>+s(SI)4XTbqiz`Ws2BGCiN zfbS2b9>Z*<_lWhL+Oh|`g)|bnWH24#)o|4U6dem z?!-6DIZHeeHA}Ba+5cs1&;s`-uo7FhU<+7m#{R>*vC|PRJJRpME5ej=^%O=Y5F4(o~PML_b4kJ+CAe% zYSg#%4al!U{*34C^q(kw8CmgOod(>?Cy*9>dRX+S{~4r3pUU*zNXuT6X=DFQs@FJu zU^n@#Og;K6_qj~}1?d^TA`dwtOuYEVNIypD`}DnN9ceed1ARkp?V`c(oaovsiA}^0 znSKfB@rS_nI`$XS>#!^mZA*O)sS7mx5d?DR9Z1c*WwkWze)#)O!HhBC?f&Pk>r+hM zWYd>Ed-6_gBDyN2`_!)f=+g-?EhnZ;x`aRaurD**J!_h-jT)h4yrM*kAvF6nl^R|n zD>?^?OLu!oxZ9`DA}~~Ck`|~1hgKklR>>0NSVD!Hc9ROitx~#sC{dHrO^&6_tWg5K z4FRpF0nJG1exFnhrF6eWSFpaYtG|}PzVrq-wK;g18TnJHc?MlSSG++>Kiebz0zi*) zx)0Qq-Uv1pOS^f02P>Ee>(%qca3AFvPQ=K3@j9?`JPRmQHIMYy(>&ycdT8ELzS zRLzVnlsCpR5mF{Tk2C30=&kAE&rO`?q24J1krZ13QK=@qG%4q85Hj`4$Tt^xL>Fpn zhzTcJ>*aMP3h89`X+p_GLdg$6lp|u1sC@BHkQP3b>mi?dkkZ2Ab3HTy@ERX&x@gv7 z(X1^<&k!SMiHAmz@dDCfMC5yDL@Yp>Ji5R`tAst25>ZU1hx`oOV!SLB?aHCF7%wuN z`y!7QnYPCZr!ijCZyd-j?}2~3cOsruz~WhkyC#necZYVFTVP@zk+@Ef79; zsq0lJLZjiUqMbEhq0!JI^!hPUc>B^iQ9vtJ*9TBSdTYCA-Px}oKk#Q|cIBCP?9=v3 z_@i((_$L$%LeU8NLn>O{N70o+(Huw|-vhQ;V3X0d)q4b|jrkSYel$2176aZC^FWU$wWp|DWQUgEWLi{wUCxUEhjO8)VS z@1pNV9!7`bFG^1)CoI%;Dk^g`Kp#o#NSUNiERtFt?`pOCz~a$D!)T*(o)@Q?%4^Fv zAOoMw%&b^veb%;|d0Aa;&D-Y9$qdUs?0!K*+l9?-vFPUZ)`qOD?VT6KI_l~hvKqF< z8#>$SS~Bpr;V)>YkH@m=8ylN5wr*}{Xvx^v)!eeFp)-GOR!j3nBG1mu&J2+7=)5@@ zU2PY(wQp_95Pw`gqp7V+!=DcG6@-1+nc1^5=VoX6GXuD7p%2ri3>`7Z7&>O?F#L?( zi!Sv{)&>n)3=%CZbz|tDK??^h8l;cF8grUv3>`ZJ%gj*#L@fcezv4%19WbH~zd6KW z%fawYJqv=V#K08Y7CLA|LIQ8!Fia_!N(`YA*cU67ex$@%N@%~55yawEB~)@4?h%e4 zw&4@Bk`Y-bJmPG9>R_Ub><0=~qDprZ!0J9zUou!WW$NIP5kAq(bNX3IV9Ae!)zow6 zBqT;7p>)OKITI}>#YqfVGQaQbdd>~OJ%k2|&G3+sr(svB><1z5x>GtQyAtC&I zsO|64`N`*m^V0or;p@Y=`NQRS!Ak)}vjx}4#KCj6EsO>a-qt64Qw^STc&NbXX>^=x zb*Ams-20;w+!~Vb`Xjb9`OVnAUOp~SknlGaGd@8K%Hc0JB#QC5%JHb0V2_)L_R#C& z%9GgR#V|=23R7eTk<-uCrou(1Cf4H^zta+0hK5dOshGR0Qo`5!v}>kn7c5Kmn5EjK zk{MEn8m5_24vm*NgXJ*FO2@eIXKECjrVb`5CgsHHBwKbOiAEc>>Hj*noEiRO=a#NE zb+8Qk2_6l9wjB}PtUL_eELq3dy^9cT_pJ!xi4#g6heS9}oCy%r6MY?_Ju#QOS4|9) ztzO13>?3iCttEL`x{HyA+0=xp;l$+AYU-k>hzUVxg7)py*I9|HE-z1G!>rWWr34?a*GVGb9AfOPay0sEPry=X5LW1z5)wzD zWSe9U7A%|W0fEKSKs8@t2o2Inc}xgghr{jEItqg(!Nqyiq`VjJ=3^^~;BV_k$&7JW z=Y_Cps~J=)ES1U2yet9W%znA3!=R9>z3f3)Lk$<2%}$UF&N;T*s}Z0k6$}E$YI43< zL_&caE<-I{fP{)O3;PcDMYh_s^vosY2;|vx3LcAvBVs$ZL`qWi=iBw)AQ!>~10i4- zdS|IUVRP3Ps#Xa{T_$S6HUqz0K>JZgF|T%)lkLb9u$}Pm6;@9RN9q&4N)io?TjA1( zc+^9#mCLCbJll~VQglZ}A_0#+B-YSJeo)#`G?+|Tr3`~ckkTPLxkLn)uq8<>r(`^d zSVYkPNvw9prB#wEafz_HZ>Yk{-`V9a&&Qg9LsP9q7a@-HTw_UBdVI#3At8YET?7Ar za34s)?VNKk=M8C(pIRFz$4^9XRQF!Cp1@S7U${4r(_^E;63|`aIiLh>n0o zo4SM*g4p^c&e@X^N6h2|Psa$wvOsJG<#h5nu}o>B!q#*pQYB|7oj9l^MvYks!H*WR zDuSq$tej6BffKIq@%?FmX6c$M33z=;AY!laE@Fc%uVD~74lR+FQIj)VSYmW zNaoBH(-4I}#8w&>3$0-xMhb4jN#TiuF4w9LeJjUmUf*$u)i+-GO==tF7;}nAf67p6 zLDchT579W&|A9#vx8Fg*opDWaV9iHzYcdEJ^g$7 zU!QTYu|2cONHuFb6Gtq*&e&3F3@kOebB)2dM!eJyHobpie`E4NBUozqYmAtA#u$=o zj53ECshN33ca4$iGq&dXjMN(AZ7tKdXZJxP9?vQ(E5FDX-)LSS1oZSb=Jpuh+MQ{f z)M|{ajW^*rF$e}_Pk(cGf8$r$>C(IpZz?lujnu{w9uwB>fu0`iN_@NQ%~tt8XlNYi zvF%`A%b+lBe0xVj3}%OIwN=RTXt;Ok*6Dx12k-|~qIDh3|1}rjztm_<($nS#&_~;I ztBmb?3XSbGf!<G_p&L)MG7WMu&M~<*$vd)5f^?9mbCM1v4fuEblfZd8X;c z+G9ol9?)!NzID~B#*Tv@?tJSi{KLCn-@4A6V2tsk>*leyuB-p+UUP)e?wO^(w(#Iv z=Bt!C+morU-LhxN`tq_0!@EcJ_BLTzI^A~l_J6-+#kgdr(k`g$u8aPcZ4DQ~NXO8l z*ny!(w`l2OWat&;^JlLy2Ejxyys@Ly7};}|F>udFBdhc}^ZGJl+nygA<&8#O>1Jd2 znNgc6I^Q;qYvyU=vE643zZrkc=st*lnQt52J#QNmd-6)Ujjfq5?3&Y(bc^1@wjXJ< zCfI(YF)GpagOu&B9zb4w1$yAKY@cYLtc}g_*#EH@*GF<}I|NgVwECjHr9IZwDaIev z+tkup*V58nFGm0@+}ti>oi$!DNac7HagiaSUq^g%XG7g4rpTZvilcwfQ4H}m9|UCC zZLxS=yfG$gXl<=iaa2i?EVu)Jx|!YX@mRdGxvh!mN(|JfZ*OaCt7~nLLUZZ(Kc3Ot zwwOGlp|i71wTB#r-wS5kV(4Y&&+}FzGG;x|yUvLB7+=%Pc#6mP-e4bM=+iO6j|@Iz zjzsF`v7VBq3}gGjNB35Oyzi_t#zfsXKVEUBYehaFi-#0%regHK@iD(&hVL;=Cdmn8v`5H(Y1AP=X#_4q`B8ztMS0JeBi6jSCdDvnOfnv-HO}g(ea86ElWF|>#V0oG?KLn_ch?#}GfK^~ zVZon_=`nx&WAl(Xa^L>_<(MOl#e0lvFGBF!*RK>3UaU9wTx|@_1nb|&m^IJE_I_NO z7hBw0o>x*5>)vZTwEHl)9^7Q+g5$EWs4q2cjI8-f?6#8fvgKW6m~DlW6VzMOiTjcK zS1j{raXu)ojWK;@)@84)dZtO%{@QJMi}rOb+Hb7&G@|b{1mh#dS1vxYV9D|&W_kCF z&DZ838q70>A2T|0kF0rTQQ0GpZZHP+{IdWKu;YX=u*Q7#!}9%}yY&&h#$f~Id;a2s z#_K$#`0i8!u{R<6h&}T2F0; z@qEf*9gOvV~=PjaNLLwK~L`xd%2IqfhShca|N= z$TIFSP8jcBY?dxwSiYjHt7NZH=PA>T>vnmj=zEQE2hIK6#&GkrnO9;AI=J6>b?0H@ zUeCctN{mChYK#}V51S*6@28r38p_@-F}|@o7i*4EV_T_l`|h}LN^3L@?Jhl1wq#5G zith6L#&5KfvAv!tBV*m>tKYb9!z-0w*nb7g-_~RN`_2=_<(|?K*C6&+gxE{Ay>e@l8)=44~AUkXN{6 zVOQ6_{rLO#=-{V3o+BRJ=sK~v(^E7O3ePo97+=}xc|zBXKlg*@9Jr`wb?i0R^h>)= z8lUQ!#-3fLSMM#m#OTO0uJx1}@9ix8%c6n=iGT7Sj2pKao=v*(?#1wXNc$S3edwWC zWQTdon2zPuMdlvk!IWdh1Q0!2(m+3G)bRQ;1aWlLt)(x+F?*g+FK6iL5R2w7XHwdu)RKi%YtUzwE$Lx6^YJ zS>{S(pr=MR4)>$Q&pLvWJ)3po*&Sxw_-;SgeI5S2w*z0_?bloI=0qX(t% z+->xogRzmoP455nzQef?;ztpUTd`xiH!Jp*G4;g$OO4-QUvSHASmZ4X;sd)&jng1} zvdbL4`5WIj)YN5+jpJ9GaH1Ut#U*u5{}TY7{$>|lzGMupF)!P<@X;gYzHH;8U8mRY zTesi%msYdISZkIxAu_~`+jbu_-hj|Z?z*SVBgWL8EaQn?=!<=N?v@*kj$FeVH#!=P z5j{a#lZ|LJx=$in8s5W3OV9P@1GSiXU*C1|_WO)yw8MK5cFtrO|GulS$*4Sd-y=Uo zu!RcOR~i{+sx_8C)88$-=TqqEdF z%QIPjVB5`}=_8HQlfC8C%ycXZjmBf;FE7Rn*@X4G7qia0#(1iK1A@pn#AZaR7E}&W zmnUb~e$TX#T}J9*qkPXz2)}-FNTCXzAVWnRqtVF2+`K zxF>z&>qhpO-y3n5XYd(g>lq{UjIk0^)gI#|?U*s>Oxhi5+b~ft?pm|FD!;4@Jz-8f z-?$*xIH%@sW*Y_iRH(n`_7$-}wHa8xw!XqRcTe}Ma$_TAvPlSSX4C$+jI&PnV(GlH z+FWw<&6N*5y7p(4MMkK{SYYlke_^cj1a$MpBeh2BF`;Fe>7(l-^wog4cVv;V{q%ih zC9v!<^T@jH1D^Czzsp;cx2UP9e6P_ARpLf778Y2xml;3O%($l?1}z@=!JwV-9}HT} zdSnF4Sz6`s((X(qO z)lMo4)J|>+GzH4Ak%xp@VlA7)g+;5nVhx?qO?B})t+==(y0lGUEe9dif!6y$g2t_>WY#YJQW_LHqmZDYm2wX>smy!Hg1nM#DvoH2pn+-3&Mp3 z<$c@HT35e$Q$t4rQMNXUor@OR+};`Y^|1=cDK7{|qGZbEw&r+qT}$(hhG<<=Q)fd{ zUA#d<{+B@d`=XF&G=CzrXhw?UBx9KRT=7OYNN7( z9*!(STgtWO7|J%+ZE9BRP)*P+rRz6CwrmJ>Pp8m=Bv+Pcbz+B=(Dvp=Aw068ge+Aq zo?t5UiGwa*wm&e(AISFmriI`kE9&Bso)MTk-IviC?`mtvYiej~=xnY>vaYj!a~>wX zjCpf>8BM;7%4}aoBfPHuLVB_)jwh?yJ3(pKR^QMOZ*FgkArUMo^krmp)WNBIu~-Kl zw`y!`=*%F~;SPv6AyfLnr3G$K^Ayd)ec3W<_zb~*6i3ygq4LxwOSl6Z&#IlWbL?byd-Enc)zOaJhEB_dPT6F{#HNuj zG>uIz!bY+(vO+r3smB3=s4s>=B!CzlA}e8-hD$0Us3^XX~HE*3WRAm?&xZXi|TSTYO!F4__kOJ zqCr%QezIqR(t;ZblitvgF0#$k%KG+A4HSF047oq|56O^cict#T^%q9#H(wZSti#)Z zh+UqA38h&*B8&D}=VWZ4&&&~#&lX4BkT3xVIZ2ww@@++&mg*yttY=%73uD~bjkSof z#eIs4?kFy=EFk;!$w}!7bFBGJe1wl-l2)^Y-VL>QdQBuB4aKY{n8ja%V(M>X|yet~QTLK$f>Jaz^DO|F= zs=BDUNEB#{cXqYa)6CG)P#25iKu&9nZbTPf7=xG?H5tWllqF{{(sNnSs*=K@Xi24p z9*=c^O`T&!TX2F!m6TLQV|CpP(FUc2XxSXqvVw59vQQ{eTDde@SXmJXRhC0YW2||T z(y(wvK}c$cxwEsOL2ySx1ypOrilR_S1pIAy8dk$uT1Q6%nkrWoRP)x(W_b3-I{dB* znsqjGi_*ao1mDWSvLY%9OCqp$N^2CXf-Osyg|*hYZP7;DTIs-fTU?7Zh(~47hB|~| zY0R*tnB8XZif3{~crNk?%qLwJ3D-8poMR7@SrPg|3EZ%@MA{in(S{Pkb6bh3< z)G1gbTnI~3)>8O<$x2Z%jb;^aqQW!r%IT)~W^FSLgaxlMd_g1C$Ad0mVg@p2wiXs^npdJl=?k2G) ziD~T}4Q)|sPqblMLw&Tdxuqf6+7)luCS~LAnqf#&my3afV1vj4F|-IFaz#0ojup$L zoAHPi<)gCPs(I1!;Ji7}%Hm=~thl8m3a$*Rae?ToNrThnL4Oh^cLjWIO2w zs%<5*Z89i0#vB~4plX3-{kDR z$vGlfU0zusN2*=4sA5I5B#;9aKs?&ma$!9MKEW;Ga0xO{O?I?8SR~fhQDN1VhDM5< z(oDgE<*J*&N!>(?zDUtZ;Z-zZAuujR7Kfm0%kl7fW13^4QE`Az-6b_gJKZfb69q-N4DCDB!_qKxw7!eBK8 zEBIPdbA6ObD5oMr$d*Ny6+{Y_7KDq$WXHq99?gkCC%SBTs9+`C6>aa5h7~5F;agI% zTvNkNT2h5us4eEEXx*kwvYV@AI4r4@t+R$LH0nEKltDzG)Wl>anidY0RH%rt$#P>_ zlL_l48Aqa2s9?34Lc-|#O&C{X0u`1La5P*{Tof&?t|&y-TQ4Z=@`xoIY zVM*$V;&y*5N-z4})M8D11>xF?!WE&)ipuIRB9o9u9a@N;UN~A&uu{(CwiCPT!HWtz zf>?^nAQfE+BjXu>hPG}F7RsCDh@zdWs25{BQdAQWL4smwOb)a@JuCyT93HJIHj#3O zA0_3%+1V68mX@HeL0euFSsscaRARX!BYRV8RE!k5#inL)@P&)8=vh%2QVSl@%eq`(*o6qB0bYR#uc# z91wEguQUZhlj<;Lo8_U(YWyG;cjj6Xf>gGM<>lf`gILMjvQels+TPfR$2WwG;ELKX z_WOtvA}MW*Sqs`=q~X?Olq72{Sdc~KT|~i$g{Xah1EHA6;xs9$Ru`2^ zOR?k$Yqa3PVvh35E0<%`_ZcoK#FZ7HJIJM5`-J6!WvfcUv{Wgnz*>QJK92B-B{{;m z)`aa;7fyAWEu(G^7y1J-j`HG0W z#^Fg6lLuI6i9!)QS>O=8ja6ygrT}~v7Yt0g%$Aoq@-kP8;n<>CMlMJ2rjC!%AJa%C zp8hfoO^H}k*i&M4cm?JdG90bNF|?8_Ktw8kD@rW(Y9VMv(XwicF2oQKgp$@wYXUsVREG_4v{kZg5uJc@Q)%)bOpaF7 zw|6NQ$&Q9sTXQClN5m#M?C5BS!UuM*(h-F>mj@Bc5<^;clvZ^Gg@u*X6%nB$8m^kK ztO#waE{s%$qO@u)kQ0PD-%t}LJs?Ee78$>&tXQwXePQOUcI+xzX$^ekCc;=)au?K6 z9FaRH={I6A5UQ4|mx_cKhwWFfC}wpf6`);*2=Ty63qqk1tcwMgn7R5y1QChhn0;5M zSQXL!1d9taL~N>*Zer)it2k9L?Kqs{79&W^e~nRcZ2G${o%qI{E-C|hR1GaU#%yS- z$5HBMIiILR^^~=Eg?^a7X~`qEZCLo=z`|N;VV1)tPFR4#Hu%u(*y+N{JL{y@=vb`m z5~q%WRY}8oc!eCi$^*i|%22^Fgl$YCn5VVPbun%WZA&jC0tOp~jmF`Fmx<7-f^;Gm z6gzA5(ncJ!bakkCQko+G zF_s+Io8f#HSC|7KZ|etm!l4rCJ!wg=N7?tiEKy zV8LqXrwHZb;n5IwB~ojO5jgpklPac3dIUxmss(GMTpVK=L;HI&Q)4sz8AmK?=mZ<> zh*D@4rh|rXS~_OHFkGp{tzi{jQA9xj`NeR`chb0)&p^qo zfLvZvZGF~dmNl?$XCD``vE8jHkrPKWitfUZB33)NyMwJyT+9^&?F|+0BrEB>1V@Wl z8pZD6pqfejMT_K|z?!egNp_o?PV&iIUoTU{l zE8{K|ZPjp4C0zvJR?yd(NVZQcMS(>>vR$OkWduI3aU52$D0jn z=+ikuTe~g8I*+h~$hpJX8`Jbhb5@xaSF1a^<%Ok2te@0({*x-ny9E6mX@MLRn;Y{FeI#ghF#?%lVhyd z#ge&_EjH@vG0`BRa&K@UbQ14gP!e03;OahG8W3gNC@)%GP*{t=E?o!ogr$vjw3%!s zqm3DbZDPo3G?Chp}bpw_f^RSQ%4)U$O=c^15tTsU3 z@gk-JYB^p90lPNgNFDdh#f_SVZFQ}f+3bd(#eN)XGz7HfKz0u9Bw?7zYGKmoQv6_m ztFNe3^(G!*%1U5qI#O0`QTr#^K~d@jlB_b(1xgI`=|CXE>Vuv=5Fhar0+2_;dt($0 z&&G-mXkNy6PX^P{7~f#ie2fp+v^2)I+B7fYLpIH1{De*OF@Dmfr7?cWrg<6v$fn^H z7Rf)EimYq+X_ox3inS;71#)SQhIH zlFGC$cq@(g(8DD3p>ARPOGzS{m+>1mEsgQ-Y?_bpJ2owi@$YS#m+|{H&19Ub`~vm* z80XovG{(zpnwRkkn`SbuwrM`b^t%fBppG=gH8#!5c!Nzd8PhKZR9T-y_BY#;-Y-TU zbUi~>QP)lHgOTAnTO7mneadpG-ezRT>O!2<$^Le08)0o(AgLDVd%}U{$Zow!gU`>!WKShO7+L7)qjAD4A-ZFHl2GvKnfV z)KHVGhMF%>Lv6AeYLnDZo2-V~&#d7O%5WZSzs8uWLIh#RmLoRC-By=|8FJ4MoAbk> z##_bIE5>X_W?5vhgxR%u_(3O|Um|8#mqjD6}#@saT@ zHqFQQfK78v3oPpf#e>+ukc&~Ht6jb9E*MExF!GrNueEBdV#oq8t{5gN;U18z1pR7< zJ}AhL1?XBW!$eu`p~tf5FJMYpH4Iq*46QLv6y_dfhm?>z)Rnr3@nbg4$M^>}&DBLL z>wAg^UBr-!CGR44!AP=#?k?hj|7O)##gGNS(hL)oaCZ^QI%>%ZF=PR{R>Lq+mb;5s z)_s<&8ip(Y-OVsj)@S$7y_T$6hAe=(n{lErcgQ=gggk8tt7dpYk&<_jyI>?)L3bCq z3sxm7=y;6%lhPGvQFDE8S znub}K;Z#KepWZuNCFa|F48;$~Ko;^ik#F-kbwd>@)4H%~=UAme3~ensxAk&@n~CvY z$xtAuuB$Ck)eP@fq~uP)1;1<+j4-6PD$+;SA`EYn6f`<+_Hu$N0H4aXE-XE&C@=!U zPDL`c4sG`2E!xChrf~hp*)4OfR=ixJU4|+5D2{p znDv6gITZoPsez$&=>MU3L?Nei*`{ruX$Q)2R&SSaY9Z}_GM{M&nP(Y5furjBZFQx& zgz+((=4H&gM)0LEe%j{qF@DyjO=HX}D3tXxK2Mj7piN^u!KV2bPqJxgjHlQ%FJr$= zGZ~v6s}8?X%erv;d5wFz(OyuLl2D@H{n-lps!Ha9iV|Ym- zA18Wjc?@q#mK$#oLJl6WX!i{LKh+BNWb(Js@vbrG7GK5Udo1x$ zhAfc8S0xe8VcfEgTYQMcUu}tB&oEJZD2aIWCR|IpwpPjbvL!3bGVC_Hyo5_}wYv77 z*Wi$<`8IVWuVH+LP4hAyXGrZmTDO<+c#F2xWIV~Dxjl~SeBWwyHN!Mj435N*B}$Lu z6w6QIaV-7;OMHakXiNNhhAdEe9H(sYu0CV&f3(C`F&t}&Kc68Blpe<^TfEDmSv*?= zft4YbB3bTL_Pa`-QI-;6cXcjb@+oGN#vFlVOfa<-PR4z(F3%5rx%%i>mG5y~*JpnLneK~>&lDN)UEvmzxop}SxtSwXi6-36LS2N~~8)#m}eCS7fjCo`dAIo!I@t!g9foC%0V##gD0?t){ z78s0k6%E^vJOx+UBwnkqd~m5u>%uCqx`x)Z+uCT`(yLjzy#uXgSf+%DqMWd+thVY> zfXA#YJ;c)OQmndFc!NUUQdcrNO9kc%bn3NA>0M}R)q z@G_)V*wY6j-VQ%3DVo?TbAl^KvRB@q_*>N#du4`Pi@on<%5{o4ao@|d8|^%6-}`k% zV|{IjtTt{;LjJ5KQF#MHG`m9p$9`T{0A_WJiD^8irUQSH3`50y; z@^K>H=3}@#k&hEWn~&k@L_SVzw)q&gC-QOPa+{CgH8x*IFDH6zK882id}c2vj@o<- zA4=ro1n=NrKZZX|JBHSh~*(4lJHqORm|jN>-V%lJsP z-%_HQVU8jtH=(;=Bw0bX3Ec&&k`;8@%Uv*(tY8x3sP0cuSBh$k=i4+d<9wTDGUlOz zvR=l#X(M@zTkNvDBT^K+&QhT*Hjl~pVw>h=yw|3sF}~BL`4}IuX=#jkbx!&+<{bp- z%a~r?N*~aCjQQ{xv^2)Nf+2Z~UzJ6vtZTG#TW?o97_AIhMT}O4e18aB3?EblrT1}) z)j?T?tVMD+b?XsfJ=iQ5WDL1-?5!Ab%_Kh3%PGDo1xAK!6^LV)sG55qu&f_jCJHKK zU4EdD%~EaUDX?2zxmEv98QQH!@C!8Xl+ykW>PoJ}cuT?(moeY&AwI^BCh#dS*5$a$ z`=QNaGJevgc^R+w$fC4_X3VQms*`bj0-sfx0$k^Bm3;IFLtdCAtkGDabYD)fd@wr2 z^J@RkmiQpU`AVxK%OH=+N?2RE>k2#T8uyI4~vEz&xMyhz2SouS?Obxw_V zLBy+4>J-MEN;qg<#uwYPG{)`L#J2U+DUDMdii*-{jJMb{FXL@C&1C%5J`z7m=e<_r zs~Nswk-`i+Em`y&8>g;RR0KYTcBRQ4cq>r_f>uFSbm>u9*Q+bplJPffnwRlWn`Scp zo=x*IK4#Ng^8(j-lj6bPV93Ri2lB700{2)2gWpo{-)xf8^v6}!m}Z(+Phn?6)8-W@1DDK^c^*tBUT;|FY-UzW7L+3qhXJE5Bya#Il67!Fd} z%AU7UN6A_WV z$Ng3XZz-8XW6U;z#Taf=)esxwJyx573|R|=Du&!cRMM$fzN&n=x}rjc+*U~9=5kY$ z2nWe2`?%8XaZ7Uye}$j4Xm%NUG^;~FP!R74uGjBm1Oe#ST3v}ueF*fbyGgElRV z@gbY$Wqh|yGa3Icv3};xRRSelyvaFP2fAjcY3*iKU zA$u1h4@0&D$%^!HihCK14Bt&KL8O;ctT-4Mvf`+hAu9|nTTh9eQk}&r{wKP&=l?fd z+ooE|Eylcao$3}IzaTN>KEis*X?0BrxiB_Ad7}i>(5V!eXmKmzJHGi=h7)p>T;4md%j3p?@aJ(X=;K0|{%PFoo zRl_S?H1pHZQ>;-o!ZK};;dn(#;GREJ>QJh#=y!&1D^ddY^~z#*s%t{l%?`^YWI0tT1PFnc?@dXgsbxU&VV za+h+s{8m@>L3b%vyjZA8ajWsGG`G^Vj+SaORVg-O5^FF^K(P+cwrJ;V(MI<&VUEgx zGc#my7O%73GF2vSmvw9FYUAyS`);dLHN%e;DOEEzclkthPNOAcIo0{DD*b^axXM{N ziDe#B+`q6&g&5j`s##FB6&*tiZP#(#5_sIDQG^BAr6SIDaH%&fjUo(fjY3~Q&~g=x zc--P|Ja15D?VYZ|(Nc9y%!_lVQb9g3&l&9#^PCOg`V*!nXSJ9txV9v-OzQvEEVD^9 zH*UvehWjm26~luTDah~@i&W)|+Hf3av`*qnpQFJwmh3QVz}|R2uE?`aRl^NO^k`QkZe6aH`sohsydB!;;nVtS zBTQe`aLqqzcwqFjR4p)N)FgdW)(4-CxIwa*zRCXS({ybV`0)3g(p_%)Uz6r+o_E{Rx-s^={eg-LluaWxHaMg_$3cc1P-uP?i#8@4w0Rlcu1Fs3B8{=V;C9Wi+yY*YCW%#lRtC&ajr3}r z&q57rhM3sPIc$dES}dpkq|!b-PP@3JIBnwQU=wlk-5k!&XU)p24svY^IE$6X^IA?R z+<^~TeY%$6cP&zgq20}ESy8(K);eYLYM)D^`o~=U;?n3+)t;-Yc2zTcS&IZxO@A2FfzyqPYuHVm#|L=#$p8wf2ce&TqO4m@`nplpflZqsHd@{hJI0+Q03>JAL2|YjBxgfGvNe>5^_-&Ose$!QFKha# z>KH-f#FfKkN%$PYBZ`F4{r)ze$mUa6-uoMil&hOi#g0p31b_a#s9Teu4g{_u_88#|X ziWWPe^>RDeiLokn_hi`FbZP;+>V?)eBYd`+XD3@za5$zQJ2d38AD_0lTGhEayLOVb z`TwqA**MrGK={HrW`>eXc&PIG&Wqr?L2{9aCMWihoTph{fbW5QyL%Uq8!&Q!r&eKqe z*8Pmu`zICWI5JBr_aPrVODabMc5g{_I=G}dU0hO~PA;iV%Zybm7OV>SQZ5wiY= z!_!|?AM%{^KR-P=doX{Pq;#q)b}1=*8v^(Sgx9xzVohW&?oes*n1xVpzw zwf(g&twS5z%jq9lPE^ZqnbM3|o$4{&sUy>!S~1;e(uWt`;@)E<^=ywMkAT+3MV=B-MXSb%@R4+Bvr=mhaeo$8fr;+oNsCVZ7YZ zr!_b91c95>IM#XxeF`k^ZI6I&;SFIuD!!;dVIrBa!#rBgPSI;l#TT4&1a z$#LAmW6E#r930S4j#FinQ8`ZOpQy5SdtHYPgA@z*jjpX_$d>Gfn{PQ&+-m_bvm zN+t;u%)&cq{32pnFYlLlXD^7(jlCc`&+G)zxvdvOXUkqzy1i#@@@g5fx+z-c1G`=G zz;9K7-&+N%oU%FV@1M=WStl&hR57$ov7;l2DL{0a0z|hdKy;e|M5nrj(t#_+kahL| zNX|+@a#jhFvqF$Qt2%BkUSl(@mlLdmq3uXZ*7&q!jZaI~__Sn=Py5Wq^U1l;h7*q{ z%iuLd+j=?ioK5^}Te5^?zmMT_g%>{CJ-AEGw%lVa!}Amght?18?&Z{Ci?N#For?51 z1C*;7Zj}x)g4U}q?^4i#$M&fp3iESm)-o)@r09^i?2PSJ^ZPKQg(b9!E4p3?<~ zs`j$=lH6D14&+|Pu>!*c2iWHFr>B%?ZZ=}Nv$Y^O8wrxLZ6GYBivS;gwbcI-uypUQS=F=!3K_dBQ@OOyt&&v~*=X zh|AeE&Z^MM&RR^a#Z|>HR~5ZnJ6jHMfZ-iV>nT>L&ofjnvp=Yc;U%0ydpW@!vgdPU zv3$O=A>1b{PL8om;A^s?W49$eVR=s}Y)aB!=)3mB0y# zM?NQ)JbzqC<;o{;1>~Ja98d6|Ek@qc4va%@%H!4)T+PM zTD5A`sz=v;bR)?l9MnqESJxO;*Ql$b)O0ASiiYKwbxun0I-_&B><3zBpeGYj~bt`ov$uj`SYyH=cGINRN)0SzLLq*O$C6c()PYdZAE#%v{ zzN;kVni!>SbJk=@veB}qy>T$3tBdoLChNZZ(~cU*n{uUL0C!XkyN8LgB>5=UJ~r5t z-sGg4NZt%6(G)^dTp6WYIM+-mHuKIi-YAlE0iU@!6IW@IWqb1YF`<1Smm;+b1kx=RNHj57ae;FF@F-JF|3tye3Nc+v9mCT=S~N@Ks`jA;Dd zAon7blfCd#-z|u=XOYUgH^XRd)jcd++FB~&teu>}IsD}8iJFF;oxv`b8b0bw%6<)` zSCrNDe*!FIm3SxlZ4^zEmxxa|=&wf%$qg#BgZ(b-S|bPCi5T!HEc1f7AkcCISdK$_ zphVG8MR|&pz-$zxOb48#i2 z@hXrWs{-k9Y6OGHe5oFv!llQiK-$jLft_ukoo%6=ZK0iQp`C4^oo%6=ZK0jPbUOe$ z4|J<)_EGG(xmA?-3D>wRb-%$~XUvkE3}~Euhax@8vytT1@WA-1mK+^wAJVq#T&M&m zXdgt;_mPIzM_IxKrajqo7@mJ%i$g8i0U^gxXdqh^a_HvKvKL(Qf^V`cqVXvwkL<0V zyKiExB!B6kMv`o)OoZ$}8lEyYJ^=-kmg;{C$SVqrz7`XMACHX;SGqB!9d`v%*-$F0 zeMqT$-DH#{>8o$p4@KcfOq(9UF%}H`VeGa)iL^Ret4>f^!pUh$bX9PI$|1iJkr`@X z3BR7U@o10sD*I)6*9MOhgSCOerY$mT+5&^=8mFR0`a=#rshy1zNNY+tK|K;`l3v!e_^q6-BIN{?wbOGl50K2k>is-HCHpFf#hXNCh8)4J(*KXg zs>?9UeY|JGcn>DOK1dB9mEIva;-E&78y(b2@@@w;hSdf0I;F0Mls#50N^lYRkS~$L zQ&XbV+GAByqGy56LDstNdaRc8w>?%*`gZA0WuZM!07mH{-ck|Vv`WA&t0c&wK6N{?ko zcX+IZ^eT^4lP-F!igd-ygn`T)1ke~rdZNebNgwR7TGEGjEJM25V>P6wc&wUq#$#2a zr=OTGP)7y3d^cP#-{(j+qp@$2 z9|HMZ57lF2aRA8|Rg!d~bS%kcH{!BGAaC%{;TR}ycLOH71SAKJs1IG64PBcJU7HPE zo26@?b*{~Z{tMRpW8lA6GK`L9l67#}!O_sLJuaFd;Y9D=;Jn*>8~nBvshn7od;(CZ z4x%SJe>Ibw2k0OZy|S)Ljr8vEE`XaErS!7YNb*E@xwJ;2-uKP){b$`w)l8BzR;iA# zXPU#FX%2g)nLWb@7i-xw2V$8Kh$QEb(#mb``2Th2w@Z_!F;nV z#fg(GmDx`>R3J9W_j!|UfN*L11=8jVq^%c78!wQyT_A0GUUibNELC0===C&8ThJL; zur#z_X=uUH&@D?tw=50a5*%p^1r{`{34G8HTF?+$&_E0BaI;4a^?{(_Pp=XCECJ1D4?`d ze|->Wfzi)k&Eh;MvBG)dB4<$pNsgUyvda#~fAEF!xj=afl~a>g87c~_q@usMMYoY8 z4WA%W=LC6xC9I%PS3p+n!EDANmm)RG3`lMh4vYrki!q}FxNoTT`-b_`%m!jqZxo!U z-Y$fqdU+2yxSq4MPB~+St9mHh-EM(&iv`kc6-c*IAaA#&I$=Fcl@Y7$6DTxlNodrP z(5NM$QA~_qi#myQWm2-Q1nHl;pEN|Mp)X-(JW(^zQqslnYH@ue)QNMFt)-f zS;A45R;6}w8V`L(M};+Mk39`HupueSl5T5CgfmPgxkaIs}>3ka?WRJk_DKorUriC)!GK zsS~x=51GFVxO>M%+Ori}iS&w=_iwMDv0cuH#uwBn2N%XDwH%7%p%T2-g-DMtkqcwywJut%$e={G zmtp8_3JwMDz-iH=?tCswGI3waak_KJn`Dc?eY(x4r)o>*v*q0?h=z_oc+1a zNS5)tFn15hvO4UrxCkf9_*L>j@FdH0lagiH#kx)MH2S%tx-l`RTM>iW{20`B$DlSi z2DPOzSkA;NaHwi-QzXr1SfT7s}hGq*$vw6uT*2&Bn&d;}QTR%a#C(IZn z#;ZAU;!cuRbBwK|*^RN@&>f;vyTeFpZ+r_u_@oQ?Mv{quuV0sm1+_+rZWd|9zkQ5pPH#ASyoO@ zvpdWWCX1B&OL_Fq+EbjNS@vZFdFx?>@VYkv5~BxYA<}KQ1Y(yWHLuVz!8>h~h!+kf z_m4p6vq)v(Ao(AFs{LC~<3TZP^Z}GS?u4==>5_d+u^S*o)|4h`mVJ5eZm6SCDgDKo zIFlsR=?NuSrstJpnVw#fWt?R=QzXmuOpz?p6GpO3_d46e3*=@VAIEv*b4? z!qzMgTeDoZ=47;DHg3L~_tfIh zQ;S2R7KcVH4vktI8nsxvB{VAcuE3~VXjCpVDi<1+3ysQ!M&-sfswo>7)f5`l6dKhO z8r2jU)f5^Pe21r}81V9Ij?FM?InoL87`Qo%XWqx!5|X~BFQfeoLs3Z5N8}Qc+^7pz z*vchgE0=_=ToSf2IK~ZI+0^?_cl{<{H)a!Li0hD4?`d|Dhm+0;9L1J&z#`-_ODl&Mawt@)=x#`4Q4k3rjcy zrD^x&NiS?_}2l=fUyyu`I6V4+q#j2W3{ z6G-F1V}n(bu7QAHHKg$btKrL#p6>Z-Ngw60deS&|H?s3dpASBHHsO(onG3w|e9{+s zte*769;+qIRvQCJv$sq`NOQ3hteSMI*H=Y)C9v2)X4ZJd`J_8NR!{m0kJXay_E?5= zug7Xguk~0p>0ysmk^WSL1!Du5xf`HyHR(@#te*5|JyuKl9*<>6f8Jv?r0@4wHR&&V ztcvuDz+wZL`J-o?Px>W~)sz0S$7)Ic)nggbFMF(pv;yP6gd#sxD3XfHh?(kSW>D3;qCB4RD8Pb<~tcG-#$EryeJyu2fDv#BBk6Vg< ze;$64BN37mvyYC9E!a#!`cF=lN#?X-A{8gB>f3Bw4euqj8iu zZ^vb0_e(47U~I}E9?7H~tvCkbcl()ueZLtcvuy2?+z8D?!ks zx1(h;8+V=j>-JSC zo6m~UT99V!7h&Xoy3WgzWG9Y`){iIc)enu=4wCsxchud`O6!D$BpW3yywkPtr@o&^ z?)DzLb3HSE0%(3>W8y2X95G7ZINw=!u4iU8z)6NXsyI59xBy^hQbOBLV|}yhM@jcP zTboE;1ht)^1GerKi9?9ma|u8HsHk($=qlRIjUyUrron4W#Ed zEe#|W0FoQ2t~vM>`5ZCl#8HAY`i=53vn}K2Omhr0i?N#W&6$m0x0nXEqq4O~(|*x& z1Ipg(c&@A>y~$(Mq(60#ZKgcaRZW^t*qeob^p_@jKIa$^tg~>S1!TG-NtN;(?QJUVsvjF+=5$mb!X)nm6!S5&-Sd&8Z82Xt<9>?9%aI#N+9Sq2l4jfvXWa9!ScFM_ z+#9!Jgc({Sd?XXb?HDO%+{4be29gQm9!oQBr!(#s&bWqp7)1}t?vZ4|j-6%g_`I{D zk>oa~Jx7vVW;c_}v4WJPXgmUA3Q}?So)KoIxv0sKOtgJZTHAMx%s@lwcE{ArGFmt?X|1y$u9N#q+qs*M@`ADATpq6)o{J4Xbg?+V*eZ^Rp zR^30s44W#uY28qPbYx}FJPt(pE}8Hazy>5gxTf9{y*{3q4(WicV1xxldP(ZiKH-6f} zCZ!w#d=*k}bp71+W{~V}`Efat?CrQqnekoU7FHNs9%hAXoberLZ$vA}LtU^9%fu5{ z)*2eo8X6IN|2rI=HOob9utj|s)9qU(+0i45w4QKwfaRx1&829v9}O{s=}$e%PI5d~ zR*|0Tv1-!ua9D0OETk7W?8++AkK*^D4PUuB2cch@Ly{_`Qy&{)hPq^`3fE3H;6bOX znIz@o2w~<|Fjka3GQtdhq+2!)BomcB5=@1xw9i%AK$7)HrF+s^5H5*S*6Wltl6)JC zmBGSS^Dg%g$%1Q=Z0VVy{VC(@YE*QSt1wHFu9K%<9~+r4vxfOZt6p-gqW8p=&pB64 zLdQ=qoh2HWr#&&Vj)*V9l9OEHma)B*OIc*UN&64B`ega60QsDQa#TcXQ#MFik(mdm z=||918I7zTW#(rd92sQ=eXbjXlbIpcqU9uMNUTwNf(~c(2g$`}`^9Bcv(jl4F;JXYneh#|b+7CH$!_4+kCL9_u#-kfF9as> zuy=%+Z#%~NQPK>6n6aD>=&oeXZFFrL+TeV!$+fMO7=h3=rcMUKv10l5rLKL! zP4@@G+cikVQ5;80J){+PqUaXSLXw^SM!Bh`%Jwjy1DRM(=f8{Y_qyEG&6yO2JM^m(M+&_9gy!7}wt#YNLMBRvu6 z8AzedCG|Le%GIP9W*yYS-+ zv`5#k4&sA;eXad{@9V5@2lV9;H;lhu@KzyTcDl>Vol2<_7K-2nb?Bi&#Ao56qEtCZ)sy&U83aipBTI6qy0@ult6 z@?-I{o*vZ0%@XIapJV>w?^^IB;Cde6&m!>kzou3tL^5j&+Wq*D>M+J0SMIr+aq&sg%;fNy{KZ+?~hY{x9Lhkkga zj6W7kwk_oEo6^ta`kz1hR<8eFZGR7;{tZZ!6V^LOmKr|)0;{{2YHcRcvdLAt;4J0brwq+`kd2JO9I41YdT zX8s;WIiwu_<@n!&dHFEt%OmYCqrV&<_f6WX{jh`mM?2ULnxApS@xeI!d&h^?&)>cO zE#j9ya{mhQl~b(5BBWYg|91B4ZJ+-6WxXC~dvyI{%@i{{=SUXf5#Z|n*Sy6{{<<3?2G+17C(R1 zs~mqL4t*FO{9egl(_uUQr}{q!d-w}TI^Ot*1LJF~czU1G$KNqx{Azs}tPkblllD*# z>!+OVk82T!&Y$?6!g@8o_BX%BbA0LXq~(Y4y`MkLF%~~>>G=`PGk${fr%1Ja{(?p8 z(YAy?81c6mHqYORsG4c>Q;;4z%jWrN557g)qW=GnvETSd>3^Cs&bOMe#pd}H2N{IpZAC-rI`Wk2b-<~+){u0wpY zAN4%SxaNGX+sjwUX?ytKIOp~MDSN(-e$@8x?MP#_=Sj#vgLDtlw_yDqOa3|UwmWHnlbuQ*I#w4MKVbFUY)6_UQNMyxMqrt@h~mw)~^( zzZ&i4`!$MKuXZw3>y#ePueQCPR`rcFU+DQk$CI{K+oSpCA7>FAZ&|h%Dd&%J@_bzY z`)51mL(NZofAv2HJ$zQ4{ZP)HVN|#sDIe60DlL#jI*fEP(yd4XdjZ^m>)U*Uc@Oe@ zV)&79V1yoB&n8t59~{>8RYNc9qyFj8KMUyzNVg*`SO0d@`#_oYU4;6sRqdJbI_bX* zdaqXcC%sPkFFC+^kk9U1gFGMG(f*w@!6JNS=AFp%@fiIyjF!I)*UJ|kWJ?xIv?*`o zEyuqGa$i7NwV(1kpkLqg%IovGzABtI@ZLP$fy&$MZp1m<9;8~H_z14AT!(ZUQhiH` zmcJByf3JL0*T1fNAiq-5fj*nAA=T46P^eqoGg!BBu(PY*Y3@=;x3O>R|R zzPpfH(;>3VS&3Y}uP?vON|3(1UD%AMsYkTLHs!lJ+r^Gv(Jue$;wr8BmHquuU3+hL zccDiLI|?fYSBs{6&+3BUHrv^=%4o4gD_8avhM4Q>>?x2IH<9e>mC7tXH0gf&JM;5J zZj$_A^hWiVR+wfH-baI{3ia?b`CQ4%gK52#pNPxJOz#9gW(!vj`OTf)FDK-;L7r(n z51ngYm1y5(M?MJ!WFiJDP}dY z$G&zMA>Jo{#(tW)VufVn!?X(ivuIfVZBmewU(;?mnZC;uCO+DKTcs>1zpcYEGyM$W zmnztQ%-=19=_6-mF=LC0Hqrb#f1j|KkfVGRbueIi}Am`OO2Fn051jl`!*L@{9MTEIJv6Qaz2LRQ(8fJrl&)m(5+oIc_}{8t<$CW zq=@TpDSmLob+r_i?;gcW5{l_cSy{OrCJQTN#pF6yidRQmze@4R5!a)&U*Fxx7pqggpD5Jlq zaI*{b=;e>m1NHQIsxrQf~>{WVJekEsU@-32|r1%C$o^n>}{Wa91X zN`H;uY4Mp6-1N&M7hAh|9C|)%uz8O>Yq~vH^dmNn*OuXb zUm5&kW$-US{|=@9>%h0Jux(&Gd_UGx6=e}nIW+OvGW!1vJ(1EsQNHBI@vrnBA-IWW zzQOlx&~J{@)BI!J*_DRppnr$bUxfZCF#H`Awt{N~&!DbkavSt4Q1;&ie1*cl0R0gL z#9cBD&F5P&Zt3Lzr^?_J2d1~HM(}D`*KS;wNvesCjQOQsuu#-sOE|lXp0mJT#Q0qf zZHs|(Yj+lK^LV4_7v6r(?~zvm-->+#$K58ujh%YjZI1a%Oph}khn{SUEjvZVq4|7P za1$phR>WDiqy1VLJwJq=M=*ZTyy%x@`2SP}KSTz8##UMKe}>@355+Sq%$Gu#_mdbr z+hlQkU60N!qh}@fx6ZKql8rxC3t{Hr6>1*-7vTIp!tr=dtOvr0jn$sD$G^ znmyRxH@mBI>S}7J706 zh3;amFkEOC$8;5Py+yIO$6W6!TiV$%T(&Uk=;|Kq>CP7;>Fr$Xq+EAVE?jl@*GV!^ zcT&`yU)|YmUE4h`TSF<*Ha$zJDMmggCkGlv7VR6+rKxINbpAQzZ*M zL&iukQ97jk3W=4@{=R(O$#Su+r+=W>*ITSRX-;GuvZ^Ca`lX8@k>oi!Rl99be?hLm z4Gv3u<)ybfOn1+lE4|h(Cii!)T4y?JFut-^7?w+bJ#i0OKv;z_mpi-hjEffK7F~Rn z3<^6!ENvo-Q7DnsS1?iD- zO^cdy&1WpUa8WLfK@+dJp|-!&(MMe=UjN+!ZULxi$6~B9Er%Zb=w#+4vd*- zkPM|lp^OfW0_ZCAbl9#7*4PguvD|sh7v=mEBOWpnOta}E-`M`no`Lys))``EuP9fDugtD811P1DNym6)gQD!D zc~Ly+L~<#%tDwxxnF+D|id_4eD{`yyon7AGxseG{pD*bVW8|EZO|Mxm=K4w*rKOd2_u3jG@TK9x}Qx1;yc$%SjtL zWW02jHlVxE-CkT*iWyttN{YRrwa^#WLS=(Jox@U*=yR)#3>_z88Yd2Od1IG!jLDa3 zkeR7RR7t(@~JM!;Dj| z`oSoT*`15fd%iiGXng#}F+(`fTDe6;Mvts`rFI(|WA$l%)=qOy~^%+aN5UhI4~ff>Pg!HqST z4R>6mx+NHghT9E@c&d!I46$y9YXi#;b0<-1iHFn7(WMc#!lhG$8Q^Nn+odGJEUF6Q zIl^uoxMD~+*m#sWof2W=)GDgR7@>eT=$IBn?^p8#y+FaM3Eq~@?u0fn6 zf2QtJ->$Je$_JGr6w_ya$`?drV~)-O8p-sUain!j-6(;sUd z*|Kg%MPBqR6WN7}ez<$xJEp&L_vg;O{Fl$KTmR(`yl}{+SI=2s+F<-WRsJgF@0^QU hqW3>P{e!QZ_T&#QnSa$c7oU91lzSg3jc=Wb{5qrxVj~PEr0p2ScA7=3vL!yhw4xHP;NH6MKh<^L3PZ zwRAsx)HVGbsG%oyKh5#JxKCx^&%4<3bR>_bPfMk@&kNe;?tJsvWu3*OVv zR}aq#K3n0R6}(U3Ul)9t!oMc?N`+r5_*#WuBlvoS|3L6f3g0I9Hih3RcuV282;T90 z-}-(n_)LZ0E%+RT|6cGF3UAwgrNZ0(txDl-{}WMo+yB%myzLL`6yEkr%M{-Bll2O3 z`>O_pxBX|M!rOkVN#Sk38drGRzqKm7?cdrI-u7?p3UB+jgu>hY%2IgS&vYuh?Pt0b z-u5$&7y8 zHmLBne=AdX+rO17e9FHmyzSpA72fu5RSIwWw}`^q{;gKwZU0uM@V0+jrtr3Zt5}&sJfixZuDSVyaJqq6>_)LZG7Q9#CN6p~!a}@sZ*_`(&e1qVF3jdnm%N2gL z;42mWUBO2b{xiYXE4+;zTl(s!MU>yI@b3!VtMGREY=zGf@taTKKN50uh5tpM1gq(=NTOxg}!aI`uMWuR$f9FzOo(6?qF61;S{BMGfE4*ta zm(!~7<-2&k359=M#GjVJX9_u;3U8OETjA~Uc(?X#cUyk8!e{|X-#ax8_PE%;7_ zze4bi|Mu1M0>Qf#{!YPr6kZqhmZ|V{BE47P9~OMJ!Z!#$N8y(XK40Ni3O=atcE2lA zc)Nc!DE#OdynW*e@B51DrBmTs=kWC13jev_9iR8rXP1aq-3ss6#N52Yr|^S?K6QmJ zZ{z8MD*rL(%M{+XikG8a;Rgvn)1dH`>$zPuDSV=Z%ZV%epxImxtqSjZiOXqM`A@l= zgu)LMax8^+Jj?6Vt?-G}T#n-l{%fxrym$#Ok6YpEzvbo0RQQO{k5}PO684a-@SXj+ z{CtJ?z0b?xQ+Tham#*-h7e#w1yzgx;r(EH)g`5h7uiVMyR4IHy$cZR?)pTC|T7{3? z$Mv&J;k|2ldFmDZbWxrLh4)nR@-!)Y{W>luuJB)p@uF4X6CZFn?Ft`h=5i7WKUmbu zQuw+>yk6Z3AK$>`IKJe+w*8zZ>g87Ww&!?xG8Mjl1%KYF@FhY{w!(YFyU_Ux?|X~O z@hSXdAxBqu$HTllWeOiz$>o$Q{G~!pg~E4!$>mfje0dX>6H)j_MgOW*__kk!{V057 zGnZ4Z@WaKp)}ZihqQ5sOyrYfFi7WhEQLk2ouM>Wo zyf?t*lqr1tKfFBU3LmlUN8vpYE~iT2>p$UgA`1VsC{L}z`^IxQ%M?DoiOXqM_&Y^; zIu$RQPh2 zkgxC#jq?$Ouk6S9T7~Z%$oV>jkM!sKGKH@@l=JlpA5Z6egTl8h=JjnMd?RQSqyocAic=L*heD|~zw=W`U^^F7ZuU*QuQId8|U zcKI7cyr(PagFo=}Aed7lkJ}s-nX2W$EWZYit$BP z_{JA``f`O|HI4VL3Wbkf$J0j?{!4pYR`|v)p1xk;?fAAq;p2z$eB%ml$JMP0ANiWg zPbj=SFR&E8^PfDuLjMXsLZr`Dc*p%h{|ax<7j%WU=L_WuZ_iUI6uvQsw^u~r?fAA< z;qCagUg1v@~b~;p1Z7TCebDiT=`{@Qq*a^28PXJ`o4DDtzTQ z;ZGEPp73v$!h1!W=CJze^D0}P3g7mq(2v5~>odB-$KMkELE-Nd@+%ZRA?6(sg}+~< zuT}W+4|sX%75*`izCq!0R`T=-g|A$~c}wBr=koG*Dt!4ToOdMq>dltpR`^5_Pw!E9 zTaH)dle|3H3Lk9ee1*c-f6e)Nh0iJG`8F!NSHy?Doqfwc%pNxt{#l{VI)#5p@J$N8 zLhuQNUnO{7N8fx?_M`BQWxQSygMii_-@fp8x=k-*Nm8-cu4ba zgq*m-m)q-R3Lg>WX;=6uLXM^Ia|Pe2@DZUO$9H|(@p6&gqwv>?@?0(a=uOFw{Sl5 z`@VX6RMa;|;d5^1>6>= zKQJqe393~1&fB^C?md0w+%M)qp1pnf$kROiGKJ3(>nE)WZ|_gEE4DeFzUJjAQ~1V@IA5voc6{a#{m+(f_s1rMKVbKFg|8It-mUPFv$-A|zxCCF9fx@o z-j4G!RbIq(UWJc*&*kSRy!UO+=PP{Mdz`OO_?$w{S1Ek`Qm(gJh4+a#wd_FOdJQg5 zV-Hj+eEfDUC#R=xdOI%cR``>I9FOC8_MqJ^9x*S-SNMA22bL*(r?CHeh4%?NY*l#? zC$%fQ9TzTpiI<{e{!bF0koaK|Z%O>0CB9SQ#V26d-EN6LO-k>0nd^t@dXB`qCB8u7JraMu#Aix; zk;Ho?evHItOMJ1!=SaLR@%a)Tka(ZOPmp+B;wMUcP~vAue3``0l=yOqzf|HYB)(kY zDg?_^iN8ZiUoY{s65k;4hQv2Y{9O{?B=KVE z#qP!>{$VM7tHeJg@of_Syu`Ol{0kDFkoZ?6-jaAR6tTOV5+9e+cT2no<@w#^z4qTK zrFTpG#}e<6_)jH1Q{uNsyjS8A5}z&c+a$hC#D`9B)e>JR;y0D|h&W2+8%4aN@<9DIifb_5eetr5}zf>@ksm$5}zsYCrZ3m;k@ye#0Mq*bcrvM_#BBZmw37VR!ICAQu<1XKU3nXB>pUk zk4Su;#Mesv*%DtT@%a+JOybX#_ zN8)dh_)LkvRpPx8UnTL`5n-3k4yZ665lHEf0Ot&iGN7q+a>-HiBCxUqY`gP{NE+MQ{o?!_-={+hr~Pn z)ocHcOT1g+>m}YJ@lQy6ro=xf@m`64TH>=M{uznSk@#mNK40RWlX#!RH%PoL@h?hz zP~!h7@nsVKlEjxw{L2zwA@R#4zEa{FCB91HUy=BT#Q#g;YbE|QiLaCR*Cl?L#9IXiGNe#;}XA8;#(#DEs1ZF__rm#UE=>O@d=4vCGnQTH%ok{ z#IKR~Zi!zf@s8Je?SH+*yCr^u#Cs&ZMdC9hext;DC4Q5{XG{D$5}zaS|B?87iGNq( zeG>nk#Oo6OzQhM5zD?rGB>n@5FPHeu5?>+lA4+_s#D665RTBS+#788)UE*sc{xgZM zllUzXzf9t{N_@S<|5xH0B>r=WZb`h>) z_&&mi5RNc>7vX+{D;d6>u$yo>!?zLcPdLc%O@s#!_AxwCo<}iE(;emv`49_4u zh_Hv@NrVq0>|ppp!W!Yu10YTqL)b$&!SK0+4=3El@EL>$6OJ={GT|c#H!?he@DRfF z3?D^!DB(JW2NV7i;RwS62oED%$#5FsOv2?1@ACm4NjS*x9>PZv_A$JZ@X>^G7~W3! z7{XqLw-7#-u!rHzg#S#~!SE)+#}V%Qjq1OKu$ORx;gy7k6K-SpRl?+il5vJ#AbdRG zMuwjxoJF{v;YSFcK)8i4Bgo6ytA)H|NT*A48+ZaBB@EL^T z44+K+Ou~%}k05*&;d+LTBAiFKj^V+C&n6sUcmUyZ2v;(kMmV2vIm7!d04^XLWOxtZ za|!zx-bwg8!Z{3YCp?<4m*Fjh3kiD|-c0y>!VZQv5x#(M=dY~&3Ht~q7+y)Zh;SRj zuM!?ZIL`13gvSzYWcW$K#f0k_euQud;W~!zBRr09gyFjgk0)Ho@a=?k!sQI#M%Yg{ z$nZ^sFC^?^cpl-42pc;FT*nkmlF0cJc;ndgdGfDNO%I_&V8)?2?q%$7(SQq zM8a(hpFwyM;W)!56P`@Ck>L@9rx31Z_$b0t3D+?^nD8{h5rzj4o=&)u;WWZ!gv%M; zcRuhXgo6z4Av}YykKvt!XA;g~cst=)guM)JAv~L~hvChHFD2|?coX5v2zUO%+MjSa z;RM4g313dQjp0`bUqLv|@C$_J5N>4nNy1kWu4niW!dDTlWB5M8a|uTnzKihHgew`o zoiGhR$#RBoBYX|vAj3Bio=4cn@I1oT63$`x3c}YB_A)$!@Lvdf7@kD{)8(DCm24L@QsAq7(RpWO@!kNpG^2>!i@}%ARHoG&+t)%!-VS?9!&Ta!V!iC z5WbagCBtcis|c4fysr>=KH(t4dkEh~*vIfr!V3uJFua}cLc(5#w-8=L*u(HlJHW(Z4AFk_;$i^hF>5YCEUpHlZ2}Y*E9SG;Tpnq4Btoi z4#E+J?;?CB;Yx;YCtORooZ;ID8-#-l-$eK>!aj!Q5jF|uFnk5!y9s+4oxUoxrF~pxQ*d62;WCI&hW{E?W5UywVD8dgC zu48yG;lB}%Fg$?pLxd|CP9waGa5=;KMgu=gILPoG!jBO4F}#!Tql9x9-cI=MguM)J zA^aF&55t=Y|AVlD;Z1}eC*1iHYk$J^gcA&}B>V*7Hilm%{3PKx!!Hniif|*tPZEBb za6QA15PpVm9mDq#ewJ{A;kyVwN4S#V+X*)iE@${Q!p{>9GJF%^7YO?po=5ma!Z{3I zLHM79y$sJF{1Rag!;=WVOxOWT@vv^XhMqmbq1VJiX+3Q$FrKR&M<$FgIp#{#;$Ez9 zGk&J(BfE9u8$H^6*sW=^*W$rr^7w;$X7?m0en$G|dHN@%^v&Jry0J!Y-g$xUY|}sJ z4zq`c4r94)4(*w(8ykAI)ANzS`FPF|K1q)j_QP#tX?znJi2QFqV}!%{4k4RWfo7V$ z!4*V8=iaq*>ECIo@84w68Sf>TdTe5kUb9&@ zJRx@~9n*8rts5;plX7z7Ov~DFj-n}k<0I7Zr^&kUt8OmIq@4OwP9N9A!^3rRfftFv z{b{CdSOMeP*+sK@620Y{2`raa7IT>1GB%SHD0;dxbOOmDNkc*Na)J)`Lk-+LK@@2w zYDD!R)UjFA6WF60KbXECOwj8HX((ehN%=FCaaI%nu;B+Ay!D&oTyOb2?g>)qfD z{fOH+xb3FLcCg2K%dgfypAz+{KPd~`|6~1Q8RwHl^tRue9zB+E4ytC`Gk|no8xq%M z#P?`r&AdH(@myTa#XS<&E6?nAs+I0=7_Rg?s8_i5*Nkw;@_gEgmgXLhvwJPqgRzeo zZTY9o+dci;*47#OjBX&kdAnC9yhl5^MSdRl7iL*VVNA)|rJKdeq@ z-R&Dc+tl9r#m?~V&)ccXrrJka(Qj`0_%uAr+XqGSpiBds6KS!GV0v+u8)!&uNE>cs zHYYNiYjAN)bHc?gyv>P2*hN-zq941+Zcez_#i-^)e`niTJe_^Yl&qj`bnn$}D9*~k z-$0fd+O=?N6mCtKtLRljTEWHxJ?K7qTD>#v*B-TIs{IXbGOr;ow)bPsf! zL4MNom_9g+VRHJS>3*Z9Xj;+KlHBi#rj#1%rWzklh7->$D)>$}&dSma)NT>#B=k8Z zR(vWtbtuanFt!_On>&tkuKnOwea>24Tb_|sYM#|EVEk;Y*xl0ucQbfwWb}!S&?!X) zpD#Mx_`GAy+`9RDi(}V1A$;NMa9Np6D1Hz5oTAx9mlj>NwvI@nU1F%WNbSqVm+|hd z2n|v0P(MAo#N!NA>9L`&EJ6<|XbWZG+O?2hXX5&j+xRt{{?J$@yAFGyCr{UyU`FUq zdh|A*GYmg8K2ux4mvNZi3PSy^-%dmNSl)^!ov3tvZrmD$7>^a24{LSWit*l#O}+Lf zw)sg@G5yRv47_q*i!9%-;PP*szNC*UoXCu`^jSMje!^Gu_66Sv^SbdVs(z}o}Qwm`+Cr6ZXK%^Bp02JjE_ju-q^GB zdwPdq=>c{tyU1uOTDpy{^=PxRXla5ji<-9$DCyr?v@}j17UttL?xJlnijDF6{RRJ7 zaxWh^>-1PvjvmwX=yo64^OR43(;tj!qXwedSnj-7+=mz4u?~y6Y&Hp(oc^Cc~~=y zf`;jC#4#-0FW)1Avi*%n4<-Cz`i=iHJ%uPE5TZbJQdGh+ScV5|`RJD{KKWSmuc^%W zS>aCB09rLoJap5C{L4_gty*=I5qTL;L#Z`gh|`QOt#eQ_s`|;~y=Km4{XACq?MA1= z+E2BwiR*@I^HU=np$Y`19shwJus-}j+*lui4dlIsyA;wwT7Q^^ZkD23i?DC1Ba{h8 zG714($7719nltL<%sjhxz^OkIDAA4thf!SK$6cet*C} z`16}O*qy(lubc$R+JcJq`ro3de&by}kOho)sWG#4L_o0EP!?PwyPA@P>NAKd>ye$L zZVYH>PObVQ*1QX|Jl19le5`OXif!Eii(##}HWY-D37v#y3>dqui>Y%^&)$){+4=z$ z!viC!p2io}8Fa7ayU?KkXdP<=>qwM0GJ`##DAvnl1aw8i`XOYgp>c%Kw{47h$3iMw zPiRnIOOCF~=EI~tzA!ufK-h<{>$;9c?hj#N&u60@pa!=dJ;a$D#vGHQXd0Skev8wQ zyE!*rG_`07<_^D++B{Y+ue4TO21h{C5!)U;TJ=<-VtM26Ak}RJ>58m;ZRk?aC%r>- zi*+2T=Qq~rW;*qC_;BX3jtC7#>wD}m-nNs;h$yZ^;fycI5x|mB&OWIkXc~ug3TYWx zrlW_}#EXn|T5S`xSuAh;240wvslsU0kI^lZWIeBo-&h}7RBY_9zDe?@H)yp_AW6XZ z9*G=wqIJBR=XTMf=OU>dJ;kY2(;^DYo#xKSZp!Bj?R#GCMyLx@@}hh z2W6re`!UH(`5Q88Zisd~FKSbT$suOPN2vm#uU-Eqv(6$%eV<{m9nDOKvE@$1k zEi@X}uir#nye)*WZD{`+`8CB^g;(?IOzTXv%O08#xIgDjmucIjr^`1fBlHENW^RRd zSl4Gh41bGxDhrC1xV!G8pw6k)(91QtdFrqeNcwKA`Vhj#_ty1jA!xLwi<*FR7#sA~ z&6K89s~*8ja_FJFq+0c0j%V_SPpeMj*qqBstX1z}GJ@r>Nv--Cx@o>j%T&w_loBSX z$FQdcz0T?kOrQHft}Z4Oct1T68Rr_wv>*e$gj`UrpI&R|HdP@JZ-E;dnB$E zThy9{g^{NYf^xsJzWs(o`?Lqw)18@yMPpI~&!Cbwd(3IUt~GA0`T#Oqx}Dx@(P~~} z_s01!!e>UiGeQ?cyWLvN2C#cH&w#$Uw(?9n3>GKf9-&83jN2^oPJSx) zCxj+U8(Xt6Mg0EDiq}W*D^UL7L|B22dkB3Fm{6<&N)IjXiH4{f* z^<-);qE>jnQuE61Sob~}+4^G(Gn|$a1CMZWmt&~L+6hf{W^Sj_ADVKGM}$UUtoG^A z^%wZ0K$T~HU#q^Im9EN* zFc2Lz96}Hw(m8!}rBzd{m}-=O=RzuQpYg5mMkZ<}N&6P9SQDQ= zkNk3YU~eCxc((+~2~vbXJ!qL_oG&}?O9MplEHCbd&og4bQ7lKbjOGsYPWo-o!cT{;QjW=?ZmRu0lO zBo3Xz9*FP@7+Mbq_IX=5N(5~sC_qA6s4 z`POpuO=C@NoIE(~AOy^-8vTgu%1DS2uD34ThN00cK}`^@wFHck2J0eF7sp2D_~&4$ zMmNLthzb0$3CHQtZJqka|LCzxn`8kbM$Bl8QQfp-}0i4NQB9l(GC-Eqq#BQ|J28yVLj*l zqG=_@1}y1NB=Y)?nTvk)c-IL2`LU6=*G3?A&6bVno2G%EU#b z7mXOK9h)V(j>Bn%NwJ7I7Ew`I@N8@W){XVng{PXvM@3LH~X^IcVl zo`SEm&Ll~g^Pf*0AN8|c9~Oo9JcrHG`bY?`>h1X*uiE_>Ia{Ale=yd-Ca*h|8PZ<7 zHj6<7-RD{qFL!Il!?u00cxSrD9210nUyj%=!x6^3af}aBQZ^FiVI&M+i%~F*N|t;J z{fhZfie^5amF31A@-1}ladt04t%UK9rN@GAvX;@pf19r7k6}f60bhLWUHkb6rp)?6 z=2|q@fxlv?a>A7ACR;Q9OLZZ(^=LSt7a`0%!k|dSF>@{MpPRbhK=)0$AECQOI_^_w zWer1;r~_t=Ss6u#lE0d4?b~Y0ub}5I!t*Uy^MFCjp}^WPGui!RZ~RJ~4<^N?$*A-N z4y~5<8gsV_eMZ+h^*O)#qoemb=I^x*BiS|Re(OVLM?0MJkF4uBpSP3WEX@QH{S|e~ zNQScYIURm;^e!uayzoT$OFuc-5N%d4L#IB(#xI}%g*uFwTjw`RfOoSEhmMc1%(S(` zkn2}8g*%jwsC&ioT=<+&Zk(0g8;Fr>GPYS2FlKbOS-LqYtE*&^H*^J*eLNz%fO#b* zf(Gx7XoJv+y`6-*Dmr3|&r3@3M>DdV0i!(I`js^Ybx$u9GUW$>`FIYd7|JzWPaH)> znp%cp-Gn7IZl3=^qoYqF2H^HmWPG5T6A+TqDp6+%jSg@wEy=IHpf>Tr8+22W*w9b8 z2QO-((C|%aK+I8-|3h6i*L{sl;_iOyRgSj14CXvK=7|Ute08ThJzAvqzbP z^5}G?Zbp2_w#XvJ#)M=RAGqt?DCGyx#dc_m9S2*sV^J-U)haN|u*T z*Wqsp(Nr{36?5u~xwV9D>@z(LA$TC;Ig>^!ub6I+&a!+|o|>(QzLiNB8cSzGC-ez> zqBsFtR?Xb+*z++aGyKnv&w2ZySou_}9CDZ0*3;-VlpPjI7&oX14M9`)?2_D#exu!* zgUMI&N){~0_0?my!T<`NMry=y?|sUft5+Yoc`Mdr3jfOQzx@0AeCp)2z9Ln`3acnv z3{&VPkhl1E=_%elKtbKdh;^~>v>0Z!*BVDg8|_A4T(4Er-Z(9sSvi8m6ke;|%UIWy znK0Udu~>Fp2_jJNjdpJVTHbGt^O!+QE4<-jqua4SK%X`6kKE-q{^BS#uEI#g2SLn< zzSC;Q<0dA$XyDCNm--7nT6~30X6`zUgvaulVl=bf&N~G8TXcw3!oOID^4_RbUjkj? znGc7t0wGH}Q_weLMnChL7iZJ@>=Rg;^77R%yZ^mHPsZ{deS`Hq>n2zSFD4d3F17ou z^(ZNUrfEGii!fbtcz&7T2LP_;BF+;cPKO9+T|>$2{)I$zC63R6tkPNFk&NW4AY~b zMYIt1I`*NUC3vRLR6UyQ#0r_Y$YH&ga-HFq{n1fb&d_CikW2Y*Gz(j|YO}{<^LO*1 zd-!~4eYSNvD-FvwY}oUib(vULO3Cxn!VyZ&2ZRUeil*~`5w_0O8S(>jo})Eg^G-U_ zVq|1dEwBDalpfYk-`~&ev8HeeBNxpIGPUZLI6vCvH)z#QfGWxD!GhqDBa?Jug|%mC z=7mPaFaBtYv$SCU;w1s28+&mXdU`a16f}{2lUr2yBShHdp91D}SpJLdbfPo(jX!DC z10b~&>xM)9=4{yKWat$)raH9hb`pR)M{-v*m``jnun$9PzdAy6bo+d}tFgcdgLp<3 z%2<;7HEW)XtR*KUTUk;0_yWtW4Z)85(REIgIXh60m8ISDEK*Pun|^bpZk`{xAS?7G z4;p{t1G-l2W44FIM9hKNys2y4K!m9q{95sERtrp!_AU|R9@qHTnG4Vg6j$B!&XmSfPZy!qe0|Ij_r>v$S z4}Iezm|XH{+(id@pa1-erRDWyP^Uy4G--Axkl70#V zS_@fK7UTm1B4EQ3?O3+0kXoU|EP@||;0w5UU1KLYapb^UkZqkt-9jDkg#Y3D4zH!` zp5eNVW;>1*_{qNGBQs-j30oi@WL;0a+1`gST`hxAa7@71CQxsEam0e9cUk9CdUEZr ze}D_xl(`#>JRULqP`rp_IWz#ftp4I5R(H(bQCZT$u~fspLpupP56a~6G3(b`)cURN zTOXR(xn6ICXNwIA;-seBTVYvCcV(hGknL6I*hjC#X%F3~&Wcb|#2(1%WWUu}*p+hx zVs~fN0|#Q_eoJ*0i;^h~tPYdHDOox_l_17+HG8O;tJy=aLg<4H=?`SJ(S6)##4r7$ z>o~jO*L0u$k<=jl@zI|g`s1ZPm_hM}Nn$qT7^l>blE5$hqw7w7$)sQ*lNXk5P-W;J zJ&mz{=((>zJLm#1?(;F8(^!;|=5Rz7OvJj~&4(bN$!op=hNnk=!ItR}#KxBPV5rdx z4Lbha|dP7+?|G{o%KAs_2diRp=T%$`VUf&x0z1j>yV-}mXU!T&h1lM zb-1=-KC;{3Zrb@qhVsI&ad-(=9x za}+PIp91pYtSYVgGl+yw;H&quHq%746JFZ*jm|`r)^wG|M)zBCT=G*Sn_D;fxX^Te zbiEh8&x2?Nu2if3H!IU?ywzeiq#>^R-mR?~9tmbW==0s-yR^T4?_W(I) zs&%VAr*-t9exuYAeg>sI;DvQx^9A*$ynTm_aIl?ozd=)$pRFHQ(S9y6#=EVW_i3l3 zpLHr9UbN~8=3f_PRaraVLk~@zZ?O)wQ_Rb7IGUKR4fYA9f02DvzBPcM7n`m z^-h?-zom%1tWwlclu0VX?=j-ni^j%yiw^NDE&@h7>;`t?j|C3N?6{x~`D7JqD{eah z?Vepkrk={nQjzy>&8SZ$2WWZ1)bQ>k8W_ndVbENs?jsU@i<8l zj~*|6N9Zj@*v~@2xTwIK?$L(_jDm24%uSpL>8OWaoe-OK3Po%&8yue8ZEYvFP9Yl})vBNVjharU zp|r(13D$_HhWm&BI&gwLkIn}HJJ|T;$8HY#42rPWZl{5Wzq z@;GElf7V*siko;}|CaUjPT-#Y^cU0bDW#6)Z{7Vnjp9**z-*r zKhZaCO2x_IesTudmak8+=aV#Dl<{){Pexp|>@2ht+JGYUPY_T%_Aj(?be9jU|DYSI zT(Llwy%@$;#6%c_l?@ivu*hQ_x(#d*y@oiraExq)uQiad(2jud1)`H61(j?!2n zD2F)h1?akY?8bg%kSGmRD2G<}ye+5?%n7w0Lc7(6QhAM86s66|%CS1(Wl*R2dI2cR zTj$WRj}F*5)en`#;*lR`S&i>=w=b+HErbM!HLQg~0 zuO7ns%cF}}2eZ^=79v*nGfl*hY#Jqq|Ud zyG5;mtd3eW{by$a<{U4%_3ArW7Ym`)F^b=|iM1M^&gy1`H(;K650#bn0|EsVnYz)T zRkKbK%lq%Mq`}=*2}TGsHTG4sYB~>LWxzhzz9W=F!Ohd85v&~^vw<`tveI}~p#daT ztM;;D&}o-g-cL`{0+@9yJ;qE(tV7X0E9oDDxWl@^&UHNwQjt)$4ZFkolvT27EM#aMDZgf)Ye+6YEmGsx|JtnW_#2tr6{uEnBq>H7UrYTaDE8=+H+%3upv) z@^n06=LZY}piMB^Uwnq%G2r2LW$YThyoefa+>PryWPjYZkC z&nRuMr+zw86`3UgWKxP(V4?{pcAuLPWEw|q#!1y~ed(GuLQ8*jX5&XIZL@wv7ON|$ z$}73S;hc(#GK1I_id-D4eo6;!@wstLzaI7r&A0e61?A=2n7L`yQz*|^;UVL&Q}x4IrUhtHs~!#BicsT_TB=ZCEGS`Q zn}fymylGgwLx0tc$z^<*X>vJ!F=$P$z%N>UawUG@OeR<17jeb?5#)_ac#r#Q`DH#X z>-eP)m&^F2jwq}Fmzd>Eo`P0vi8cb!KU_BPE4qx^m&X0|xYUg;=;k@N(Q4nY7jf)2 zY+A;8=~lp)lie~lzY!JMFgEDqGyHU?wH{SPO>2wc7ZKSsSXc78V=ksupAOQx+4iI* zIFTutZxBfT1}Whl_QEGB_fK_s?VVus6~h40{eqmjJ1euDPg+nn8E!dvyS)ioZnmm zXXN^NESjUBB{T%}X~(s7CNFgLizGYddOCN6!(T8CXPhYB!|JD-iI0}FVj&heS0fMW zeJU2;zPuH34#R&diX3d~YF64-n)sTm0;M%QftWw-Vq;+|&Q-OsEb{*Q9I0`4z$lGd z58{!4SxN&YG}Z)dm0xUxS}}dXaHG|nk3P{msPy%ym z1K%2{rzTEmO9_@)Hj+J>Rpk_ziXc0WR7eGB@s*>rq)ukJ;2PC43#|Q0a=VgaP%O)| zdtFImcq81Nd0;pzQXuBqhvT>?K`k70b;ETJ6m-23Ai1A(Id6Ba5XKQtkYw@A-1?lh%-;rq=tN>ky6>wPa+ScHK2s6m2NZ%0NlKv>tk!_ogm3mQ8IG2RI^} zHgN#Uw1@-h@TXGk61-I3lCq!Fd}ybOBvH5gG+r=MygOP46dsRxch&II9=;Cp@GVC(*N$8NHaj+xw$v zA6V${{bZr}$!(zOppWM%{YUowSmAua>w59VFMwa`#RYVqb`(T;k0ks+Fa8DHFj;M5 ztSj$h`B^{wo5t{D0Cyz&$F#&<1B(e|wb24^JH23)pfCyjt~jeTfGb2?fvirm;>1v&_rKV2Ds~_OGagrr&i<3b{fKhL#XYn(vPaiWcHM_t zd$dbjn<+ee>%|xNKinGC$(Ff{yh?glTaGT*ssH?y=_;q=yT*rlbBBw@s#hRMdoVuQ zS;UqV-W&mZfnM|iBmR|%o(i&kO0 zc7%r~X>1YY#=O}BDd~`cJuA4Oz0Zaw;zZxd0VKuvo}%o_U@=tx@CVqh!vM-&1+e-< zT@(NhUrFb|EyLx`Lha1FZ8-T{j5GDx^1LowCZB?#p}5b|d0AQv-<})iVyx#-GK75L z<&n`@B}Li;>q@j0yE>l0UBsBn`^3}A`?ISXP&yhnQm@eB{RDe_4)w=rQ1)JNE=US@ zSW273+d>O)hLyO(<(G}wctQ&x6pxGd#pq-jRw%^#$^)=YQPlGh0&CbL-&+IqJ*U{d z6Bj!eVxhPMTTJ14W^$$Vr|1D^=#=Pzw9skM0~w**=m9r{1ck@m;B*A7$DwcAZ<+jk zQ@lUQ=84)H{1oL*|K%sj5MQT5c-pIJ@O<`ecL+3;zwNSXzGFOmw z;1Hx<@F79~jAqY+!6^{5M)ZHYKk+MBQ|#0$aljHUPgny+oMN^UT-HN=#>b`A{2tqnIq`u;Uu8 zT*{A6jNNP5y9YU;e0uM|=?End31h8r=uc;nFuX$cen%to4_)K%J|s>!EXlD7pxxeh z#B^Q0m(}qMQT~;%5xB7@xZQS*$L9OVIE047Ye%56)sz^SqccWW;Y`;ny_8SX*Yz%! zdFKO6Z`NEUldFune{X;68XwF-5RKgrCKc3sV*99d&^u*-YZ9;So8eh;X@c{UI>dY`++#%ylzV|8%EfGi7bYX|C zT&tlE;jlHt4{_l)tFt2b)u}VAp$h}AflxTk-(qG7>1|Ly)>7SFx6|AUi~erp!Uw!d zVRn3K!&Z;{SfR3Ydo9FxibuaiiG{w3MBO(R~tk)pYjty-T ziX?-|IG-!>7+jZ)=GPd1hu)1TFqEp*oI`!r9E+Eef|#<61Y&jvlj%?LV|lazPP&}| z-H7^-YWM(?+TXCL7Lm%#B`JF=fA=bl6&bih% zP&{n_xs#t`RF~`z>p?%!dX?LnL`j$r#0C>)rQ6B3(rn#T&jtQS#$jNGgN{9im|Hr< z89EGQ!EwCa{$Nj11kcQ;*WQueH*{w36ZVeGgnONQ#OBM+pIX16)_UQOXwX~o{4{GZ z3%AUJhGTj6BliG%Vc{1x;#`%$G8jJuh;#70`io6TAAvO}%-KGoSW5Fpzv)D^N@KH~ zMH@;S1MtG7(ODWRP4mYF9@23*!dPcf?L=&WHaqgDQAq z%(eP^NHV8qlQi8JkKdD>p{aIZxPQfWR!)H%%ZB%+m7Q!Tf`xCNu_HYnig|8b$40IP ze0OCv^Tsc}3~&4z$ZC25+1N9ATfE|b*!-eM`X+YXWmGv9pd2+pn95D+<*teEws~wSChW99)T~UHJfj=n$>t5 zrxvn;baS_E&cfc1(PdS!6k1IiE5~&>TvC7?j?*Eg2$QP=h?KQE1_IF*Ly%tA(F;DO zB|GinkFEW@yqQJO{jOV2heJ80UK30s30wZmA^!bU_V=B_+>Bn^9svb7IoHn)Wb~IS-bwXQXuXL-0E0v#~+7M zddwx#AvF0iIS-~cDC+UJwj!RaVxGlH54j(?T=`^oBOvh zR1r*uu)Z7e(_!O??p(vu7p%E;f;HwvswiHTENt8fL%JW?x0E0m#+GID7fO4BGNe9W zyF9Gdyn_bh@p8@P(8`Xl?S5psuHnTSB8qnf6o|Njzc7*Nzr0^A@mM!A4_&zHD(3C3 zx)ODwDBL=0wBY4$;m-km{ zI|!#ShV+pM|}1K(TiSv&xUHwGaw- zf(fSOCX?YKt#JP0?Igt0)}u&=7zL9jtDMrAg`dq~CUM&pD8JEMYFIc`1H;$@d+vx^ z=kY|Z@kF2AMTy96KBU`E)FI%WoZHn?mqY$X%y0(b+Iou0Lw*gR7JJD!c5~UvAXMP% z!WkpuXRYQ323pdznxFYqhF0Ukqs9lh@#bWD*P4vI`ip$MyK7Bacu{n_GhB&f#)r?t z833`5AuSmH!3M_IKHC;}5A6?jE_CB&Y3BmF7ZdTi(%iZY{Tv-8vuAugC2g)T{s4-h zRfpj;I=%wm(hp^amA7P|jQI2b@gJ)1Yw!aD5lXpXY#EGu!6mOwV4okZ%iTzFqdOsb z!hz(^DgVdiMt9;cO-n{Hnd14z8qUZ|3lYqO&c*nwRTok-#PaqTv{s8lh1SA`lr7A_ z+=ar<0yYt93tfrp7?0UQ*mfGaEtiFwA?&*i9ZKI`KwR$=^R#EaW%hYTIhvovXCG1X z($aDDtEd%L+o`YN;G#YHvD4hlPfVuo7UhWd*P{zEF$ceZm9nt$Bzk3Ok=y!|7m`hz zDWu2tL@2`_?FUDQ&&c47X^cATjipj!t_Me~GW{*%yrfOPacNGeu{ht#BMGcH{{n56 zcraenT!Y5&n~U)@4p&-f&%@78110>I9Y-cF0GEmn%t;=9Y*7xqp}7>2tX=4dvgCTWKn_5nY6%{NSUw_OI^rM{i?00xuf zTP#fk`5;}YJm<^h;U4G{lpUo=lG*X`5psX{n#sNVPSz&Y70*H9HIPVKADv7x^v{>6 z3a6IaOB!!Ii{j%07jTg|dbBE&roSwh3ZIRYjzLI=xpLQK_+d*Z_-+pSevWG|QD)&l zB(QE}Lm3WF|Cw|VD}4V_EDWT9L_A>}pbY{3rg!ps;^?0|9%aro=vz!XtTxmJX4B{U z3iie^Tj9mjV!Wr=EXO(e3U}$8A4&b!KE>3Jy{ypa68p?w?$+GzIx=az@zYz7c$MAA zI7*MMbr%$Ovmh9@Y-nD5Jx+j*i1b{i182oT>P9SjG`CeRbrQ zBX8Li(;uhbuOTLZ;`}#i<&5rs%g5S^^r&^&=wY|cfkhniAU-6uB97NHmg>&to^5(` zp9_v1V;Zgw3H#7N4y%D7BA_*3VbF6w6vabDiRCR`>U6Bcd2V)l9>0AUZXZr65$ha0 z5uwdhYk{!tk*e6?vY9FBh8&IMR-Av8YJashNVxe(Wp1!<>g zHAnN(P$XhEG!APxk~1iaSl-zbZlh735<=WD8HykCME{liZGeMM;K-+#uLLaC})>0B?d5d}CheVbwBJtHcF{v~;6W8!B>=2*5rV}vd`e@Cpmfp?i z8aK%oE=Od7uaDrc;=j;JsKqGu)miNBthJgS1A}4bB>qxzY(WnH^hV#01>j|$Y*Z)p z#Q^@^bjsgi+&l7%;nbQd%TRg5+wrDhD8WyYtrH;=RiUZgiT1117%2O^Vr{>A zooy|9oYjZMkF|V0M&ELrm=PL-PviM$Z5E9XIySn`6P}Fy6`eL&9M+RGP{S+o`4;wN zbbM#j#$d+C=840ydXYDS5Yu0ytCJTBLAiTW%{0kJlOo_ zAFMsz<@!c?Z+K-#drF@)VaC~u*G@(Tbh>xYJRIpo?g?}n@z$r#4)W5WQ0TN63yfIh z@Y2y~OgnaQ)2#lQ)g618SWt*i0SZ13-OS#9M|G#;BMPN>Ptjv7LScAA@$WLy3qttR zNr?liZHU_F?Mv(v;pKfW0s3eKdq;k(msE?hOgXU4e5;*VOgnUdW39il$70$i&HI`@ zl0e`1#X|34)-B9M;WH_ak5z2!Hz1eDPP&0&?gmL{c?U=)4uEF(oe2sywXOoUA zbh9QxGSJ^=LBaUgl9(LQbb%%!{DY`Ye18oNjKcE12d;01YUo%Z{UF86*~v5%4e_N| z0uMc$>hJxj7FhpYz!fp$?~ujUt~*xJ`dsoec7K7me=gm};coHaQu`d}5#iV$oMmRk z;Hi^yxq4;$XML&UL~4H8c;b5@57L%5_Cl}~LhGFPQt4?p1z_x3x(yRxM+isnCuP&y zTl8_LjniN4v-l!dQXIojbTzhY`D z90FzbS+*i4bAf}tM?2k(&N>jAA29lXqWS8qLwOGjEpLMAq;oy^t_Z}U-KN~e+wI9m zaC?hz4-b+)V?*B~+l%FOAPFt9amPSMrP!Hy+b5JE3)mUnYb8Hn25G|CNw14z{j_Ur z(1Y(Q#0tl<7Q%Vc^y@G>t$!Sq!!tuzFEl_KWr*o~URWm@LwsI==C7jvq3=c5J$(Q1 zQ&#S4M7ei9%>3OZyWL##`Tb3kc)d39`!DeOaB=*N0IH79PoM2!^F-=OM^m%W%L+8wV7D`bfO_y~tyEp(3`bBF#5x{2n?Uy^%XY z?5xv78@=>w3_bUbpkCUF{nyx_ue|*F&$u2&UpN4d{an|zAET65lNI{JfQiRH(5h)a z5uyW31n^ph^Zw4n{Ge6SIt0eK|KMW>fr4hO`YCpQ(A&pz(HfOufR2~$T!Dgk_;1MR zVamzOvF1NWD(I$Tg5vvq@Ol29|I5Btf$v7VNs{PWMK}sf@dI3eMxTLM$qk1>f7ttE zWE9YrZx5u;$+SKpBOn_)8-0+!C}EVt=JD|)Ve_nd@G}$;(3p+4xJA$`~$I+AdC{C*16n(_(=H#Fg3U4m!jb$qM(01Da#4pxcWTe8LwQ8ChB`?Px zTRxmEzS94SU9RMlqi<>-UNCi z-#X-PY;f)V4aH^uQt_zxJ_+mA*yzORvDnb|;b`ONF7$;Wcfh;>owO}; z#)gJ?fJNVn8QL&}Y@#hRR_qDAZ`}c3NNcBGR~@&ih&A^PYs3S@VWy3hlW9BXdj45+ z>zYu%o{sBM`bD0!MU3^fJDHM;@GbyCC|qN)49A@*h{6Dkolf+l^?`y8{yvm;@jLWY zJ@!exW@_=1{OQ=lhvPvDS`VRPvGZQ{lN!)HgVeU{pc>ISXy|PIW~Q^-h0Zpkyu5Vp ziSL4x^8~p(0UF@mN6~uck_|}u6f4{a6X7X8mfYk`aFaMvPeYX+T_xP)KY;>f-h&YB zH_x^T??X|X05{7UNbyQhQ{xo9=EmADNo_O*ri%}p zB}YIYk29I$jWJ2C4Q<0kd3n$15+gw$9f=XPRwd8lB=2AU5}FETzYnijxkfkeY$ zk&b-rUi5%WD@N@>yAt>;3BEmMEdq{(vgw=cd(cbhb0u@StbXti&?%-{?bH1~D5LS}DFl!2*g2nKjrGdA(=U~CNrPx?7g?%#5+5$VoE(H7X9c=(& zxo)T5iN*02YqfOiB77ZhB)+VN@8ZR#;+tTbttW67+J&1G+b8Uc|4RSIr{jlaqbBrP zAAe;rmRE5Tng`!0OntEH4S00&zN|||7hn>{zh8r~?Psiw!~Q}`tTgx-I)O-K^jO7& zNF{h5xPdI*JSGdVj5mB5RCg=pH&z-q#6JvSvJpKaUXCu%9rNGO&6!@^I3|le5*2|s zly6-&jmT15)BGMYuA|5#QuD}N$b}AFrtH^r{gu+;v#T(J4HqFT^QG%}x;w4&P*-{j z5$^%KPwDV2cpRpoDbg>g#NQuQ9EVo>AYJ3@RbD-I>?Ld}hOoS#-TwaV&}Zn|Wi*N5-@hID6Zk6zu{QZtuSw1#=)5k&$kzo%~iVVNBvP6bwu?(ls>z=Q%LQ<`LR+wxR z(ciyg^o#Es(XZ*6`!3W<8_G-9kv?fYg%x!^J}jq#(77-OK=be_)Au~sZZzG*hf7Ee zcGYT5AZH|=59#b#j4e8nKxL=_P1b$MOOdMAU!o9~{|ALYueiYpQTf(N)C7Y_Z;ALv zqsH=7L*Q7rMcqVU5UR5CZe}b6lsQkD$&)70B0TAMB!!W_NXgGju$D3AVpIp0I`!gf5|#p#O{ivZB;Nu?1z=kMyBxn6i%5>9=KUFyezkTgGOS zV&SZCKG_;thcAa-JEf01Lf7@7b?H1GJEM2`k;0_f@f_R|`(7Br3R=%`(Kolq{-5Ue z@&+;-uEMi0rN#Mr%eWlM55N3SB#w=G=|lt0hrNUL6Q>ejKlpH(FW8V13bT1FeJ6Vy ztsZ@KC`rVL$anwnd}SN9k~?1JdWYPJn;M(at|&Zwa{A3Bcg)Qh0fT%2Ql za~C3oN>Y>QI-EbZeGGqY9=8uNJB&w@$w1+W@eOY$oqNQ8tcg}z^5F*&7vdb$m)0-X zu3?TAH^TOR{)tTsu+EVBGNA1z#d^$Y8#8^g?{D(|uF159etbOzpX0m&Dxr^4(|cW* z*7@i|A^148R{baRTK0kJTwGvvkAI+ga}yAK78@U^UZWMS5p|D%ge~GsDE3Mp#4jC$ zwf%3`x{T0QEbQmYhJ3)p(xFzf4Ua*#hbXP6*@T!itp|3Sfcc>wMrZw z$5LhQdo^Yn&mSF%*9p5x7@v@qzPp|5K%XRg)>fo-;M<%I?TxgK5AkcJb^Hfqc?=ud zRy{liu8XK#58zt0e{SQ<-d`6XwGWor{|IL5SaiYn-~01xve+9%f2pZQrD0{5)%0k! zZxevZlQ)^DR~`L#B+LtgUCrJQ=ApOIDLAc`^ae%J!b_EpB`!f?R==+1INk=qf2f8P zpqu@d+iK}ER|VbSQ+{q{hlmfw6bg$w=tz1{EC^xzSd0as9?ghwJ4RkUp}YukLw2s= zEv&!nEarB96U>+eBHz&)|71F=FlG;XyjyufzNJG~nh9!;RD{ z`E=A4{>}rJMEx4?r%s(Zb?Vg2_jP!tcIL908um913h*B9 z7RP+9GaE4I{eLnNkP=;>=6bFD=Vn0U2jP2a$7|ip(oJPcLd6|;ly<9qnYH$wvMwCn!e!L7W z!(8!90w|oh0y{A0l+%PJE^a<=8*myFcjf3=ZrR z?=3umi+qw{v-73sq`D`3v&FDX@i~ zEftJf>zBjZr~{ALhfL+M_HZ zc@%C<4Z+fbvqu4H$ zH-5*z+#8gsJ^-CY`$(mJrI_3avcX^&i6bl%p?xBe*w{!y-7|H~|3_SHt;|8T(|0r) zWU|2aGWGUI`Ya|A+Wb&GbQ8(snn+69S$t1|kdyF{3Yd8B#dOe^cmg~C6B7#`NU`eB z?dSTtq1lh;vOuZ3JnV*PXw7vBjrz_^+G2W5Tx(69Ib=S4pgk{fny>>fslIv;FzEo6 z?D?bw^oar%<6?e}-h_gmA)nvS$RNy!cbLHoSU^5>Kf$rh6u=zm&aW-99s zfwf9W4T@yXP>vk?ZLobcR(99r49j&hwO~Tqv3_I<&#`sXV%gUUTdn_#WnU}Y(bUn! zvac0J@`ad!OhiTr$-b)S^B&3z{mxPO5c?Z3E8RkA-L@wWo`EeJ3u1LG?DFn~06%7aO(b)C zq`4{GqgoAmSJ^TPvzqsig%(0jBilHaO}g0e743(Gd=wiPq_Y4geft2P>Ek1qnb22` zk4T3?MmqSF=lWdu`HpV&o6hf*Gfx8r+z8d`dzyaJhZnh{nGc_H>P5dggsk@%rKVk6RL7t4jK=~EnAeQje%UXiG{`&~(ad?39m z4F+FuOquegR?yum6Y=W4g6pRfss(4)F8s_KG0S)$ zb69@F8}m|lvmevmD|R;?ob$y(I7jhRD*P9ibrB0wcE)vXqa`29rzg$L(9y;3D}jJ? zK9bFx3CiNehW1_jYf$zijrP(206oEG%$kG6lVeMv$hklh+))$u_u`22IZ786sk%(% z+Y`wif1VnK`zOyJ|H^LommyVC8$HjR+H60H&Q<1VD28}Y|gskYv6-k|2rsqIT< zDFM4gbYh0u-HAlorOB1q_mC7l6QlJGBp#zzV z+`3^|1uK20IOd-3L7#exdXQ`ASf*CWqyGE$X$*h+4Mf8vVA-Iy`@k7WwEWNFOA(;^ z!dk3D+@Z0lM&;%YkR0>b?`C|(zh%w!F|&a;XA=mBf6EfFgV*@Cc!9N%f<^np#|GzR zKjS$Z--Sn!qU&rR^Cj?|>Hc=S%M9_scxDwUkCn?#M)&Py$d&G!xKLA1ruv0bNbcR0 zjGbRB$vz}M*ENOim zzn%J4XS|N=Nr(jB z7$@#IJ)W)|M=b;6etu+L%e4IQ`^0vpA{POuc6o2MU`7`;WTxOvJsr|~;Ff72?bq?7mmx+^fs?-tnMrWdNB#p-4KnnOrj-sP)K>!Y=KE&> zQ?%zPMGXfJEsx?_lsW}-%3OzrgNqp^ z(fsp@7!$U!;PwYQ{i>t!UOlod2u%y+Ky=|z3rsW|cLIEhOuI!*Q5YR8yx72PxH!8} zzL)*yW}47lkcY$YdJrM@Rk5ZO(fk2~jnA%kS$gobr*c?t{NC0Jj`Z$3a-3|pO`k^d zInNYcNLhOdmXHZc(Wtq$luP8OJ^Q|mshS|ZcX)$L1;-&#RdzB?VPiLb1sca}ZQwLy zn#VtU;>jHFs4L$-Z<6#Nd8=nGWxwl!p2*mqy*szNN*Nt)F%j%P{1@ipaa5E>1lgrW znZw~hMCIA6L0(La8W(9gcAWnu9BGn`T=|Q=hkziGnaa5m`ddG)c5hCe#R|vQ2Af;U z$n91x8ca=PTbrRDWwhmCi!KwbQmY$M<%IP`0EjsL_1e|z7OtdoeuS=5A27Q9@jyq{ zXD+ct%ZrYWS-x<^UXADT>{<86%>xY(C+ zw=_d9zNQQ**|_uj1jXvf)6T2nOM9|Z%M|{E>9c8J26;@i!9e zwx;tEgGAB)f(*|$Z%qcm>lzv2tvy0YOcuLoj;ZIWEn?Yx20b+QjO|J%i0|Oqy*XB5 zBsmTez3dO;GZ>e(EnP2jmxZe1HzK6ZNA)_=(WE#pUpW>P7vol6Ts&A7y1{wel^v^3 z9X^&XdOSLH%vh$aV8UXE4lVarV*`Y4rQw_f)035YkPyYiWvZtvulce01+gc^+WF0k zQeOskW6>@3>ZG~t?{@cpK<$AEu_%`8UVv!hDz@W7MQt(tk%5MDi*DMfU`(m`+;~1+ z>$@>-eP{QicdqYBuFjLdbp8`-w!m0C%YWja&F)$L6O+Gk&)wE{Ur8s+RGyC2#c6)K zL+*!#NkGV5-;LdBeP`#DY<+iGO@UkArSs&2*8=vbD_q~{0=I7KyAfL7?Z(3G@L+*f zpaojGN4NI)+z@=mn~k;ENH;D>FAvhoEPace3-d z+^TaQcR5BhlSzkQ3iHSjk$oq7BAG%yC>-pvj@;kXbCIiOI9Y6cT=?zX_`t{n2ukZ+ zCIqVHN1EHtvN4|pfjNn#6q>eCfJNQZdcu1RjL0DQnkbq+W@7qJvkh-g)>XZy;9o`4 zPaK&k*u%M%e4JXmIJ;Y2W(1Qgu-3lR(b%+}aQlTvq=(|!zt%tXJTXx7pxTyc`!Q4! zf1$4Ws*k4cRF~S+86Rcpr}dd%(Kl8wVz=hePBWrZU202LLC$B6&n}SNI$e1D zT}J6O`#B1&z<#Dyy0{2|>l_-ZPuBrU=tNeCG|T2lyBT>a{}RQ+p8N*YI_DB|k=TZL zP0LMNn)`3iar(pQy@Sf-vB3Rju8TUIfX!qXq+Qu*&+;#)b8fW8wuNsju&~QP2QE-Mw?x|GI_DJnC!g<~X9vP{sKb+&l9ZWWbN@`gF{#LG*D}W^42e z1P+HDi>S7rhCbB1pgVe^?lP*MZH1oQ)FLR~&c$?QyE{Y%WUmpAE;Tzbda@2E;`@_> zAFHzYt{=fqLUhW-&%DFL)FFO+e-z8{&{~^g9|^I;cQH6vIn$ee9rz@e1aB0 z8eaVa>4KwMsWQ)Bszx`1UDR&)oBsdfR%QfjVKxYV`8_2W>kd)IO|B!H# z6CPeiXTKi?zP-%J<;Ch3_aE<`PrLZPh-g7Ori%r98;15dUNS#dpWfS*zs(3R+`mla zg+Et^xp37`b4k9-cdhb;Q%R#T+f;J6n1R3Wn12-Si8CpPcizm+ z7^tyO=hJ!T5DB<-!eHgz^XXSeuN_6N8E~&eaBp4$dUew0Js~fLK7s%AIZk&A?Xx9+ z&Qhu9EB|Sum-&0<(97s&^pc0{G7+ltG>MmxKd2E(Yr}gUlp;YSS~}v+c|=o+*z{9y zkuxx|0}MAU6b0=(P=)35>S>A?Na}9_sFMzrwx6PByhNyP7oQQAo!_ zsZ{c*@XR}{zV{=pzDL1q``umoTw&CGUln}+qcHDin^hg6&H$yk?Wb!|WBfaqTG{-h z^3$zw|5GKsQ2ksT2B{}=pl)BXP^{E)AH zah_qfeB+0W!h|#8`}=Enb@D@*d;8z`;eT$o`u;uI)%Q2*>&6dN?)$UB_g`Ckt&pvw zlOK91Er%a|uX)n=VVo82e|nV4*$Q`czz^l(nEwlYsGHQCA5LeZ4t{V8s;Vcwt5}nE z35XgnRoUk@`q_;iCNN;O;)j2HNv0fr`0n%IJ>Z9iwZVJ957Ryf-v3|l!!`H)pYX#M zw*o?@^2>qw#t$D069GT$>c**;{8I9v*u91Pu;xePL)6u`tj^W&x916=|=P}j-s5;%9Nbbrbzj_ zc4`_+z=`Cslg~Nl2cP~64QDFrM&%nlcM&d~{B`FC|LVRU9DLu{2ky4)Jh!>GwU#r}?ru3&*J{b%;{WbR zhEo2M5JBM-JCWig?^KO$`l(C3#|&g5BZ|nFC8f%57dwk(G}yk4{$w99Fh z!43!9W@*fSl7DXg6M8cJ|18F4{;TE3_W2Id*pp96ENDFbtOe;98rpGEYXivt#!Lsy z0B?{1q=35$DpSF-qR_Q0j1NL=85e@_Nrtn{@2Q&vLS=z#+kfNKj*iD9t#v6j&=j8O zzHed$V5d7~NUL~&TmhG5+o&nj2mV)nxc^34>&6d#+*F;*566Y{5BTAZPz!Dp(K03L zLM^M>z5jF#l}ZZ#-}8h2YYZR_nfZAwqWk~K4N(+KDHO&G;LBg7;U#{!+VR7);d{sr z+f1|!-T2}6Vj4I92|bzq*N@B>P5yEyKhFP49P@HUnHKjMeW78_P!hyRuz$l1jY z&uXCL@WW%_d&mzPPqqx*_+gfq#?601Pp1EG8GO*>H}uc(!;a#Z|AimsG84cLf;`{{ zp8o&y!*e60 zIw}tiY<12Q+)I|b9@8k+3MTdh{n<(!G;@?aT$i+O7uY$G_@#gi!iTlWUQ!Z`e}^Z( zzf=PR%gCgMVQWsZm|IW{9S+AI-<>@E_78xZsf?Ky&2ay)lbk3H$7|v1?)%xn_kH*t zV)_KtVe4D}7}p**Ic6$%6zKr$fWM-Hv%QLNE2J9ETc1nmqk4 z_LZ8k^bTY9XZ$7SpLzQ7Q77sAM-2^WLnv<~OWGo;ZyPnPfFFN2V1f$NZ!cl?%}n7= z!+|hey+y9>>^Bjl$UoYR3mkj5x(91oM29)LX-kI%+LGq8>PM^+Zv6So-=D5<&h#>8 zUm`wrXkP+JAwJpM9E*inC$m#KG%xreOGr?=v-2FwN)*$olnY$~&SPLaZ=r7(L+zMH zPW{z;1CM`@v;cx}Xv|{I%pMMIRG;kG(bN{VgJDN^#@D7tm!)Fm{i;jgl-Tx{?it^( zkC!-`m+C(JYsQmdy+7^&&O?&XW%~4zRn^+my|gH`RH0RB@~V6CTDy>cSgxl--1r8< z&f-ieAS1d&!Arg*j|A!}3hK(t{TRtD=f7DWK&aaIW_HQjd*?K|#_pqny<|nF+C0=fRv@v~Lg}0y{09x51f0>IWiXwehz!WssD~g*0Arhih zFMC(s1U$7fr?0fPnKd8 z@)sMWuL$MQ%*gym{^okPtgSw;zfw}8E4;^bz?({g*4Sci)(|jEXNE*GhxK5X zwAKAmqlW@VP~cz+2+?iD!edqIv_nI9(-#5j3*M}((d9T?`xob@o{h8>{8FVUQ50{- zD?*j%;vHA~isj;>`pjkd>}td}KrczW>O$&hu5LeLE_d_d67ke_1RnDeZK}EH#oEjS zc(~vNm5gr~+I+H@Nb$Hu3zdvj)oROqy}vCkTu~hsnTJ(=d5fZ2#rfW{v48U&LCrne z@1o^Sd{GKMBaeTPDx?KrBGR;q9sDH>iAl8dR*KXjbd z+tazndDzo!LaO}Ph~(%06r-oH9~P$63XYz0X1=bx!b{GzadhbJUgB7u@R#vsH}D|b z{Ptdz>BePqXe8ukFL4yT*_!79Ui&>`PrQczQ^5XSV)q}<{;ME+cFT9+{192Zu_)5C zBqTz1Pt)0u8xk>I;yU_fV#m0_1W_Nu=og!;ryz7XK1kbAg|>8twsCA<)9$Pm3Ywg3 zD|l@?p78;P=Z<4TZM|PiSvWx)g#;}VakKjd?KU(`EAJ;#^QB*uTbZNr7kf6OMl3-( zTLsx(l-B*#$64Evrf00-7XhM<#v7`ZT$HXhLGZipBaJ8mnZi?d5YlSPOhAX@6SxTN z)$1O|YuO?iarWWV;%Lt!O56K}`Za^eTfi_Vi+!EB=xf5C=U>v^vT>W(hpAWNA8zKo zPi&RsUGl4qXkGO7pLaX*W#4rP^%bA`HW3h9(73)V{H5(M&K;w<+{TtIq6gTdB1oE=*#_hZ0CD)~wHKrO%voDd& z245z^`GA5Y(h$V3NDvb>UwHB9#&Z%itvwo2L!XgMQ$z6$Cwoae7sTjHHgDzmx7`H@ z@#$qJdWj2QLL;|iyhz=^UETNJ4s8dEQP+cgBgPn+7xK;qv?wt!D;hB~ey9Z}p7FFx5-z|>o? zqIb@4$i4^P2Zz6t+7ZAw>mSg_r<=fjRKEWa?rjHwR`n zZ^$jMmbb0~NB>ZP=g89X?QUMeyvm-3-nb}viMx5|YWPmo6U>g^N7Hu20kkb@{P<|9 zBj=Kx;kD@rWivNP>clRdxydBW*~30%dw=F8O#`umFF9xCCTc(^X~i^i6QdY;oZuOH zB_B3v+OZItcld|?od&Ev6>WY}@l}&O;9K0RY9F^O1Ig09s%w9WFMbhe!C6J>-&RG3 z5PcmlkDI8Sr+n|4_gp)*@n!k`%D+*^^-iDQ+L=CntTq$hs3~>BwwF$2(c#II(o}FI z0n~|6Z}LR2_6uO80ph1qN%lx!a^ExY%~rv7-c>1P9V+RyRV4{Z!6)j{Ode`=3LHVx z;YX=Sy^e1N;y>$?!Tu!GcymstG4)_!ejkvz9gjUGEzD;m$UMh-e&(hkJtUu_9I;?g zaK^wtJJq(0DRasb=V>y9pMez3H|;|W8wp)(`{TLeKXbWJn}iQ8ZXljX2Ykf%EM6Hq3 zTY)~*JDR?<0!=Ye_3A}YWm10@QCCN7H=^v))8i3+{SWW2VG{N>QYKYVfKz=J*x6&h z4(0`VJp^C0&m)=9OiN=b+W+O~2jE*4<_qPCze1RW`Hc4LO*{p1VPQVN3FJS`&jC4k zEZ_up**W?y%pa!yZAy7~{5Ty-0y<UkWZ9Pv z_>R)0y7??sP_Bw>X%kKN)-PM&dFk;ZSPs);TwCh6USZCTbORq6j(jSv712lnFPei` zk#Xpv_N6V+Cf090vwQ(D2h7E_l*Nvg@t?zEk#s>h9@U&OxA+(JRo{4-RzRvteWg1O z^Bm&-1;7rkwt~qn?R*zL#^2cuAA`H_@oSrpevFHstq25B6WKH%tN5kDh50OO{2o^8 zgtBbbDM^kVGdGECyhO!+toh}z=00Rwn2*+*y_H(%kC)mRT-RsL%g<`S3j9CZ0nJbP zkM*5`OSHyY_7Q4Xn2!X@9>bGkGNg!?sN*&JCjWk%{LkzkR1*8o*|rI?HU7tJzX@ym zDcS0|F{^)M@dqpoo-fJnNnb=)PSF-#GR?T6Wm>N-6Nq-t&4jr1v`nk$h&7+)EvPA& z4I{<uN`EW06dnZ z=E3d!S1m*AG7i$5{m|gN$6!*;sP&oHAUH1IRO8L%(e%(|vW3JWjw#bLBj8)6fn_go zIkc;<`plaX;XzEviQ5t7Ma_73Ina8lUB2Zl+*zQVWGy$(k|VjpM}D>h45<{6d(VdW zVaca3raUSoVBsz*xx0gTxt&aP*;%)H$>BLgGMz;ZP?5DZkYd-`ZJY+zTrXLalm8Uu zH{kG>&-0&f11~XwELm;esZ1}l`{1#!H|rTa%7_7Rwi$5{J1i9UuK5SZ81XYN(I0rd zYfd6<#4wYqUUFVgcv~--vBC~78$_~x>fK;9T^BShKXf}#r>1*P0^adCh5n#IG?lk- zdlmA6LiebU^R}gsm(=1U#Nx!xB0H(bn}<2pn5H6|#fTyo8<@tE4zyiW#IQ0zMgAHT ziRRSWBg|6s;DP?^Aj1&V`PZOMz|eK-AsEl@8$w>9I*$#Cd_$J(B|#BR6hY6)Ii+T) zltHqiO6?YudLk#wSz(r%2Y=>oiMrmYmF^#uzAGooKh%J-)I7M4|A`y6iK}xm z+}4$0sQ+w`;cPNwKS855#v{6j9)mGFL;ayK{={&{?EdMa~F{ z6spLqpoq~sahlXOF}s&MH>ZND_YT|KK^2q-6)Yo5ww`~1p5UdX^P>5pwhB!q&&xc) z{8O8HJ9|Fq(e!SO>0cEuDy51>i+#iz`JMDwT==Gx`8OY9+%o%IN<^BNf=xd6%_i5| zG{HPi06m6!IMEje6a5e-dM*?!P1oQ`#lakOfx4>la&OL;G$Xl=A6-#h{+iCI9!c8R z^x5H=y1P(R4|Hksbk1B=0sk2xlrc?FkKJOY?6ZZEy{Ya_+Pt6^iaY*%Q`vbj;ke9c{*z zrXiBl6;Pr3T|5z8Cl~d9k;UGPmAIn+n#E+55;BYR$xc0Jb03G}fadnYywK z*@AX1%xR}bXFE7j=lMf|cAg?jHmZCEW%7`mB1?V>Xf~bfp(5YZInb_CkpVgR#wwpl zRE-J$`5@o9%J&(3A9nS2-xWc=LCSZd@;NMC zn^UB(iWnC6RguGjA|I0_dv;E~BIUC#?Wugb2lb7 z8wTPX#0FBLmv#_@XG^H?U;GnLuCFj|HV$&*=&0u3q}vhXTR&mw!_#_ z3^v2MjyMtDW0k-8M99E5(vcP@$NMAM{YF}3Jh502sPgDM)HS&w{uJbgu8&wg+OvW@9O}!HY zmhtZhxawIW1md_3EniYj=Vr>h#3@ipAy!>_U^%-BuWr7iotG|GJ9hr?)h*T*^?V2Z zEEbfn*c_AQy2IO4+(g9``m+_P)PX?(_bHj$uOYp_fU?T=?gZ){RW?a&cKUN?4~MaG z{BIS8DG(t;6f53C&1*j4uV%0_Kk9YMYP{szOk49?n|DwYnady|p&TL{r|PZ8O!efa zA=+0XjW7OVI8f*@Kfigze6C!36C%tnnlv{yiQ`m?S@)RgN{_Cw6aBqt&*Ihnn+M{_ z_4Z?;!o%7hKCVVPoQY@2AKw_nG0=@PiD4?lJvNEiJOI{(Al3hb?rJ|{J{fMNO*O$f zmvV3D%~~6-{4$FsZzOFI73cZm4hD75l)^2%Q|=MsAWjBo9sD0U7NKKTW0MGVG-n&A{>LF^|AaqTa;5{szxuk0cl>h3$F z-cIr`bBy?}sm#~_zF7uP$ct+&EBxkv^*fUf*_oCCe1{qzu3H8PC4WJCQC@7g&ZIxZ zYrF%T-opb8RM3FQ<>NQ&U2^#hSN%a$=J?m&0nUS-cDoM0s}A4**DB8TAASOSkXot@ zd7L$RQeYL4+|rk0hU8Suqtd=tq0RaC(`jv_zq8ruiFk_+1-9lp{S#;^`>dtX590In z=Dv~aCQGQvi+E2Q+Wu-6KZp3hr6Buz^6AcvyN-j~TX3kwH|QMC zO^3E$WpbjhmU2PZx^=sTcs-}q@Op3vkN41_*@q3K0X@R|#tP_|zvU1b^IT)W_w=FJ za$^zq&g)c)L;Ax$r9dMEG^2Np&%m^9qcXhtbwY7^lpC2bj@Gt#$>ZUmVAu@g5oa7G z;kW$?7Bit}epBg8ltT^8OWk3cs+>ay?RX;ADb5e~5EoDdnp{X$$aS$D!Ls}2O#fN8X#HD1&QxMHxC`-3H&%pzh52vqE%Mr zB-S>W%Ht(8Q>#~TAWoe6mqS(KYX5%(bZV)EfkM7GT)xj1R*1{Fh99j5KD2e(lwStl z2siOjY?{B}7x2g`%Z*3OZy>Ms53j7&?^*$s0x5|rr;X+sYoo$^)ILK>@J=8bNr<*Eq0fGlp$TU##5-j z3&018AQoY{PMvQAW#!rH5bKe7^q72ybC%eIb1}3mIoAMREHcuK2Hxnv(FakcyK9fz zcSgUF=d*)fGsew^KQ0YPkEu{}{@G6d<1$DA!NMFW@sf_na1XVrJ?`F8V<(kW7UE+#N!2IryF_x$!5Uni{eg>0lS}!T0@s0zhpXaIP7>w*ThV z!MLA2qp+F%k9xwMo2N0<^7B$lnva?Ju40(Q&W8Cw;LB4^3*fyA{_lkMms`PmybC)P z&Lf5#GcgA3o(MgTDNY|fw*6-Knhwj(4Dy`3Ad=xg&3Wy=3;Ch{W4q+%WnU(f>leNX z+^=G{@=!iFO6^W->TG^%55!E&OO2JX}yqB3rD&z6+Qeq|N(Ep-Re~i{khRC40 znmm7x;l>kQg5M6mL~r4(BS|56n8LwXgi?ohjxF9A#JgI#PVBa1JWPEB)4usJH2`%3 ze%M!EPIW=PqV+Bxm&A+zm6h;a?@ETe!X_6SXbnxxvtpSea#i2#-;^O;n7WX%naVd9 zRW4$mChP~0QQ2>lfwA$>V^$?(jwXdu7{cmz> zJw>%@S1g)(D*GY7#P4x47IVU>uu85v$#5@TUo%!3C0bXJ_q)XnRcqXG5OA+uC`S6+ zOUOXP`+JWC?^<&5zQaF*cNwt~PsfPgRyg4T(i|&wKRR7Q3%CYqoe;$u#LZUG)XHco zYYm=Cg$eo34y|o~a>cCUz;T4zO>s$d4vF*^?Gn*WpDZn!IySF)n=V-oAG1B@hiev2 zXa{m(RERt;sjcM%!|YprxslK=qG4QkSFx8ty@g-xfqZ(oa~DQ(fk_u%vg=#5Z&##T z+;?<7F`E`rMc4Q1THD`ta>eEUU2FRbx$nPkZC{l8{@d0tezwbhZEO3Dfn3t8pT45B z0R}6T=|PSjMg9$68RvNk5dj+|_mPm?Q1zjg*jc#CRHls#+^aF(-m6zVBC=pD5Sfs| zeeV@nUhoo!={M5e+gjddZ{dkn;=0c?83o04SCLgrgp0qd~3onc<|J$}go0?hn2+xD8sfdzfoV!VdAO7gZm|PHLzE>RU9V1+E?pPJ6&h zR5wp2SJRA)FSKEv#sOdkl%UHl>VzZoM9#jbGMWC{KTgNf!wJUWSgDwc3)6+==Sp@T zC2Qz?j0|OPl4~jI6+S34C~T-_+;<#RVI631qq;pFMJv9Chsz%3;SL_|yPJm_e!!lz z2^$X6@ukJa>WXsQP4vDv`VI~9NhDT-|pB7n9j|Q zMmq{|l=~$_>0CF@%eA-t{)mf(!F6O^^GA5Th1H6AOM}v*&Jkdm9}f@yV$cNPg=0iTLEvQiKW9BeYS?_pJ+*9KnrQgDWykm+9cR9HH*NFdDa?OBbgUlF{)QBy`ne$t1oSTK=+9dNDU^4eNJA* zGEKdX)L#S&{GBy{gmd3b6tKIiE+}oE!@TQns^F_&;ure@u|7g_|#fgCl#Jc zh3$7y4nqy|;ZiprwqMzWf6aeu{a22*TBXY-ZldQ6>4|0Xo}aE22b15>VDj_snOxJ* z^IX&tEb9LG`%x-WIYb=eCci=Z1kh>UF^CUEe6uFR2~my$yAPA$5OXPjcvqiA*-YhI zYXUUbYV{$_V_$2uGx1JVeY#XT8DF==PLC-%dPY@RjRqK z+ju;aPW1&?LzN#(j!l)bC$6xa@a0_MB|EzX*oCBn2~$hK;@b#@@IN0_Z<0l6{N z#7uF#VLS^rkTFFr{_rmrcLSYVjG$ z7wiu`WPex;;Z5HLYb%9CKn8-lAV-Ng;C!V9H+cOAES4U>&#ZpQ#@E7JwhK zzw#)2XUSya|4kOgsY8&xZ zNGbMz`iVhUapF?N)+zFT8syNvQS423Je}YcOY*P>o#M@eA{Uywr zGggQ6EZoit+WkAD-w(^wxiY`5CCkvEFEL@xXzpXroBx;vSPdXu7`xpg{8IYMvpCs z?T!~CBTVMKi}}D4_O|=n6Z~|Io>-dSxu+ov&u=dw%XTz>^YiL3mV0HBaLJK0%Un(Yorl**0;-U#&(0LtRBo*O0dFBIUIT%m4(gyC0#J#KF zZQa2hsXD2=V#c*FVWc6oAxC$d`(>?HT%YIH?`^d=KdH;+y~O@>Tuc>SAZvjQt^Thp zKOF9FPmy-~v#-eWAA*6im>-!RYW2PspUm*WyY~@r@{pu_Q-ByU>PaK{>$!C#1uSVh@=SPySddUbwcRt45;ZOzBb7Bj> zh@Yaog?(wmOIGq-)Gw}ius0lofZ0PS@J`KxINJcJ|4}V{oxwb}h4eVR8_vu}|*oS%y|9(5x!5_+>;+BamPZR*5KVOq#_bNN( zzoht6?R?kxM+zIXq!mcArxc-MWRu2U<;P5NZg~Fz>gpJim&{7j>^uU;g76LX#o%JI zxCm!AW`OKc%LRTGG9EOhz)-%@3_~FFYuOzcbTtpcY9H|uV(7Xj*T0p0m4q(*0MP5F z3814eB~_m1Q=v_81poyA|6^?x-fdYbcX2TLy&1239KpwE+6&adXlkcsqK$@Ny74Q2 z(RAVYuJ~|Qd!QiS0!FB0J>bkQS_rQpJ$@<3Mf!z(I=d$SIO{-xBk`vl*&Rp<|O zn0$+AS>ohdM%^j74Hsxr29VoGk{^uze-CUf)k_5 zUr%h%%$6S4uvZ{v8dB8ZC64AXeQX}qzQh;_pO@SF8(*dCuEPO>fQ+0gX{dU)8T;sG z4!9+IA%C>We`KN%YWo{EeyG-E&v+jRV-lEHP2~y z3Fi-}BX;nx`+|Z1`ro$l)-=PY8n^EwXn?_Z<`_|ximQv3>OkxZOivk~BLQhZu7Tl3&= zIr#ff_*?5ggvM|Ffs^Joq??QusWAcu!Vw@0^P4ueMv-F8jHglA9 z22BlK{kvH<4LkhUM=cox^6_5z0eR|;vm{fFw{|-hvl70; z)>%(t5#~q1?fTICb(Xz}j&w83K`7z!KwpC|(hcy)(|lheX+Zz37pesQu$QyXkv42y zw$Kn)gZ^Z}(8}Ulied-Hw-h&DtR49x5c#FIT|qhjn9BXpf?WGgT<%lkJctfdQhZri zun#}U+Ytf!AwN%>SL!711Xe~Ty#AH9-Hzq_<2Z_+ms3lDRv#x!C&I6Ku!=NLMEXI^?1Rc}qymJ0J+%Ux;$u%rk_ZAiixxAJl#2KT;nSbX%`DdtEfOxprJM^>55|-)I3dr4BWx zF10lN9!!m+TVCz@R%trH`QG$ME%Imn9ir=K_7uLL*uC^uy|eV4?A`~@58lVS_oHsa zl9Q=^O)g%_COcb0x~4SP^WKHA-H`g00squV6tq#k1%RLj z9!@#<(i{S~v<+ceMT#w3#W7{JV~MJz7tV@zt{41O_?~0Lh%cMc<#=F5 zJSU%QtVdF>`L~`an#$JBEPWxQ?t8qY-oPW#nsg*N8wSk|f+WHCq$@*Oa=LOhbs<9C zrhEtW+4}a3LOp=YOYMP<-oyh;KlB}Xc|5%g=hJnq zulYlfm~>(GtB8Tx+4U&h*%nX*a0zmVqrQk#Wn+`mQ^%&Z)b&}uo~f}cuX#Mz&lHQF z&7_j4d}WQGDVzl~u)01)yt>cp2DimODvoiNJa!wdS7FBcx5H4$34`<8@Wkn2{7)Pj zj|K)~lqjd)vfuKC{KZvcJZR?byTUar<-GK1^affpBR>p$RP9_Gej>!6N+nO~El|X1 z8n$p6GOMn<3=fjInmKNvTKE(0pZQ)Z891N9e>E#s|J1RxmslvAalhOhj;#}Sx%bR% z!TSyFec>O2_YCjDIE{z(hQN<&{qoDj#@U0cwK`i8m1X}4W&=8zH0?GZ-YO`!5%IBv z^LM5pQ4S7l&0~LRs#V1JWqg7{FA<}^LQY>M$1c%aD ze!@m<_6GYlvWVd3WqF-WNn=EtOi4EEv({_8Tl_M~sTTL1x;5zY1@8TkKLqa+d2eA* zQwXQGX3P;B9m4--Jm2xxdX?HtDoutC{?b7KoF{Dx;y4q^-uN#M;Of%NHFZ+i-v(w# zS171IA}8?tHKf6L>P4pH+gpP6PjT;i2k<0Ut5B3g=-rrFBjLzyai+3$HRnhE%}3Jx zg9A7cSCJ9_pyypWe*IwF5bKw^EQUz1KzjC0a`|~d(c~X^Gx3v517e_;h%aGyjc3#C zBtL8r{?Q)b)M{F6$e1f`$gYZIT&6=Y?~9Bef#+H--g|HYuiSr|+=m9TrWoPxcbp-1 zG2Kze47dHnJ$-;DTE+S{^tL~?#`cL%1a!Nn+97rBPssaQ@=DHkXN9jNKr$t7hp0Z% zz3(5A{!sTm{VxIPW$7jV-PZ^2(zJho74~-!-}Fkz3McOd9v=n{6VgZFX!|gtQP(?2 z60PIi#z;h1GI=o@{P=A`ypxf!L!=1QN)Z@{B4CS;*iHz>rLQ9x4;g5pjBylc(xw3h z*Q8IS*;~Pcqm#FY5A7ddSJLlWIn6Pm3H-12j;Fo$IXRygD0%j!nlH9hjA|H&xa1&_ z=pg>(6mS}Z>guZ!htfy$*IPGoEaF<5&yhIc$+<0tN0WhRn5Dx7p3A;LVjwqiO8o}* zQ7Pu|Sv*=PZmybSVhmOPl7Zx&y+K$#nh?Xf?rH-R z#CU*!2rsAPL^TsSnfmn&(yJ6^cM%g*-G+t_*5(>m8vg+*Av^;X$Bqdfi3_6WEm0y1?0 z2C?L$Th;bZkL+7~QEhu|UE4#dO;!}~N~Aq0#)!24(fz#R5*KMi37O;At7kd*0o_xE zqU*v2)DtRfj_dC?ySETmBI@4=<&o~j~SJP`A7>@0a znf>6ByFeKipQQ_j8ty7@U&X0Tx(Pam`%`vgcpd2Uq2$xthnC+w{I5h0;e2kSjoF-G z*r^|K3P7`7@@wuQkd|2Nv_!VI63Uq8pUoGxcZO-5^Wr5mU^?QHu>mOXfkyC=U7m2| z&a}GFKX@ndu!3G=;I#i^tMx{>AMZBeXMQrDHgvY5$RCM)4doMb+&dO8#%oK|7IDne zJEZ0c67F54|Ndhqz;x*|iZN2|=-)ViOzE29hJz;-yT~GbUoC><>43|~0n7}xK2u$R z_rrmtFV%qMzZnA%W{Zhs{BjdwZ%l+p0C5Jj`8}|XIcw{K4np=VW0Q2t z69-F5DbFU9H|IvWt$A!nL#ka#rR`;1^gAq7_YKzvEYHX6TGS|=`7E*@o{oLZuKj8@ zNL%v?@?t$B>4W|I{%u%jel9}rf+4iR2}VIuCRH+TI*~%;dW8iZJ%fel1!evdFcPU1 zk%J3IKoj&}^$M9XQCA?0mFsqm;2++QdImQGylS+yThTxgt+Qe6pA0u>kC%;J^YACF zGq3-7v8YFFa@~iSb=v{ihGXSM+wK4Kk%$H2*?4s&i|lb7kCpf9G1W#eAconlAz@p& zK-iSjRWov#b!6DnvK#C#E2yniZCgC>m3oZj*0>Ah?XA9p*U3D9Rv&ZB9W1+PxsfD%2ZEiWI&DF9%F`jmY3>@C!z*kj$u9= z@3oIZV%Ppl{b~Q#LHmB3;k*eUCk9IkxWS`gfuARW_ zU0dg$X44B~(!IgKIK2(11@73Kv>Sr7iMC^N9M#yEPB!QXc+_?c&u*Wj25{Px^f)ln zzWXjETi<_}jgEuU0yYY{tp9Cd*2$`)?`^>YZyL9D*0spFIX4pX)E+ zwyf~SW%gzR7Xw4;tA_L>1lC-Uc>NOo^^#vD`wr>ziy2T;`b4W<@vfQ6OyHI(JsL8X zmc}?ve`)EkRWRj@f!S&Z?esZzbE0hR)HHB9Kk-v>X?jN%5oS6(@-q>0>MGMQLuPXR zLG{oLYq1v3`Bq4SJH7=@m+!nmg~YyuXHv;D7PhO?bunCI$~Mw7b*a|yf=XQal`TEW z{0#a;IF516&j4Nz*R^s@I$u;`>XA1qMF~9@6W0A>J%23!N-ozdNWC^`=DQs|7q8uB(#&V_-kdb^ z#k`f1QpawYl)B@(2Xe-%+A z!_4K>(@^!5m$*w6rVHVr^>TnNYuNhPBY%6?B}A7Eb+%W81F}vbm9y466^KI{+Z&o=*D^VV{m@> z3Lx%K!@%&FUk-&dm;FuyV*Sdjt>uN%)JxgLCI<_rjxl1rOTkV`?Z*URtdiB@8H)bf zWf}x?Ia>DZ%<&WD$P{cFsp7VPy2d>3+9i>y<=(ZeMN8bWoHI7 zf4Bgi`3~<-^7|I=KF@3qo!QRwYJT6;x39bzb;oiU==p8DE#r4hkn26Y+gDVsB?R(n z^RB!^nsOD6*yHNaYR1wrZ^4LOlTyEoaJgcn>RWHl2uqvRD}PezvL2-NuvG26c?+iX z>OpD&sXZ;VI7sbDDv^<<6jh`2=W2u(}soRjcBdL8Ybz+d(m(&5I z_On#2`vh-4QjrbB-%!0;cPq6&sk@L0^-0~;QtNtcJ1I4CAj8TcucZsGuQv|6Kpe(8 zM1sNv6cV?d{E~;>oel)38ua@y=nHf+rE4 zoVPiDV8}mTL3_eGieHRRUJWQt$ei<6^1OuaZzxUFFQM)wgmv6->Em6LKMpbPJv3r; zF6BqMwCQxXi}3q(C3exhv@5ZT>^-{@yQuyd{imJjNCODIn5wt&=Dco+1vEagA2@uD z*TApp3620d(f(E)7&Vz1M>x2VdhG_2HVbxyTj1YN!hA*@v#A3?^w5q}y49z1RegLZ zQvD^Q$7Wi<#?}7kuB6L?q*V9)7;ek$zt?YZIJDgu&f?)Jts}kKF|qSl+`lvzAoYF| z1Y#z6c#hsNa9-oy{Y3CSL+@$3;#y8%G8AL9n90w&F-OUE%V zD^uN!%^^d4KOS6;Ia#IW!2 zT7gZki3v*P{TI9NDB4WkR;1=^XlBj-TJ|GNnCZei2f&4k9RT0<>;m8hO|R+E5yf6=0YAi}#XkXPKhE;p zv*iSmp~J}j^!X&PtFse&H4Kj0bZ~|DdW4pbC|H4^ME8oQ*TD&pX7V9#|Ncr%%v%P z&Pp?fRfYct&YivX1ry6?Dnz5frF!fma@^8d9}m$G|oE;k0D z_l13Gj6Xhp){*A~%wd+B>#)LY@MwJhd^!DdyKrhfYa6Xhd)vx1Ho&|Zri9vk=>Olf z4%60Rm$n;zr`^<{*6#K}yYJ>pHnsoL@#C=8hSZlhLMhT)oQaP<5#$oNPv6;aJ)7LJQZ3W>>-G zjkx|LAK<}m@uiaqwIKYb4lz9Z>>0fc_ut4P&z)rKLbqM8)P>P3>N6x#$CJ~^n6t(` zpVw~k89UksW>dr0r%9oVd)6KsO?^{44#!PRl%FuNdPY)L%;ReHJw}vxSM`-2TS?@Ub&!T&RBV(PAVHX#Vx5`Rk{ zD$`hE=q!Pf;M_k8uPo8eycb{TB{K)3;5NS2y4!&#VZ3id>y2XEM*yD2y42A zOyj*shrhq0m6=@*i%F?*zJDFWCD3mTtBi(p<9sCW3zWg0nR+Vnhv@q6q=+WhQh_eM zT;Gs-A)-<<&H>^8ykF3&8Q>^B4EK^LWeur`kwwMOs4cwzGE(Dz$5|E$+C*)E$W{H^ zLpTYfCPHjZ(M&0er0VDUrQ#Y@yA0pt`Cj6ETZHTl#~w~0^9pwitnFbLb(*<3Iy7sv z4|4NRfJoUPSME(V;uQ$b!bIXy6Fl|vB54$sR~k}l*mr{P4OM%1i3#GIc!46{?UB{t z5;vYg!br!C^pqj*7u@vc%cxD&?ejb73-K`F9tfqptF(p2d>wg^KBmi;Slj0*EnPp) zIk%^avzI~kE_-9xPQUQ$!a=l7px$hwoXm1n@Ve zPcJFT-avKT`xCTN61KA}b~0_edbQeMGQgh?#*&c;gGcoN3v8qfX%ir0$48oK&|XgJ zkw2_;`KZk>=j(nolOxYV+%m5icRf z5SmZi$1i?heGDHXhT^7xV&*L<_!;VAqP6)`P&nW3CjqPRH9+;HuV`Ti&6O=W^$oN8 zi%_wCUR`=3vm*z0QuR02SAF8m5w_}6ACAft>`(Ta*~gvF3|O0Lt6jWyx7z$R?pBR9 zwZZy@VAw)J7IGAgR+7h3l5mg%^Ss1J8mzBc>&^Ket8GjBy_%;LBrsig-f&}_=id=b zGNhC+Nup1Gi8628n^lZMIBcPalzM@=%LL5+NCIdjDUjM$sEhB-Jj&iBu)oMWN~ByF zZsR_>Bl4n`m;98KQ_cW*n^%AGBZd?BN%8Au&=O5Ii{m>h%HBc7`poov`pJ&dlWZG$ zUg9*GG_|v9e5MwoppDGzSix*S##fXPK2S97)UoqtzAFoqJKkX?Fqxt0*1CUM|1Vl2 zv1{_pZDS-q6`wP@0uwB7t!5n|J4@-x<3`B~Xa-MC!@8`&)3FL9P&%r#Ir zl3pkV;{@bfZGjk_=cDYE@>V||qR)*STtAz8vFNqG;kzyFytfa_7yte^|$?*-w3jUBjJIy9lXRHmJ4oFoHbyyfvOp>>Bu4* z@fyJe&tyMl$>sXT-L~d!ltaUTT3I!Hn`)fvf5z>(HhAlAW?X<2F?VW9^6C1_2+x~y zGsusmPM+P6I%6(dU0|;v-8`>-NARh@zbF;#c`q%hulg=_L7m->F*Qxw51b6bvz481{Nu;;}A4dyQn9X`ac!2$jW zK8c@ZBV;5jzXehL{%CxLSwXBU5ima-yAL@ z>B1{3jd#D|#%zr>?SHa!kWJ7_zV>rp_v`w4g1%0&uaZ8w9THz9H;SANmB97+I=Fn; z``Jngh!|J18d6{OBUjGA$TF``>WZ5~n6n0Rb><$)i^lnlsjvOtY=Jot6;3%iVtDo) z9TRt=y&;V{@{vCsvnVSpBAu@JJhJyP1%^P1zV|sIth~H=JM$mNA5k9b9rr6n^tqG> zEteOz^*rOe=5v>iDxiiB{c|{0){stW?ueu_Q}mOmz80@+1a=Ff0CG%~ii0new#2~D zy9Y9ty7OEIpnE$Ul5KmkWe)+wVNYitm(;@B0Tx~D_o0dQKLzupxs(_A%^F+m`i`+3 z+`^wH>2}qqA`Vuj;puesb$1()=Af8&&CKW6%v`UTIqTobpkH3U8DHRi^JClDSuzN| z(oR~|3H)%a(*7O_aOeJY?Qy9U!I{Z#j!FFsg|~t*ehum4ielT=y6b6K2M&M}Q?JM0 z>Ct>-{JnzMX(&C%%#;f8vYEv1oZ+5j65n)%dzMN3fS5fubFXkcwgBgtF15Jpd>gr< zm^Y}25Uwe|{q+DZVEs$1;@Q$uFZ-n{MHx_(7` zO%q3Zyt=mdru?1PttaGvQ*ssWtMO*P*!j;V&`kRGBEOeh!nmqQXgl;pb{c<8JJIw= zHdY5>->4&sUgwuhz`w;P;W~wJ+(@{yz zkE>_(MX@vE?-A9pp5x49fTIH4iuv##M%M)kMb~bc*1rf?E=`Luw1hIDyrCDVZ@ol4 zj7blG{vdGUB}ed{t>7Ow*=K*NHd1R1K7Z8)K!WwSt%S>!S#$uL!o&>$>OB93`)olx zL3_Rx$}yf*iT|ZBqwVS!X#{8!7%#&0{&duWC?4I|+34rXI_navs z6!ZNU*OA=Qs$o__nt>wER9K`@) zcM%Y39E2(2o7QpTxiOFsp4H4E<`%#%$5Q_WE(S(?YC^_i{jkhId-%WpJmfjY=W-V) zjWivL>aI%#R9%ov*ei&~&VDDWugDb{1%>NdVt zoV!^6hcye=E)quD|ET-E@L-z@kG9Va$5W^5gTaQ&HX9nGl7~?W<~w_uM6uiYd*U+p zEIGHsRQD`7H|BhMZr&Xw0CVdq)>xRf0Bg8O;2?-e3sAtNHKmN&0ne-Q{+GULZ8XaN zFjKkV5g3I9xe1?4VWU2#3d)&dX6;7_P+7%M+AgEPkCAYYe9w%Q(tg<|WVI&Hn~IVn(Cfx{+Zi&eIgvV!P4W*MI*rlL0n< zO2w@lCTa7xtTkSX6-1=ueeYng7X-WJLX~@iK*D zrVG?jtVWkfbh#<-mODwzRQ~B<;pPVyqxa$jArYBvS1C3r*TRwAWSwTyPFZ)~KTOt5 z?k4NL`!wh$RNA8HD~%&nSy5zG5D$;4;5Z zJx$r7lW{#Snx0XNU%|31uTD-qYEu#?Q;u5qb~Ki z%+XCNNc*?f{8jqcdBaw%e>r~zw*awUw5#|v)THXrq*C>>Bk?n4f6jD1n-`o*W)$NU zExqZ1PYjP7J&qxG3Y!@<(W)9K`gbac>Qo5vFK;)BKD|JiF`Wvi$^}qTWDq#zoB8mL zzmm=ok6@mqU}_kW9~+Na#RMu&2qzvFuSKJcxEZW}xI8P897Te+bVV@VlX8Zu|xJgoH*3^R%2tL6@I~mVm5Dfov7#*Z~hwilu|e2>sWk*f00NSn0}fWVe^@N z+8&jC)k_}8d(FBwJZXR7p76vyl&927!&(<-d#+njK!dSuoHHU@D+TM8^oVUE{iLnO zB#wr$>WKAR-WwPjTRLI1)o_}4uIXXv#(7)?RFqDN$)c&_%G8-?>gTnoBZkn2+7#Cv zWkwGr53>#yyPvbLQ*SOYR@Z{_I;R>}p7WrF=M*M?f0)Vr<58oxNLRQB6<(Tty~awX zzNwY8_@%%pywWj}+WyxX;UseASaApQ3KzhUE9&w;|528N@@LHbJbN0smm4hk|2)8K z$ZYI`j`+u57h)qYyFvQ53y_=RNFF*u*_b<>@HOwP2Y+8*xDZo z^yH~rqVTJHT9|RWH5o}yo@ggLE3j?g1v&KehV%vFy=!jc)!ae7IRkj4#i7GiX&<0{ zyv>&qR&WMg^rwnV#h7il_p6vv>ztqKTi`7GCWDQC^(U6uOWtb2LPyt6F81d96FrR6 zrf-#E6K%fLc3;-}twIgj#N|Q&6>3I#?$WTr*!^z&nX@1*qGd26mHOL&=xF*Eohs)} zUgA({XB+20&9L3i$46L??P*eG{};j8f|uQ_Ig2{nJY+ij@ElDfz+*kC!R$xrojHv* z=6{2tQJfk1&4^tu{X1)s?X+&dQ>v-psz`oY2SZ#IQ(1-573xN%Q<)L)u^Xb9D;PD) z{h5E$*lN@ML1IJHuO?IJwL$IwfGw|Jr1c_;9s9 z+|ke)Tn2askovFAndPg^|M!OhP`CvvJ|;jNb+OFeXO#LYU3vPd+f*^FbEPAzsfk_D z4%}W$p~=Ed<-nFgAs*=+>}R;lexB2RHKp*rRaxhzZ@m4Pcuk>xKhQ&ZM^vQhi*GWr zUwxlC?@O)h@UIcJ(mk`&td{N+i|4fRkroSSwgt6$yB8RU#;+)1#9fWZ^`CJlH%+L6 z1jt?6Atm%}RF3Qbs~QOr_;P>d?}McSRAhJR{K7b4Ui-{14!&%*=2V92?8`dL1S<1h z@TC+pnZFntsuEuyQN*{d(>>&Eb@L=VQYUr|)P#$T`U4D+I=>92u+^RzB6|U~pu zQcv^HdmtxHyy=yU;mNS)VJ1vEzd@27!qI>p`iFT8MfqvXb0tOft$ z_pSc=E|_xaY0RnTED)X@7}VqMU~(A0u%-S=JvuIFyus@J>`$WOVuHvqZ=DGmv+^sF z3i%JqTfL{t7g?r!OUP8GOiz%>KkPk&=Rp;4m2UX6DvgW>Ew9{d7P|rD1}DEEk9He# z^gXv{A5DFY;wNViqVDt|&>mt@vSTo+(;rW#HdBUIiq=|4be%k1s{J|h9X&>7HY?SP z@AyalSH9H}#^0+R!*=N-T2dj3zPcj}!&g0A$?O=0$!T$Prg|SGZ_|}LT4EqmJ!q@k zbuM{;lKY0a?Re9+-E$`Y%vb-K4}|!_n!)sl1w;1dP&%~lq%TJrb+7}OzPL0L$Jrxp z2fVS=^JbyQjit{tCT7k*BVlvXG;y969afS^iYJ<_8)WHVaAv-;18Sp z9Q;Z0GNa@VSlF0}6_m9P=(I;i_t#BH#Pkp9tPAH;-BS? z&NTYBnzk_o(pP&@TNA43B2)`@dFOtXFpp zm|&O^n=SE*GJgc!3&{_qAJo>P;^$`ng{on@z{#Vm+R(LvPiq2Bhc}48vPFujwZIqPU zzv>+jiss|c7R32jx41Pnik1gj-#(W| za^(eR4TRuq-go_Cd0=yPB7Gu@`%%T|$k>_hu)@ewJgLiv(8koic8<%-YTEzYkb1B4 z{c=ro%^3WXE>BH@I~_!cI)Kt3a1(xy;u6N1mru zBFb-UPPhgAkL%S&?!u8=+hS5h6DuH422{_~bqwdY)qpq(1|3nzY1t%)BShWrc z5-K35Q36C0Av)1SqoUHfKu7|lgoGwD5L7UjL>Y%c+N!m6ZEgF(+E#7rzOhNDR!gyU zUx2#2$Edhezzu%S*SYWa%z)U>_xt$$^ZVIH$-Lk1yPSLO+3q>_o+~cjDr%CCGn$&u z`UMx~>g=-r;hSyQPadW?8@1-k!MWG#M#vQ7>J@7v;DTG=KBWfCSetC3GY99H3<=Ux zoJc3uY_X5n4Ho-~EtPVfAOGei??ukA!)_8fTy`v@GF{0(CU-=ieSa1mDEFUHsHFwN z&DrrD`os2ZaVW@b-okTH%FO5SH=@7M1e!0^|Mw^*Zvtm-Vc?jIKqhEC{^n$(Hbv!J z>QHS|+cyn2*!Du_2bKRR^yVtzx9?W_)Bl;3dMavz&I0FC{9*m((m@>X$1`-8NALmpg*MGUlyr zo8YoT-8P|#eI0s{h`f|fkC%Z0X}WoA7m}ELjFsj#6vi?Gs z&Gc!S42--9==z_+ORDIZ-w3GPdb2h$qvp-J1zO3-vuNVE^u0zropdWamSZPl5NGeZ zINR?gbKgZ;hIVFNLKO#F*O#J_nM3avpbttewnljq8ff3`zKa`N88~|)&?@;}{b+}JnSB4=zAxL0htUFR|2;NRGMS0v zXsPE0-TwgXR3_fC(?L=?hoB|J+fib5IlLVeGQ8Jsbbblp215e=zD)c*R|RB1m`y8Er*d}2g@sasi*Q~RkaHat*BiP;j-*dWv@2!GyW?p7toZ-G8lo%mOKfoa$4qs>B#?A zSb_~`|NMXihKLrl?VlgSjg3~A6I`^arFWtVT-&Pn+!uVBUcn7(#WVUOtJboIgW|G7 zwEkUcT;BLg2}x@0UdYTxV6g#ktprU4n{C3K9W>$ZKR5yF{y_%H(R&!d`AaI23W}bK z^d#EXj~Ke6`*N^r%CCH_+X2+r&$>TD!Bb=WgCrUuU28DM4|t|F}hu$mxj{oSKfE3&wDBmz8p|DRwG!cst|1>{{e);zMF8A6gK#??3HNQLkSC zNdiqREr!NYyi9)h%g{LKeKY++;SW24qo4}seR$fMc`IX1gHnM>-Waq z(PZCIpekI>ZAzOAGH)oo+6}Jbc!xtQGqUms_)YQT$GR3yrrAj!(AB6m9+-4Gw9jnu?&1O2qTgBh9 zd@o6PS$(nb;;Su;Rxt7TODVd0MmgYr;J^l4C?wk%1FK^k(HGA znpBw9e#o8H%e%_Q!jA1MS`7 z%g1d)Pv|i~a3S-eUbg~Fcml*68W5IfTUWtC(nRWV5~14mp1p`V4uMnrRr;t`be#HI zdXXymVoGp3-T^s7gweE%e*k~7yZLR%3OMQ2X#Mr7{y`VJjH`Qmb!lk#9HzSz4HHo_^w3}b5RAEh zvuTZzdlIHYR>%ki16ZNYG6Z+BvOBbdF7zK`*PcY59y9qcWIVB2CQPkB2C*6z9-mUY zxk%?oWr(Vkhy8*)09r#~qy)JFC2S>w@o;C%)_3$uX_Ga4`Y88wyK$IOnEFyHz zJ;3H&4*`Rx_%iP%$uWN2tb!54pO9x))~gC(ht*Ns*MU=~Y%;;NN$KO+p9o1`zn@L< zcd>J{7TI4^auxt*;IsWeD zb!Q$~W5Qht_cM=(>;QgZF-E)}KW&)6Gsm9KLXME~LDxM_E9`;GoHU$x*qtH5m zoeceHAJAj+Ws2#$)oeM-K@}yIs)SqEl>mU9qTcAL45tdqyIVva87SAmzz)hY1?5fJ zOVEe$aF(HuospP?3aHHApb)fBM}`l4w&5igGoM7O4SrH$7d*mq9(lh(TZTSxfn5Ur z<_ysL_(%S66>@+QtS1T1V-i998sL2bX+fuiFd;8`Rr&~eqhz@A4Ix~PRCd_pot5gh zTIa#EZK^V{4yWq4=nC&-a&tw)r;^g=i#@|ve?_?p9c?B7LPcVqXkuHelHYq&q-H~R z`+XViy} z7JuCGer5iPRmH1f))~$tcA>FZtBSj{stBBQ-Oco9!?p0yxml2;ss|AE?}I8UJ)^t# zYF;6Kkay>?be&Q#Em7U)Vc8S>*eAUlX=|87O56FMOiT$QeK!mTLfuN`})G5}&tAy!*dQlw> zB+IMajpZ3iyX3~8mpA#99zmgs{5`3zTj3uR&84r_yN*2vq(75Mnpl}WUb;AI|6P#T zdqYqrnt0weUCgJo+cP8;A|gm5=xCTNUPO#>`$Se1wuN}qIW+bbGAb7e*T8oL@h zFTCV(iWwjD6#0CiG!N@z2S*c)FK=VtG3gpMZL3I3e629r>paYb=dpC{yrulA3rgAS z^lE|e5KE6a5%J3o?`IOmi6_0k|IL7j{mzVb#7HI*!!bl>ujnM>56O?T*Qn(c9dB;~ z(8zAfRpzrs`(R{M{)skv8#!GOdNf_j*dtzqZVd?+xPIe{#P+r&mQ8?Z&M<1`wbahe zPmcYc_?MD<{l_u_FMMwih*5g4yhKWywNVM-MLUoy%2~1(lDIN?87E)wn{8A%en5F5 zjogZM+d&|zLhd?7J5f?G!CLGyKDANSK6RHvP5RI^Mb#6JP2!I?3W^sg9w!5~)^E8a zc>(^#-?~{PT!d|>&;JM3PjK zN`ZFbD$}9tMNFOpP3rc5i7U{BY-rh4ym54-Z**3HssUGcPXE-wJo&~^k`QH(nm#^)^LWEvc#MAOIr4`iJ z*-4kBUw4oZ69%|TrIi<_cVp8lhSSotEw2ir>Hm z2*{Q$VU5m-KSbSWh4eh$Ok0W}#Cdw=$cLNjeIcoXu(hM9&=CH}`8EmjT2l8I*E5E8 zy*QFFp!&0`WZ^k`P6yT;tNDEx5+P6bAXE7l^hz50q2hfU+rbNsHKwB%Z#x_>&nJh; zQG2hACddf@J)hdgHnju7pgm+;6n%BQ2ynFb6~rS66#^HQ@!aAf$^L^?OdKnl(`^H{ zFiB{?iB^C5?=4JXvc}}KO4{}4kRUbfwEI$sOu>A_=eN=J5v*Kfb&U84cI!w_(RyUt zq*b~8SxK9o1GDoF0u4iM9P=D`i{Sz|vAI;WBOyuRqh#Xx; z0%Qx9+?_@co)PW2FAFdD>%+{ybq=s_s5E{!SoH8r!=i0NqqW-@aG&%L2r;wn2_0e_bm3UfHu0dp)r=eK_b3_!~EB+PQu3H%a(@QyBA;D-0pIVa(DM z5UfE*tcf-)%wfU&=V@uzFo%UPPox-(tkYJ`^=Ah)b|1z(0Ju6tQ^0(kxW6aBBN zwsAl6lVGKW-L&w%8=3P;_6hBXfQ`;U>x?885BgAuO)VZI?G)|q92DU%5bWURJ$%wn zF>OS3mh*!5`lJ8&saEu#+4U--I(k6AyS99e?_?#cFUIV5Fm*C_e+ZK%U3(;seX3yD zK|~<*t901}el6>ha38tZKqVJjciLO_Ep%$f+TgP?6lxgBQ>qgy7H%vp#ku;K{w2Ig zXeF@%ufjNb&s(^$-M;DHaM$x#B7=AA`0A^~Db-QHFbv4&AWuT4B~0{Qazv&-Q7CT)-ii3$ykW$pbW@pnbkJ=3`|CmN`~^)cy6isysn!onDm6J$)4&!YJ^SY76SPuH_HXMqXvO{6o(YKi96+ z6|oI_&|mG%HWmKdO<-m=P_+0Z4CI%V?GgWWdDmat4#Z{K*$|RB^w;oh%Q?|~5al%} za#L5X0!ICoEnS$$_ao_&l8kXQ_t2`7jz?{zdEvxJW>J$Y?6NlJWaeG==Je8v+Rq3t zJwrnXvaR83Pv$+Q+Fl&hOuSYRu2{46HBvhCiq^g#9r&aG>AVt3nm}92sZwTp^84~8 z;cb1fJk@&*PN961VDXyy-{oVU*gm8~HH<9+p3k-xpHV^icKq|rCO9r zPAkHdEG_WxFoC?$lq{tuxsD1+0boTAWgXpesSsL^&RM1d3~xYr8Dn+x?S`KaMM+HplG)1ah~q`8R1 zhJ(KieD7L6k7G4}7cF)a7w-HsWrCUGK+muB$Z;_m5}kXx%T0L$lA*IckI?>KeEBne z5~81t9g~1;{t_8vUK6@4AWLTnbe9&=DYf<#;Fyz;x*;@<{$K^2*gEQcysbUB|3V*r zM)Rqnk5Vc>+ADh$mGVBRK_vxuzVa3PtfN)l=cWIInUSNP!Hh`mG2xCZJCWG_x}2yj znpYaW?a7Y!_ek}7O#ne~JGQ>Up>&8Nc&8)k1D{XzbEHZ3lKgdvr?$RK4ilv^8Mu!5 z-i7P(_6YEn*T&{UA7KwJM_Z)M6hRAHnn^w_r`JI0LFLazSA0ggwr67pEqte)PvNfF zP|L#8;pIILAIHnrN_oG@IJf|BP&Hgu>5s8Y*U7tm9u>(+Y&#;x@DslK%v6aZE%BE@ z%Vod7CARb*(^bva2!AJPPOWY)PS5g! znI{hxKc>iYXUnQh+L6129Yj(RQ(({N*qcq1>YVsrOt?;f;;Sb>d$d=nHk86v{5BzR z{2=dF7Prb_I3r8#u*xu<2KYlbk+@Np|b%XsvRnk_)c$ObVoW+azy&1$R$% zYMebpZ>&g7*po2ij_AN`Ab4b|w@q|Ks>wu;llWlj14Kr2#aD=k#ij(JL!U{nmMt4h zhQ}5pO~$ody^w8A-Q@>rBHXn>WmCPK$RQ8R62+U4MD%Izf|BV6avBBD(cZPL;XpQn zq|r#(bewg5Wnv|W8=XT|;!VR|nZJ7N&|2z zQvKF2s>*Q1$7!Xw4}^Em)f0*xBEpM*jp;(8)pE(FdK-yOINBl3(%)8)I`=T>pI z-DNt2em>;cRMj4NJy+A|IG*#;$80mRMcmAPrRg`>x$T|!x?4soiLJ0MhDH&ldl7V# z>>3&Ew&MEDDb~{c8PHw;zMO8Ppejs#Y}@)GM`TBnR4qDiO(2!Rol6XFi_K_~r+Sgx zq%fkdU*N}0?X(f@x(QbD0j?}w5nlX5%2n1nbE%x^UnEK+eWPD7-1#2QLFIu|PF7cw zmKApP7e&Lb{xp);{`M1GR#;k@D2*nnLFDX+ZJtW^%OM7Dj@aEq?yLWaP~C~#thl`- zVd8ejW31{HTO`2A2?gj!PJosQz2nqGP|=$Du{EUv5EfjuM)F(Q@svr?#K#EUc3SoB zQk$c9X|vFKlbGes&7I;mx4V|MBP_fcwWLggQKV2rNKSlYp--Y?g_^%7c!ycF{BiwF z&k$`@S63vqrCB_~L0JFE(5s&?{#4O@fM(Eo`>NF&)oQBbM0GPpOcStXiNLhc-l2-Y z_%nLyeQKbm)_|O}?f6cXT*IbGJiy?9tnbmpeuMDwe~R(PcE10)MSqI=EQF*I%Y|GH zczOv{{uU4bZF-UrZaFqffy{w(q^xe{pFIgoe%IX`~at~lTrLd z&s35BdBC)eFW9*72fpxYd${Z0G@_HJtj_ySKM7>@wZ{L5cT=)~hPfR%?`NQhcEl=jh&R14AHpP&{5qRw;n!D{sZ-*Vbe)4y` z0T-_uCYIv{yvS^rL1MR(RTO|ignTFHY8q(KDXINSbn#|*$dI3-41Q>t1>Rc;K%Y`z)Rmst2 z%aEW4&TYN(2g3!2pU46vxRVz?U4zDHM-nRKowM>=2PdTVl-HUpxb`v4A-?nmUsL z?CIYpHXP3sH(6rpajdut*A!8+Z2^8PgCoJAWAbBTIE2=-fn=zCoKSpW$Jt7V(WmE$ z%4Es+K7cGZFxB&fxAk9UKP1S8wL@vOCWx&q;T;WVwQ)03{P{wd;VT0uG=jSD@;Cyy zT6uI6;OqIR)gxYlm$d(W_Q7`TSgdP30ylQ?G9+7(2;7O;aHlLJ_SJe(j1LJmZBlTi&A>Q>N$M(-z^1V zbSu&pA$GpRF8Rz{2dDWROs4}lGGzt;vFW@KR!_dYagX+#398||z zCI7NpKp_R#$qE-`i?e zdI!+Z)m8ea8&XGmcm3X);h+Z1l-jlm({Cs@OR?gejsPO?m>*tJXzC$L3e$KdU%qg`FpUlCOyV*VqFG|M))V_%+f&zW|RkrVWsbw3Ca2 z2h8}F)|}3i#+h+$74PAN0@7r@^k;l~Me*v`&%svvyEbv(U+5-g9vE}X%oz3{yzwHj0DEsmN-^GT-;>Fna)@mibuK-))NL|k}|-~K78fh%+8{hNXO*NI1;;*ds# z-ambEUh)iUQeApEAetI}_#yJIHxW+17*d4Q>Wn_$ z0}NlFjin_ttWTdT>|s+pbkA_P05qz*?UqQpR3$HePnQ;DX!I(Dv$lX6qtWj0BE?0V zRGMT>UI>l0IvPEV7Yar1M5EnCqp!YW$i8oZpcw7_>rUUkwM1WqnIkIx#qXs;o_G7- z9ldU_evnlWoBejc6rKQLgIffu@F&LxydKkm_ZWHKs(LjI@V*e8;H_5j4RUStY7yzgY?OXm`Ms{^NS1Gx##gdLby@Pjr4%l=0Cv~Z$? zYury#h$7Zm!+k~3V?&Dp%56;KWB7Rc7%Sv=?Xm9nq5OVer2CC!*T3f|*Fe`{Y5+IZ zmeR8^p2K?5-dr6fmwxEwNG#m-E-%2}xo<_poxPW;)@bk7|HJ72?mmrnp9X>$r4kzL zU9FFQaUaj%qjs|LdiHO5eUp3L+toR5N>Jxq)zRIPCXsa-fXUv==05boo7VRfX2x}J zlnS3qVXm(xOH?*j(YXVn#Xn^G^=3nCYb09S5(#$^P-o8$2joH3x2?(EgZ#`yZ7|@8 z-l@O!i50wmj+yDQ6HTEPn~f*^1Vu`PS8ZX4f5|hGD!COTv+0r>1_wEEW5-iote^4~ zL=)&9HdbY9<&Jmpk+T<@)34`2*4NWQ+OmpeGwJ=BgfoNeM7Fp3kqks#cGq3Uut97m zznEG9g4{OUD&CmBzifba#W8**^y_iF2RqooZ^ph4sGp2tU&#VZYKHm3oj+BfMD5oY zFnuW>nDlQ6@md@)^ZQ)pV;_6#Dn^@r4v&r3NQ>CjUcWo^cMTm~xhaz8)q^@VGA7%h zTn<<7X=kffmnHW^dX*)*^wz7Pini}{U7{&LWaMo#d`t6ooo>@)w`6`mKbiHElm8Xk zyMt-U62KzI>{V)FMZACsUZf=m$?z+=F2IeKC6$`&T)_vWyv~oe$m{FUc#T@mvHj=X zX0K5`$DFU2Us3$e%i9tw!cVliYzkWLrA`6o7nE{S@N*j~o_o_SE&30QS;p2wU>v)- z_y_g_U9(WElq&ho4;bSu2nmxP>e2i>6^SjW=nlG6&f2XntK-V>ge`QwphF8oJRNfp?zCJg%^USTI8Y*!U0k1#NWTQm!3d{WFcx=^xjpb+~o?kz7KQ*i4_+L~k|mQ`f{=YB+y_!RVKdW-6F7 z%=QR+HLk`D>LcS1*(INZ?!4TM&r0_qm~YJG1+WwnqT3~o#*AFUou~>Xf4%=hsRBAy zgRV8fRHctW%J}2u6x#uDk=Was{W*ZvwLGy3=}eWJbQR|Rcq77e;{W)S3dLUY+UQl5 zd#NLh82iyV*kT?JJZW0N;qiEmCVTE(s(un|BEA9o9!*1#_AH)}wi0-wy}#W~v1_vU zKrT6!ykm_yXKZM(gE0wXhtSp^=HQt*&8DrB(GoRUm9DU+FpoG`z9Va|{?lzbPdtsi z+Qv>p`sQc>@?x)$>`!^_l2A6mxV`m7GIOasvOGS7lpH9h4t`?~LTc zw*ZEN-=y>}&}R6E?nPWsiZs0k`ZQNc1Y;O*2)tj8#|@EC^2?)TNopZWKcpNBe9+!)CQX{3DvbBE0Bu`XXU> zbm$9qol60a6=TB-*a*!wyVdMNo>N#+%$DcFh3Q?dyU*e*CJY+0GGf znWlzca#C!?Z~U!OY9gRXye&d{B-}Yf;#H{C$*j_>mq^H*Q=uU{7oB<>yKi_2H`_6l`oAtp+n2Fg#vfVN}5$ z)~|%FROs(R1PagZyXV6VRGwdR&u1B^JU?U5oXQ%`rtR=LAy!xGJ@aw|oJj}u!lFj5 zo9y3Z0`bZ~PZG@?-KF054h2xz)GON7L&@xm*WpS=WanIGL-X_#zI!`)xWbF1&$wxa zG^TjHb)nF9wq=I9i0(syCx@5lJYhxRWIr1`9K+qe_X1P6vz9M1@Hut5#XFxU9#~DB z$;j4his}c@8gHsZywB5TN}-&pLdx z=~4LD8qHtR_HzZsGPuwcZSkw3V~-0jvHKqq$EEukD7v3zZ2vofJKXt&S&oK>HQt$I zco81tx=o)=hv?H#vBn2JB7*v&Uj$IkQAIWrj$s!Xb*@blgY)L&qn5Vs>StpLJ@cZ* zY(%lh`70oWZNCiKIF>eiImdYvC^q3?M%4h9ZxrKKu^hjgW5PjxSDtCcJdDv#KvGX4A@e7PJxo`7Zsli)uYrFGE}6& zVcuG1N-s9ZRbvgTB+#)=K1SAHs|So)A3Wk;yCBfW(jS1b)p=i&p{HH|6?U(OHds_9 zhnF!lB~$i1%m$nm^ucoGE>Sf4kd0=z(q@>&mFinQ$QKHK)8|y*>yPlCAGPA-gaGO8 zB9&x|$l;RGX#R_sjj@0KDb5&(8#A#~3n^0ph|EGzBsVwDsK(G$LT|5&S&R~K7$vq&h1MI2c^>GV zj~FPF^L&7NKIhy1b3V@;YOH3XmUf!q9<`Xg6v_v;7%;Y+(TZKpDWCzlWF1XDxPi&L z;;^1t#t8-&;d%p#izEk08#R{8t78Nf-YMJh0tm*`cX856d47CmA~AUlIOb6fzMfH|dq6b`|{W zJ2id>blxrSgl60BQR5o5d*D)Q-yCw|3NN}w{pe6ixa(Pa zPhT>lAeJ|n4Qy*K48dSlUucaw`^-Dq@3BkgLV&aNpIJDYXVIkej6nSrxb`y-G2YyD z!l~5UaT` zpMy*~72WzA1&X)E`g(5yy0~CZhGtz5DvDPjO*$yja~*)MRM}L~zJeJ+dJuNJQxA>S zSv3o*ZssgK+gdP&C{z6NUCv&n@1Ts3RhZUbXsyz`s;|WI^lj8}a+qtc`adXcu;7505|5)y^7n|jfjRljV4IEJcrb-@ zY-am;L0+uQyMt#I8L&U7_1@AGpN|rLc}I+&CG2G85Roz#_=gERC6VsnR)AGrJ>|7! zAsKplJs*;1U=WC*Q$=4~5DZ|&P215&lvl()6VFeEYODsHq*T!jX9b0?qc9oW2T+NdrO%DfHbjtvj~9WAf1Oe?(WxL+&#WeoOqMJa{9T7D2UXtnz?#6 zYk{V(wxDo3-yPk7!;fd<!KFR48#TpTt#8Dv;yl08Q_U-CfHkrZ#p1mMYMIc z&@z8lf!2Zw7C{mE=kP9jp{o*eNu9_VNK955Eq*uL8KXNXG0xF`z%f!fwv50eg7fZV zVS;E&^aWO@3oNTdu7s7yck;tP=Atk-3RG9?hB@}_d9&>JXC*R)<9*lAOPTQM@Rp0Nu7B_i(1oqycYJK&U%Nmg zYddc&%%v0~eHcd8e(~E%w^LB_R+;>>*7SZ;O+U#t^@-q4g>E|BKLdgxKpkNLG?x4) z%1oq+-v7P|?e-kV9#E&{_gaPS09j7Ifnf8z2hWf#f-J_Yq)7GmT^+%2%)V$b)%3N3 z6MZBA;~@D*S`HjQ>PRhozOaSQ4uBMjOfkbRRnJ7&UTgOEchF+yjfYd_Aoq+R;=<_vfG7 z{H?xy?}C{`GP!w|bPN*)?HBHx0Xc(E!s{Hvtw{XM3nLn36kNfF%CUn-16B+Md&k=X zUFpLb)kuzyC^xg69mDc3<>0tZ0k6}NpVPek26_Lp*awPa(jbczf~64)c}O;S2?kd= zw&>-jwVY#-1$WIa-Rp{aBJi9BjFmtJr}7Qzd}5-y8}0oprL}lFMID|yZ{U}d{MY@r z2#EbSFE>EBan@1l&Tj*9Z0{h?^ioAY>^8R#yoIw&yZ-^zQ#3~`^sen+vUCBTdE-Sx ziB-A*E6CyhZC#lfOs;p13IM^*;xt=8h9RsQtQ%4nOkzY;bsAA<+Ea|r$lzvBu2y!+ zVIX>v=Q>qXZsn^7^gI=`lZAf;kxM3JQQD|}t2dCKlv|cP85^x}n)}#%u~Jn9-a3?K zdVhn7_Dy3H?dNxpp61?rGq0r;w9?~gO0yqoqF64~eS0G zPSrTyH(VruJ7lvb!40@w5Avn5xLz|H?>6m(JT=t7I$PW1!&LictX80XZg z+rY}7sJY!`--RpJqH-|NIgH9;6VCoxMQ9nrrcu4?R68qEr!C|A=7Nw6{lYbK$W+(N zzG_C>GMxS_J0FAO#Q#KKNB?RX`4A8UB9bZ5ieAi>3^rzgdCVZ zmp_O*Sx0A2)9=7K+O#Gjyr5kMES2pIwx6E(Nz>6cK!??$xlRUcWtpqV+KaCbYt~%AzPA0@?D847hLUgC;{N7AQ)4UhM9g$ z*RGc+^@WKNFHy{Pf|3oaj|RY^z%BI$^t^%N8q_EY?YrJN{{j}yH?aRa$KH{Bo-xT4 z*g*S7>_oNMogykIOK}N2m9v5RLZ(QvX0xUTEOC~BPBkDiOrQidb7JS|+Z1!C67TR` zErs6uV2qT;Q<671OPS0_|CZmpV8Jv;@9sW~81$665aW1DXH-!3kL^{p+m%w03o%A( z=`*`ipu`V#7h=R><;8C=IDA6llb(mO_T0R8%Tv?beHg}$kzV((D*MjZra+R zMBsZl_6QD+?G-2Ovfat3(!x@qyEkGsMAA0N`{G(70WcQ3R-_Gm!^k?)V}hJjGp-!; z(9y_WsN@ktJOX?&MC@I1BjfNT{1HH0#WexK)Z16vdlTap7qQzrM8c0Uon@p)=2D8_ zmK^T!96?=tcVNh_*RdTBo%`^z9OvPp|45W2=L38wzAA!{L>F|isw^*v^^LO6HO@|a z8=*!Q(dYCks`&V~Lvsq({(*Nn;aMevSNB8@ zD*|leb+$MPvj=3~tm{Xr0$7I-d|iL5s4><5ox#%ec<(oRH(zPscKx0&m1AcW2D*OS zatJ3?bg>rKD9`?Cs{5OCy{70yl0unmLTP8!2=o%#TjL7qCWe1LRzs4$r&|24GV~-8 zHS;}>sr)~lu&!GI&#~#KSc3T{Fp#k)lcArxaz9ZyKx|irVRc@}=QLXITv`F9HZ+? z7z!)cj`>Sj=)5NaOW2LWpA|SKUgc7>A-#BQ<#a`b=q*z zbqODxJ|yLAe&yKt++!`58v6#?E8Vrq4635nC57HyT_A+p)4X$#kF2h-gqA-V$@A_I zqFgc-FrHirBw`B~;76DU>9Pc-An9*kMTdfurOMPS%1Ky3uZzYY3sFb1w0arG(Z@mv zmP|&`{AH!lL$1L6kN<;J+=^mhvTRYy%6Q;0<|$BxG`g5cOOW?m7t= ztGEI-@p5>H;%!3nA{MBaXQzCZwR4cDlna6@xFEPv_hjC}jO_5nz-yIB`|So*nK*>c z-uh-Yt{>22`bbJTdgItSOXI-?=>&jFogV>KLOcoSRY9llH4=QuKpx847ew;s9$u9? ze_%9!rPigz?6=uVU$_mPq;C1+^5^s*MixH;d8LZ#Pld{}L?DUsGE7lN@hv_2Eu26IHA1x+dQ>rM1w?4eMn*amEwbc8rt8WK+ z*7H&p)%-|XlQ_qq^6NDY7H3(!Q^bjdxyLt<<88ga~)qlOn`kUWO9Bav2MAy2T3EwaV=m!=EJSKT3km_Q<&os-W5-~ZIT>~)ki z9-8ik_u`4Fn~}s~!t*Yr)KD7(=bMtDw;m88&LyvH(dW*|#ww!#k(_>In|7025=}QV zQItH+N*3*RhC|tYG$cs+F^crvl(p>)S$Ycc?F^FYNfmt?=R;-zH|l*Emyr-0@1x)Qy$22qK(yo0{)=-}TPp54;n1!kg4Uf9V82X$q# ziFgD}xLsBD@;IpSIXhS+yxv6m_!(Kx8od-Vl% zs|8?bTMNkaG3Fzx>jh16s{d82W&l}uy6agVPpf06RKR-S&hLU@*LtFjy$v6S?MRpI zyf~gOfj#7A!fu+CJ!F9w?sb3P4nbt;Bk(O*R+630!;<*|PXwL@;t0=g2_~!UG3|A! zVrPnrA*8j%iWq{&XWA!(2d?Q>s5q|Iuz=!H>2s9Zcnuxc7h1je=i zLLcwATZ9-bTKj|-oyR~FK)8nz&XYf$H(6h9`gB!IhW_{$wQZjKbI%Ogen|>WYDRoz z1&Yo;-adM-Lrm%Y`GnGN^Q(NpeIM8u$#O+-%E%&+zn)CRj`wE3BM;M5cFiRo8R>0@ z`*!OT3wIqU@y}&D=ou-7$$rT2E-heEeIK_!{jZaS%zlYd{%B>2|7x5$$O5O>Gk=cw z80*ETWW27Pv5SK{@t%tpVuy-Da{`7Nm$!x?BV*VIf4fu1UF_!!pss8&k zI0ilTZ^4|$u6E4Xj%Wkg&t$pk1o)HQk`^l?4chr9I&ncmZg8wj)N^XMJOTu8`+OpX z%`D{zO~DnV#+fteQs+1nF?>4~ayvQfda)jFF7uDokdSZOUsLO7E6UtoYNtPD4ox3f zy$pk%1`J0SEk%-|~JDe#7C1QxPgNUIpn;SADk|F9M9*heS z=*6bJpY}0w(eYUoVxMHB%#RwrUc?zpVLEZ_hfFX!Q4+$sP7~vHyU_{V^^bPXVDn@A2 z(O;yh`^B?<+t^Hz)bHpn{TIpxauWX&S6T2PN4nf#Uf)plJrKH+E}vGYV@a;dq~BXz zfvc@R(Y9m!QF{yEhx8=-=$xz0J1m^{EDXYgcq+Y5pD?^Dy4h7m`Sd{kF+OHp?{6Ic z0>RUkJga)^3bChulHIag**R59Cza~I?{U$J5wi17pV zIsSw?=J*q?@SIcunLXA-S|-r!3f6>oQ+vw_{BQR&kL_>uW{+|oI>8Z*eSQjURu*sK ze5Umg`iV^Q;+5gf&jd&+wCOYdIqjYgw1M#bB|Yno@`?l(09`3FPpcZOqkAKg?7(r? zn|ndF;rq)YABVr^eH=bu*q~|Q3tr*JMT6Mppz8-a&&ECAec5V*!aop_rG&io9k~8J zM<3Yh!LkASDpLb+ZyA;W=5Ow~C;;|R_guf(2mbeZ-Yu}FFl-;#6LWyw0E~mU6v;q* z9H2f97xV-85&eHzo0oSfYuddv{^a;l7(ka$kQUgu4>!m$krf2+WI4rQW*;>(V1xo!e68NtW#@Ryjj`y>N6}&hehr^Tb zAJF?Z&b0Xw3J0AX7o1_TOr^pboL8{*lxoLO zUx`ywC2KW#+#l?n6?3TS`W`jX#r(6BU`xSPazoQrxJ&=qtXsb0RA}=yDvCs9z(NHl zZ}p$gchAl5`_HG^SkFQ5o*^;$Gm|Ev5AWi$36-OS$ee=>*?3n@|FKTiD+9bAjx?cX z9xd&3#QoMM-P?vZ0RkTTBY(Qnykey_#=g)`Xra1G6@6Kmr(V7Fvp7B8*Du|5fLiK) z5)#>wKEz~EfG>QLslmU2o>}CEU3`!H5H?bzPCpxI|MD#wDbKy#bNoI3`9Fs9rD95D zpvgnZh`;SOw56TG3pdK&!M<71G4of9T_|C{05B?RHzd!fPOqY7u+Aq4;;=Y0N_l*W zJKb+5&Zm!Zz!06sirsvPuyf{TntQ(XQ$fl6o$sEX=<%OVcq7EOp+<&Wj{7q3dK;=H9n4I!q{y;t3x4mK+Ya z=X9&hv4CU-HP|cOqa*L1odq8X`0F&Jh|w@29-Lm1^kaU(gGGY+b<&vO8|V zhV;$G>+L*?-+%l+kW#AXNE0@ry-gyg?&Zeew+S{!r=}h|pP>giu?n#u4*n1IShDCO z`7C1B`VG(Z|D|WY!(9hbSa6f(6e7^h!)V8)@?w4le6mnUuoy{)0mjD9iSu(P_j@>q z(GPfqi{nscuZ$ZM?o@(zA^rpf9fBKAJC_r%d}SCb=*!Gf&7sj-HF4Y(ajQa_9Mg(0 zzNx26QG1^lVY?^}2^kHN^ZKN#G_`K^dCED0E_CT{Bm9vmcMnyV{Q-DQgxxa?yIJDJ zq3ZUy8K3YmZ^9z>K6nQk5X?V7sNSKwsdpZOht#8Koi0})HfHWLb!z-%2-GnlXvmv3 zA)(eEK`e{99^ojBwa`bBSxxPqDUKTA211oi`K42oc1@wIkxcsbBmdiv_$Cl;;!7?w zg&)`>t@GvjcFk_S{n-C@rG3j%o$7Vk_%fu;W*6xprmN_c0r+*V=h=WKDU$o)VxEkm z7X;|t@IwYEn`9z=Fa_89gPpe2_B~nEc@#v%YD@b|J_=aJ^elu6u?%cZgokP2A8h#~ ze1JSw?GmA&uANvWBv>CwCvEoG%?n^-P#17E@?fnHBOQ`>m-qX##7H+m1Bl2ohanCZr2DqR!4)~X{+#8=iVo~eY)Wl`zkgQ zeRm9fyZezRxpiN%WU&rtri!}I1>dl8`~`hz<)}1Dr9eUMG9kD26EH;A&PkTpKaVBW zW0!mXSyRfajNW;V=V(Tq=gm1%>o>BoXV-44>S)h51&1=#tlj)OR=+<}*56LoM#lO= zED7Djlm5ymicJ}yieoC7)Z=Vw&F;dy;ZKGK6shm~?xvP6@7}`^p&fJwBIe}oM6?xE z;5-s-Z1jFVBa`Ewg;7jiPwqgU_OT7VaMe=n+x&$2AI;h|nqb$)oiYmJQ!Ighxa%<3 z+|rWumIhlMKS<0qKvJ$_K{PMCNOl8sc0OwtZ==)iT*U$vnNM@41ylld3Q|#(a<^c7 z!ZJ1|n6T*+Yr_udjYZm5O>@-NEOu>|HjDj5e!wQII=zeP*>dziR-Z?c=a-tjaF7ar zzDKz8d-ekXEz_ps^FFp0CER&CPe58ZnCa_=to-%zG71)I5IWy$+4nBhll32^C4Qj@ zjI+OL7G%gLc=%jtIuahMiPNBVx+iJS{V>@cn*!7RLn@ zeez<*Dd$uN&3Eizd7`{KsE^}rkK}P+G*$G2L3)-RnZZON#Lk4qmU@TO0m*oNI{nHW zTCqb&a!@LDHNfk8Cq}o*rz1v@YO&_F2$(hp>7NPLxi!q)77#jLUyLuaC_GFZ*PFn3=sa8m6pj4Nrel+|zaHfA1@XIGg zM&TbUPv6UD<}dt&zB~7o%}eNB;7`{whmsfG(*#}9<5e~Tw~f!7w2zku<2#3^{D4o(^St|NVADS_9`Vb+z89>S+jcUG^B;=HGa=T!nt_Ut8KrA>?#__N7@7fF}dWVBO=ejweet!H@M_(34N zWpDaSTgtu#wVEoa9SBliuQk=Dc}DTeY9nyowW4$Q}y(|vsQllS9 zO+UavsrhV=C}ma=xN@C379K4YUMoC^h41DE3^$t&jD>#|37Y>6L!|lP8T#|ionrKr z{*LvCc1RcSYw0VqK>QnGuPYU*%CMKBq&e(W5Ui^TymuM3*y|rY|2#flK*n$Nek_uH z#2BD74?ZLL6>RpAz2E}NCrFCK^`}QXxnk15o081g=zOba+V>5=QYHG7i7p)9Uc(3kvxsOi;Xub1D!NC-JhP z+ELmBk8m znMd`^6F|zaij386=CiR{xbv?-C3c&q8e+Fe{D9u_f9|teAsy%_7B-dC<|y#B)Mf2q z>LS`{k+w=*AZZL*(cqos^8WCv zqN5P3d=C1&>lu?os-2sQrmi!hjHdqLZqrCTI;fo%yxW)z)uh#lx`?IkhbIf8F}G2= zx+;DN!X`eezTKTri-GlKT7-f=3J&CE0mC~^}y9nZ77YivEhGl*f{*%weF zRr0GFpzW>;)eWagk^(F*kN^dmzk}4VcR)px~ph4a}4&h{~#|}vUj(>DtS?}1rT=vP# zzvJC~8#-kl)z!XzlZQs&@2JaEN!$M5^b6#r;$aMt)NVVzwgdTckh|O0v$bEW^C8JL ziy28c`umpCcktWE4Sx{0CbZ@Mb??=HNLHiw8PL~g#Jh&jwpKR?;2rEp`sv{;M`h@^ z_R3Hy9JIwlSLzkGfQxz0T{gcqxP&E_Q#QnRUwPCB$(sXtRVFs1uf^r&+JS)}_^sMU zeYgX*QxnNe8IKz$$M^U0p|wz)0g$Izy7O!c2)+C_ zQPuSQymaG%f{L$?KsV^cJFTdLhxZ$=LqEP9=*O|Dw;)pwk0Y+bvMgR|dHmA)ZWlhN z|9$E^$_$VF8f9J%X4ATz-fzDw`~VGnlxg4eBtb~0C-;YK()sRVfG>(WE5`NrO}u{x zRejzMq(k421dq?;0e4FXT%gs@;l>XY2JQh39y8j{k0| zt2_Q>-ks#XJJY@U`zyTrp8swP@7had?mLj>{wx3;aZ+BMSK`yKIRQB)(gjqAv@kH@$w7y4D6=Iff!m-`Ilutch8lVoJ7b z93}GpCurig)^5>X^;PO-v-c%a3{NduY+p(qIF=r7PZ`6(E>h7$C4ll!w+3$KVe;?sI_aZ$83m)cR3dygM1M!&Vq- zW*48S!IEEqANu-%WE!keOQV{e=iJxJ?Q8#88?4Y+3VCII2{|Ib!Vg@DeKo99(d<%6 z9PXEJ3#F3LuEgFiT8ZZoSKe1uu9sP~L0I$rB%(ew{9Jgi=MbY~fl$py^3D}#%hWbq zU|e5;mhj5X@y7wShC3LZN01nzKJf0K%!ZSL;(uXdMIS7{{a7%%6L$Oc+z#E3 za?DdEh9?etI$V;ziuTroPTB~eLcw#_8^pha9~=eO^CI7i_>$-zBt4}@Ew@sijSEU0 z&Wn7bUyb4#mFg(@9TS}wJ63*iKgsJyi>=-dkER~|KXn%UpJe07sQBaE6h2i9%D&^K zk9e4MTl5ewMPCPkY&We@x`^MJKG?pOJp4NHpS41sw{BtA?Cg^dWoi!d;I6R(d`f8y?sfoO>^=%PI4!m3drczOORfq5FBG|I!saFGVGC zu8+G*?Ok48LsLVnp{B9n()yOjwC0vbZEW7``pA&l88t0KBD3PHvB=c=NKItwyjXo} zq zGfk;>YkcqIG*A5@uOf3B=$E&`UF3Vb zj>ptrQ~lh@GisXZ8tV&(4vS2uS#^?EThpX2;;r?OX)VpOGDRZIO_4LttE`O7Zf zDyA`*NJDF+rM{-Iah}zpO1#lPRUbQpORG&*sCr&(29Wtf73OLhX`^l)=%RVbtb!1vi zLt}kip2jtvc4y7zu_e-4Gp`i{+O!VQKnmezch<+Sl*qjKUhNimuHrj(OYFeh(M+!3&KKRnQ$heXSe}+-C>*9?Nen7bKrkPF6bDJUox(3fyZ<+o?0+Aup82%6=OcCP{U}&x#;+IoD^=+~G zCc}1a^Ux&I+Z5Tgi&)L{$l%!{A`@qTcfZ1{hUqh6(6}*#4XCBQw!SHrfeQ|>A=x-J zH_eQxHr~=gAqcRcsWk>z^>xD{b7wTv&d`(&){ODQaG{;Lh9~T!R?{*mICcb)Z7^ z#@95}w9Gqe>JNvX6k|9s&E?eiv}w>Q(?IXDgb_zszEo(bX_{_RZX(Q;`acn4dCg5= zZ5PQSxex&^F|UM-eon6qewoy8;6QYUP`~74BZrz;b4%e+K0v4vrA&UE6J?sLArfjs zA~Wmf&24UhU0mgs`o{X2R^%Duq}q@e{3*T_AxuY5&Z&5a`( zVc0n}Ee$nO1A=DK5n+M&lK9JOoi}T0bEBho3Cd~B@uoU(sL5^t+xBIQqZPGlgAr3n zCA8GX;w??!)8|qrpbI5@9VHF@ujPHw>r{v@8Qi?@GT)-sKn~VKE^VGQwISeR9|Y4j zDg~3zuK7{CKGGU%iPr)ioX`StoK_M28OWLPez{|;M4(&1ngnO0rlqB3USw9iaIC@e zpHHMpl4Pyb5vLFU;z%JDuf{#(&1`$OZ}XN=6EZ_<{+b~sq-?FwUZun zNOo;Gc#kmvkMZ&7x9Q;Y`9eBYgcGRP*2acfF}f+y)>!@Q$iR{aR&l^bFi%4*Vkyx0 zJ_{rBHQcP459DoYd}^$v2CbYG@6176&Z7e-FMu(qzTNY-R!ty^ zGio!}4he?9JUYU#wsLF@wclcbx_LI13~2DJB*W&cniz6d6M(!m>q+Hv*~~1ZfX=51 z7qyMe$O)C37H_JRX(Vd?Iv{3r1sZfGh=O{@{9iJ9&=}avNWm691=SQHrt8jXSX!W!a|0fcQ$No0E6qsy3sg879Q4Xq!H2w3;Eb#k>iI& zY#op{t)T_MiOG{;v6{?$8ghkH{&N&&6wZKh>2i#ZAy@9d;OV$y|6kzA^>3q_+Z=C1 zC!u&S?m!x*(qz=_rS+3zS-NDJchNZDv#Gghcwhvey2R)*%YCadkTKKhVGM9)>a`&T zBf>-tO=zzna7Qk&F=Wi1xHDWc0HLg;Y8#qr8{>6oO9XDC=|_6Z`{wQ?E==1QB2}(M zecJT;QobQJ51L@!5zaM&5&HG5T{AUmrpnBS$xaJ~H>4Gv+ZYej)6V?S>L_Sem;}I( z))_2;hD2(n0S6+q88HaI`ESAHkjCbw=|l1|GH{49w?Gfy0_8s>Z}NC&S7pXA6-=7o zpiDrX^p_cLeM?I-qz=tvYA{Zjdn^>^w$NQke*b&B zOrYVHHEA4cX^3O}48CkdERkjXOF^~HYl_vhMTV#&TLf9X5hF%K+S=O2V*6)?%}Bpl zTfjeBlxD0(UyB7s3LOQ;8bY8(csEJsj0X)XqqnvGY>u?f0*jGCEun0sKGYz$#Z1mi z)ywTy--ks;j2P-PGU{Awy+AColouRk3i#|)|H~>swqZ?V@+r+2 zos7wNB{G<0Nd{pfMbR=z?7wk2y4<&E08FbxCoeM6#Nh--wEHio8bCY4E4yNpo-zMS zV8_(ex74$asFxwq6bFZaGBcr+Z4AEIdEIKh5>vkp%b8)=GB#MnVs~Wy5II9S2`&H~ zLMDcKE1nOy;(xU*HNu?@`;078d$}e>#&XZVl~p&O*=BVo4Q->a!J9|p8!aRBBfMD% z$>gwj7EiQ1JuVsPPY3dZrp!^{%hqpN`1uvG<$XDkQ$CO!k|;s@tW#y$Vu;qDU$G?2 zbtV6h&0q~~3M~}1Kn$iLjcHA%|8|DkV9h|zDE>bScXobE zPUp;yJqKnv^t@ZYqU`TL|JRsLNhF-5pZ`{`X7=oQ7HG^zK+;Qg+&N zCsOmK$xx^DBc_jt%xY+p?HHe(LnllieYn+0Yi7Q_c|2wX*yK7u=GI51*Jo6n85gq} zkkD8=!-wyrZ<*$)@#&5pzPbIc<7=n&SYzYV8VEI`q5>rXy*g*9k8%I~nK+2(abn9n z4ICr}z6H^~@2j*1`80maJ_a2B>@y)Q#y1WzXB(e~(3GqQlt^H>)VI~v&vxsTTJu8H zjoHWAkSh$A!4b~gb_A}bU|}=36;4r;a#G2|IJk90Byx_e*VW_55o$nMZdOf`JX#sT zYR%Dd=6i6iLjyUdm{W;bPMX_M_Kl>sliPm1h#cN1K%Ap)#xv?0W#zP1MxB7LSPjDB zqPCHyv-mq|C%O&P_5V$eL7fa7fq&aPSq8A1D03%j+5lK9qA`(?ZG+qLZ1p1P>#yNw z)M&}Vl(yE);-8Gf%+&{(rH#|w(!YU0i7OeaQ0(LrKs_EOdFh*Bz$`&(;UsnLw1WJK z>QdE&UNJj3sL9T?zBn5zqmG8hnulj-A=_aNoNCDZFVI+SAz_e>-DjWi_csA)-VSx6E4ik@$Q&Jcr|+s4-yr2yS@gbtlPtf zdvL2v1N|>jXl{J-_|t-GcGpklkY|v67h$MLEwTjyDZ}*1Lj)nC}*LTTVL3A&b~lp=Pm=?Kood_ z(^*Sp%V6aPBFtYjMhfw}&a7#X^K%TJ<)g5WQEr1KllrOp&G+s%sUVYYt!eFz@HZE!GtI$TS#`y5 z!Vt2EoDWK(vBJVzHNm3LAp-U=_2VeRO@M|2H6ho950hO@rWj`7TCJ;}U9T0UBcWgn z(;Dg<>srSG%P^4;btGqj5`V(HS$Io#a@xAMQx0CG)U!)BMrVq|{y8@;7o2&9HE2ai zz}+r|eRC}{TygFYkf2x$zAyRp=hzrpM8{3cpQxRvN+knBA zW1HK6kyI2$oI<5CBeNnirSc?|5tS9?pQxAQ`rP+(U*f2uNal*e-C|I*h_&XWcxQx`xk1Wl{q?~fVPg=7kZsWJIYI3VL9T5!G z*DjW>UyLw=77Js#c6X+9N*J=_Tp69?T@x}wk%}@ksG;xxu_M`qvzr3HcqRB>$ry<` zU2Ow|5U}xf@20~~t(S~KNC3wgdg0Z%ZX^^UXxEutimyhC8K9|EZjMl zyFIc-SaRdp+Ih?{_^GRpT#zfa8OB$uW;|uxGzv;nk4ziUG%oPQZn4pJuVRIOdeS8M zKuWd-f{ptD+{B0vuI#?9G{ZO;m2HH{Mm&`wx{h|La9L;@m|C_))cQ8Q!INKz;j1dz zl=Ti#n+9$##f6}eZPrtwul-xN5xxQ5Lve}LBSt8y zxRdZh9f-_ob#{Z3&<#2Rr@Fm8-Z3!H+dub$3&i|Xh$4b@*Y>RGujuT#puPKoF2=^a zM6(H~=or}0RpQ2?>m~aymu0=Kl>0NGcnV{t#&Jkm1uwp#q4%r#2M)hf6f4Q(dRyd{ zGEYTF3w6mVA)WS_}vGJiYF|Le|-CJo!#0X3-Vq{2RJRwo|h8&); z%9aUn{EyOCq*pcM)Q8Sw^Q|j| zorU-G8M*V;$e$emc-bq93OC|tyfOQLP77H#c&wngWhJ<<_~tIESV5R=3+|R#!s?90 z7mkp%5*us6rpahxnLgKL1^xBYykTv_kby3X5?LRGW3R^zQP3g_{2#fW{*H|UYvsW| z_SGBP=}15Ju|hM=nJtydu5Dc{mSidS89jME)w9;bd%Y)dGp{AhTh+!by<1YXVfeI# zc|ZsR>>&F*0$6aYp?}&wlpUiVjX;FYQ#Fw!F>FH%w z`V5_M^SrJ7-Tfu9%dvlRiJEw2%lJ(5wk})NIaeOoRW|SGGvP$b3i3>;Wp%a>Xs|XO zQi5up=vgr_sZ%$1<7QUOoK zZOwDN^QNQ9ri;iKYcpUThQzqZ(~w>}ftB9=PCUM(Q;H_;B)m`vyTjS`E|N+IXLt_Z#L_rm9Uy|&ezp1rF8 z=xUc+gAAE4HJ(`VK|{0QTb=Uclc6}it~G*aS@Y1M3B-#i$R-GgkO&vrhmSoMyG8;r z!QZzPVR^nN*w9J(q{6L+3eFFx_oK!`amBpDRzzwm5^} zEnC)|)aQCUTit35Ti;&CTNW*AF#JI=e=UZ^tm2= zp2udIz_j^iZjZQ|Qen@S-tgfa@xUbh>uqGzGv|2ru8&DwILo8}QZ{F{0ac!PLd)wN z;JyLcUWzuf4H`(Ew^h+HHzPeM%?Vy9nDf&*n0Y8u4ySobj0dmp+|rm?Sv)ki>IJI`VlA1>1 zSm*U$=9S5FCDT0n8x>rjlqyoe)DbO)QZm}bJW=Bw^B|{tuH8_=Jm%@qQY^1|<`qZL z*)r$mNkqriMt2fnLzf$&hopjD8=AO}KF6W8oRY&sGdB#4+H#q!m{9~uEY0@J4>F*z!|JYbZ*i}tK0wu`FM(S-EsE!%3HBQt$GNE9s(X%WqDk*L*N_(M3SMI3^b z7N7(V%mufD`uok5Ff12(|FH!Zp$$*Y6p2T}#WK<3hAyg$RWM|_teJ5c<7iuXUQ}bI zRv0FE)=RUauutllc$_#>wy4yD2%X*2j0;25b{bYUc~>XgjVK+=rb)tb21}(HYAdp) zEGZIBE$R~jLLe0iS%|HKhs9BHMsb)u$asL*w&|X0qA~KUkv?~*@vzkS*l7;*@G};B z8#^^43|XhjvAenJBDltx#ZbzaT^LOrbX79RX{LFP#EzPZ*cUw@tVCN3MYNzr+vG}r;@G;ebZ&XIJJ6lcrGPQ-9XcTKyfpUE8mfD4N^RI4P-ZFo|B9pGEU0BnI z-7-#Y3;XGoHE6;CxlyJ+Rg>MKdEUgUSZ$1 z@)sCfx)?(X&SQ^xlEKqp69lsHqLiXu^MkyWkeZrSiB&JVMb^|1n+Qu+8yf=Ihj{#u z3uE3nz{8g9xJu^6KJgbGUTQIq`P%)2?gY#Y3(pb9Yq3us^n30ui%|+BMa=<(iABY5 zsrRt)4fH2iM*SvJ<{9E-Qrx%nl<`5V^Bi~24|~?ZOQwy-z!Tr@c@uRy$Pve(N})W7 zVlw36b8|6gwq97b!Buo_M_OUn$hjDrOu*IX z0JBd09^nf4DG&~|`;n^I1qsKB%B3r-l)M^ymu77v&#bs>*@+sFTe|ETdr{xGY{C3S zd)>IK#$7I5R=coq;qry9cH^@7wf4Gp;lic`il2RMgb+ zv(-fsk6}+|pG{ysWyM9=vw z13l%Uhuv)!ET8lfYh_5R~5apVzk!aotEbyjb8E-y?hv@!ijNFW=pKxAE=e+se0zZ#Caa zzHz=Wz8>Eb;5)|m2;blE_M<`GxwePzPQD#{kCV5ZcivX>jve=HBt4Puzwox#NBO$^ zJt@~Wq+Gjl2T$-rd%2!XoxcK~_&PtT=PPgx-@|$>>1#Ak^5rXeuAabE-xx}4{igjk za{b7mWcmfJU*S8N?+YpQr2c6A%JnOhbv-tecpcw=dUPo9Ilj+44DQ1gzFE_f_rL8M z(XoC1k@T^>%v)^Nx6QQd44FRewSWP)A`OJ-Ssr{=iA749^VOkxAMLJxuL{e ze0TBP%D0Q}D!z?;=kYD)`^rBJC2r^Y5Z9|t=VcjV69(>5_^iU4IpRjjpX96_f%n8L zd`ZhCPrf&6zDrM`d_`#@@ji|&|69NFwEkp;QH6g$)#7mYYBc?c^K8B=uh;Zn=+nfB z)D;cmMyvU?g=d3iE{^>-z-{SuwpB~|dymWKCEhtApA%pA$LCz~(y5;JS5j4@kX_!# z)Ntldq6*jyYyu7fJAem)+knw=Ly3b@4m>LPz!Q>x)=;8sl;;%ztAS;}W?&Vt7uW#Y z3G4vw1?~hM1nvPI0qz4H2Ob1^JS=<|SOh!{tOT9}HUNu?&^y3p;2>}ixEr_=xDR*` zcnEkHcobN4Hsb^C0Y(cb2gZTNfmOgg=b)E>RpV&~+zC7?`M?vvq6xGcO*t?Q>^PTs z0Z#(A0h^1N4{#^&5bz-In3My(F`jpHBI5@hjMENyd=mWu50`+qkb1x}V8;~Z2RuF% zyudxBj01QOcmjA77#$0p%NPf+Y8rF}9tZ9N4o*kE0h`YsN}L291eV1pFNaRRoinHh z+y^`iJPbT8USLBt>kB+QpK$~C zETG<*z#7Vd`|7Ywz@xw;z@7EbX&iJ|!ukqa2EPE00|$X8ub^LG2R7;?@G!9QEas2R zYXI&9b^r&jra$0G;Bnx=72xHyLq*pxK43Gj3V0aU1eEt#9Rx;sKhz0@CfiQ@VMl!W4sfXKlX7Ounb#y2-plf2HXdXolE`(#sl03YyuYb zKxg1!FLaag8>v?eUSKtFUmx=V7I9q7G2q}P_-`WRn^|w*;1==)zKQ%e^t_360am>Q zJ^`Kt9tB3XK@WbzDCc9ufhXU_yntof!2@i*nfXil9gG85wF7*Ung2VX6Y%KYfd{zf z-K`hLa-9Q*+DK9BJM8-QgWWL^S41YY3L zyI9Am;QKKB3H%6j2JZYQ>kcgY7<|F){i=_%e!zxLfFIa=AL9ld+y~vtpv$Ki7x3u) z@Hg=IXILlT;C{w8jd_0-Jiy~$rXS$ocfb#fewT4iC;d3>f&0D>e&9jieqh5B%mcXd zN!I0j;8V;Sc=9Oifrp=F{N=R!8T|rJ{(^piRnIWr8Q}jF^93G%9=cZ0&u`%qV9^Wk zA8;S=u)seujtjtll5qf!{*``!Re6a-Q6>4&M4}aVv>=f<3~V0939U0p1No_i*L*fF zGLrQ8L?Skeba5il1Ux>87mxuP$~ck%xbJ-OFC@)LQG0>Svl59Dz`=_XiL%+O^CgKy zGqB^*MB)(eDDRoBzKC+(V7X6VJ$Qg8f!-YG)Id96R1QoLxHys61KfEH^?=8Lv5T3< zO8NutTSb4s!`IWUiu^Y61+FI_xaW=Z|2o>;kVxzY?z@rs&4my85{X{m@lA{icyKfI zC7&ZCnlGW>w=h0n!#42FWBhNYKJf6(iNq0L+0H~FektYeN+ddfgYTtZ;GXw`2UvC| z^Slhap8yYV=Y5I9N#J2%3=7}K z?}=D=r~ohS!-Lp9uP|0uSakW=g3Zxw-s{h~Wcr0ukSyE278o5flsH8)^dopz$u;?? zn(!m}1AL`EL+8Z_g|Vi>s5hI-U3@FaUnuzt3S+w>wS`4Ha%v0X+jHCU3ybOtV+#tS zjRo@yi{_h4s>v81;oCsFML>^|?U9@E3!}9%YBRrQfrFH#y=bS z9Hm{Z;u0YFjpQF8Kbn!hmi)uyXVPaY`O?1`sJ0P2x08R6d`w~Zk$gFuP3mLX!jI%X zqWJT}TsxkpwLUID_>uZADgMm-(GkzvpJkj=$lpi)xDboQFDE2rt1s`km-?8r@FV?p zX?;W^{7C-IqPhabW7IQb{2pGkjtx9@TCo5I=_|10Fj z3(;vA`9TgcM1Cfn%gNtOermtM6vaqn|)|>@}@mq2i7MATgrM9qg zM_x@~)%H_s3!5VA@(Zi#3M=OqmQiCtVG%80>jee1g;h1fvZsLZ9`K(8{~dzAwlEfH zHSFEa{~E_TX8zRc9m_sR>a8t|tw*jT|5+Iy`J*IXKa&3n`FqLV>@tCpAHdkr*ifQa z@{zu4RX)qfkC9&v|D?!ggUDy(1q9SeWlh0acWL#=TETbPP~v96XXG=|#MtW#*7JXU zK@I4Q9PgrDFZEiI^`vX_5jnq~^8J)!Iu%cwD>m&Pr~J^Xl)pgv5y}n!nQ^RU080!B z%RxCB0X;$alZt;w1WmIY{ZqNsPHw)_Dt2D;sK590p~O>CU)F_{jn);c;=ffsWY6Qf zmU_)+3?*hL-EI;7*d=;xM{aFl*>?D&De{y2!m{~=aeB1;u+Xk-7wzw%eM2ym_y=u& zYh+1b(JjJXyK>>89l~GR^J)vLg)xM$z!UOST|x8k%!Y!ni;HR*E) zjqvlcG9U1sBY5>A`LB?Fi2QRUk9jmR0m%kCA^~`Z_Yc9l49_ zI+`WOSjWg!8B1Faoo9n@EBFqv_xz-EkfhV%!fk%!x)eGs4Y{wOK`dMmvV!5#hARSZ_Bwg_m)$3z_$l<|@Jxg?s$4<(jM zhN+L;6~2#0YQwJQTYeNe%%;BVji)IcRNpNO_1$98cc?R~@9sw5G0F^mr~EDb-weJE z_S7Gh{^_;LOh+cwSkS=#rUH>uI{-6(>K~>4M5)hsw@0osyeUa3fAUqzWqn`La<;J2 zU#yYV(rz>g@)&r_B;Vj&9paUFms5U%@_VEl{=6lEl&KsuJCWncNN2`k*A_s-GG-M@ zw$a(Opx6q&CSnH%72mGNa`AVN-tFjx>IgoMv|=RKhX%nDuW`vbyBvmJ9|6x{@W>q8 zN9Or7`A5hvahX6ffAWu$A5Y0Q^T&ZWLB4Sf&HOip^Oy2+%45Yt30!fdPe)iT>)1$n zCFRd(`3~{lw&&CrwnjFDe5C6xEEn>y{td$wL|oNVL+y%b< z=Mw|gb=@WQSmmR>uqkIW#v~~qma(MWle9ZoK9u+l*Om?|F|gb6joGOYIf`L(78Nv` z45?)8^yo48cQb|(e~}FMe@Emhs|Q;n?+^KRegR^sCTuY%L_D!(T{LN=eN)9yA_u=p z=6`Esak`y0e7L-@HK%})S7Q284fVo;CBri@)EL*ystCWV*F*GoqB6Uk7CJmlxi@nt z@c_Wi2mNCFnFw9!z>Qwf`LLAbR1FH*FVXHh_#L)g-I%;3N&AtrAvYfjB4*6&6Kkno zbTMZq$vTPESO8mGUVxFdb;vb(r;B*7-pSpjHh!M3L$okX`q|hmsjZg>euFleKW7w=AwV9dE zJlgH1U5&I`m9!(v$v;f~I?0C~;^r?VJt-i1lg2XWp*1Rn) z$QhL;&Wnw`OEG_Mpn5~Hy7a|I*6$JeIa;m#8@YA<%bQc!e5vDj(@yyO723t-4<-IA zIi_9Bn7jqI<}AD=cM+Sm?Rjq&HeYNQOz2jQ!*GoH3#C5O#IK89f!m2YVd&FHd5oC! zA}J@XAtlmoE%^=Pzen z%NF`q+Mm$raoV>o%kIAmkG?>8FXc_rp|KCk!uaB5r&*+okKmgC;dWF1t&+idcSH2L zf;aJhzS)P(qx=NrgId1XEeh#X@}<0~X(%D_Kg(~|W%`S~kvlW|#l;0;KGXa~w$|jJ zHp5A?sQ~3e;BUQRC~=kGH}s`~_}i6{2Sf7C7d=|U=y6g|I+zrtyEPe*#LFeHH^{xO zPjT%&Lazzr%QGN*B{OyXDkEz`G^J|6@bvj;+Q)I+rmdZB%r`ffz)%#n) z)6_ha`1=q~(hsN)^?og`KVC?t4+x*&lxF7QFV+pu#Zxo$r@!6T4ki9s*2l=biBs0e zzTNCM;GA&3(G+i0k8d2y;zj7Y!HA)|&7mZvP`HOtowm|aC zQixugP5tQFB;RTrg!T3h?DRz^A~ERo7+ZZ~aYar7ZdmQ? zK(A~6s*kXs+jG(JqD&!2ZNZ}OdQri`@Y*^^GLKc@In+6ns15Ppmxl43rpWzhs?Y&m zP#{J<&P_I}=N1<d*> z-_arj8-@}U0OTaziNCOw%PHg+kv~EAwYNnU$-dsi`;6Wo?iI%ST5~RrjNmX}1hU-t zVBuC!kP+EnJq*9edfY?*2YZt1k-9%L^LG2goWd+Kv<`x-#|z*&(Tjhp>v3BIYHPfO z_^rlUT--9}bs)Pa(2H60z-~YCFWFWQ1(X^2w$3QHxAJ`!{0$qqKNZd!JChn`GV7;trq;-x zvrfCA0Ckzg-&<6`#w?3}sES+UZ!I^HIKT7?7 z(fZ+inAXTUtTrU%1vq+YGeCvPAFPsOS331|`JbUBfld9*_{PCRIk&-m6ZZ(Ru zUq$=gx4%aF_hh!W0Uc?77wxNW{`a*PIzLVO7|#UlNaqWq$8&u8)s+#-iGMMA661ZR z#v2VkaG%Y_%f4hQ8@`KN8zvSOG}5k?b_aLzOpOErj9+EsE2$sRPwH3I74G(P*3oqq z#bOq4EhugWU-Ns05^p0;lj5hD`^gz`VVuL9UkJM4HTU3Cz3s$!;u6&sEml{6T9=E31(Ex>BC;x+E_}F(cJaH1 z5>rEal})eJVT(_o!O-NXaSe@Yi(R@0Jkfj7pP!KReTaOI{Ow|w%zBx)Pdx^Zkb^8P z!%{q}sPY2!Tkji6$cgeo*Hk-#wbVFEJ#m)EGsE>P4ouDPTvY=`k2jXUub~O?qvKDNN5;SXl*^gn1 z!^SsBbCqPw!e_65&-?qK#5aU~Nxn_;8UBRYb#a)WX;!Wk?=*{Hu=-B;XD!Uuv41G> zBd*iRa<*IZjM3AykAI%$jHG>1 zzsp@Zb^zKh9{GF2#3G5(>LB1})>{*c3l^tb*N4~33bUq3-_Q4E>hJu*P~ykAB+NSC@21-4r2eR7Q<>8s0?#a1bJhx7 zLmM2E1+w+cvO;wQIoFP)aoV!BFad`wm|(@_3~}~U^xc=(2Pxm|imVFltvt$bcdEU` zz585h8hR7|jEDAE9Z;6a+Xdbe4{4l~_1Yd`L%PM1O_$ZgWgetn$5)Yi+KAspmGD6r zk&`DWKT7$K+%L@F>tXS?{eDiZP-l3AYmuy{(SO`9+j)2>@k7#rFZI5HFcaQ(GU8xb z*?r6^+Esp=c=0L2$C1?I#^0imi00$BJ1@e{X~B{l-MHc zZ{(i1ey!ZUYP{u?I`afXgGBZr%*lvc=zXuz1jL*EiRV^mmZmS_5u)iT<;sX+Pv%j7 zFZJK7bh%aTcc=R8Fvs>hv2R4ML|Rkr8*+eLWac_HH-7tF;6L;{`yR!ATV%xhsmnz# z9Li3w`Eu(g3%wdl1UDOfWo~>YOsD@}4<$Bg|Ecyy&X>o^ zvapREnDp}!{WSl9-+d_`rpl4oPnvbZtw~!j6gSUIrDZKF$oW?Wk(MVxLO!C0R-F$& zo#b~=A^q4lr^c(qs0>0KEo--BwQ|l0fwL?yzmrqIjh>TOT2Eng z3i+c6{G1^F0N1jv+r_fsK(FS1>V1#d)Z58#=G^@`+>Y@6TO&=EQ+|;0KPnwk^@j0N zHT;&r_Y%lY%MytdeD{E_BS<7Rk0xRGhvzb~`$stMIXQW!K*4N^f#x#Lm%z6t&hPuU zw(~?m5}KXQ|78VN6UDL5qEEPh`)AZ!maZqvb4AIxQ_f6L0jR*x5yR#Akey1HwX}eT zC{<5j6tQ9i7Vuj%i%F4%q^22VvfTE<(BXc@v%4gbxFO^(@DHPd#;?!>sH-ewup1&H z|KQutZw)7iell{b&xbUnJnzDwFtI;aTCTC0z&s3!5EHt}Fyz7ig^eKFBKmG3Jw;+EU$)94)b)S7X57{iE|19&jBo%pm z1$@=~mSjcfk0j}7{6yn-tAEy-^JBr6&0Mlq%d-Er{Vb=SwKLIwGx_a`u3L6{Bezm?e*CGWGJ$LwY*W^W%`eC~kbTPNJkdk* zW)Uypw>L5t%Rf91XYN1B?$zFMgk$VAtIb_Yb4Q3vvz}XNzn}JB7Cn~DE|~SKx6hIG zMs{Z%rRv3UP&^L4_&k0yqvNsrE}}KUy7LRVQ?^}p|4aQt)XyeQ!}bZ)k!t!Mu2mWf zZX|zr_(lC7;oG$rqObW)(vQMs9_<^|`^; z$Pcp8jps)CM(Agd{NZe3^+qlI&qjF^)g}_>X#cw+SElU$dUMW)YvSPsuc3hFkCOW% z8_qEClC9u5u@LzS^+?9^a+iz$TuaC-vVXX%j5~nul<7b#*$sa^E%@sbp`Uk~_~*m) zrTUY|$K>qXZYD1CE|)+*zY#k-954Qy`ujI-tNkC2!8$b<5YjQc_QiLOs1z8m@%tZS+tdmFiX>xIgo$wE)IQb~lv8y%?V?@0 zYaqRyD0oJtRrR?Qna|DAe@`Ouw(z-GV~0%qIBADeKb-J$4rY%N7)>bno&?`verq^U z@!cZ#>r&~1_nC8@5IB_@wGzroBbk+W5T<;pw`jt_lrp*e-bxV;&y%H*udtSUeyaIW zDqks+&p%vg>q|ZPy8Pd0eGw7)y8M$P+)Y5A^*`PTf@yu<{+O+#qZ|j^3T`&78yDWhLkza}H!)nB6d zZv3u(V@AHKze4jJJzf2)GxA;i7R{G>?#rcjeMY{kzd`dQEnkPfDUhUi<3?-_;kMc(sp{52x>({&D)o z={u)qoSt*~#pySvSDapR`o!rEr!Sm-aPsZs(8-;XGbdM0j-1>$IdO8~*1^%;(aq7x z(Z$J&lMg2kj{hCMJN|b3?D*I5tK(0{kBlL>lAKMxI^I`3hz~TK;dHw zpHldo!j~214QT%grz)JIuukC$g}emRd^RcEq3{lc_bNP~@G*r?DSS@h%L?;0YX1tS zDx9ORPT>lL>lAKMxI^I`3hz~TK;dHwpHldo!j~21ZPNY~PE|NZVV%Mi3fC#zq;QAA zI~3ll@PNX{6h5W!IfXAP%-gK}E1aruj>0;HD-^C%xJls-g?A{tSK$GLk12dg;d2UK zR+u-a{VSZRaE`({g)0=UQ&_)zfp_Jy1-5aP|5x(rRXNJKyJxdGWsX<3n)6rt;~jF~ zBxldH#nX@8iOZ|m%`sxU`L=9YdA_`Ndi@%Cp}sv`Ealbha==)8Ij3FO_i)=+$=gF} zE+aULkx2=iaF^fWgX=` z+U6z8W$vxIw{*|55u19!}EzNyre zF7))Ne4!8>)7VTnIjLzON%h=?w)H}+bO32aX8!-B?F4-z{z5GEI?6qkVU?o^n-@ z&vB0Z1Ah|=bE2U+HZcuTz7<>+N0`x^(;)Bf@9EuA9xv@K<)Ca4)6H#Lm^3p-oJ964 zO_{;f$StH}eK-_lgHaM3h-Xv=OYTm!Dh*%k~+&l{4S+K?PrQDj4oOYi4QM_9|eGJkG`GIo3J6+Iy?`Z{=4$qZK**eLz9*Tk1i9vmE; zoK^MnqVx(1(O2u@K&3`ocm6QMmMhFV&t;ZoU7Z9AXLNOL;B*btU5`1|p5q+a`|~%$ z3+-`E2*+G(623NPHI}-Q*shwND` zD?oj7BAZCReRICCl=Ii|UUxf6QBf$XHEY`Y+Run{;N61-E`HK-`~Doju$hBby5W_IjzELl#{T8X;qK6#n*0OjXT$b7{gP8 zj5km!3{dLC4Q5-5+0L&CYh&j`8JJUDOanR7Q5a5MD9=JCO>}Zb(!F_uJnD>tVnjsE zkPTDVL*nJYcX3h%^0Bj=?=CCW78k|Uxn?6xT>s_qH*VyF5hK(!xG-|I4Cj@`7umy` zl}h>8GjqayS5MCk<`felVcVL4jU1vbuLpXY1xi`( zOle5t{Zeyc04H^_Y8M!}ZI9O&ldE2SW@}I7pScP{$hiTI4PgV;${p2#M!!L*+`n;6 z$MDMNS#u;@sk&Y)A(c{WMR+Oz6W6s3`{QJro*S?Q%p^ZNb1+`22YyI3(aNRqGJBG} zm=+iS3%Ci+SsQQX#1EL7^CWP&V8))l{7s#0sbd!(anXj}o<6u~z?_>sY_jgm!wqfS zEK%2%{2Q>h=ykjivwWB|bNU)k2p*1I2VA;e|zP-Dh^HQiM=kiGZuW~l4)Wxw_=am(LHuEH zNcuLe8R+RN>)~80?$?xmgxV{5<)G_M`W9#r`AzU{MWxdU`#YkBfcNwmaJJ?Om z!C84->1B2l>FZ+-nN$g|I|<7v>cq)%b)vtFw5x|?sH0A!nD@SQ93zCJChdq>U3_k_ z$+&oSd&m+Aksy~M=V6cT-eMOc-cvN<=q z+?cBTQqxt1`HvIPC+D;E;$D~myy_Cvv|;YpqU#~FoL!BHFvd}ZF!Ya?h+%YenJ$x< zuH?yA^)K5saTuW+yI%xGkF{ZwZ$w`kWhmSBK@4a5hIb@1qLQp5Y*jZK@D1(O-D>aZ zZ^wT#tA*`Y-`BQ5>_QzHLAJomXdR+qgA_PaeR4*umBuxFZT%f1(kSFl@wDZTRHsDj z!I4SA8KKdoG{S4oIwT;l4tEfr+9?^QXdSnz$0P1wCdrqx6Or}l9LRU;B5JA!!S56i zvuk5Cg0W2@y_vZ=mtB@jgjQu%8mC1TMk4eiC!R_F!ER7QHzkdYNP|RD@VeM3rP*&z z65_bsI9{XK*a%Oy#qH_Em+80}Bpc$=)T6yj2*F4;_GQ2-!hAGJA3G3$Va#66iCP;k z10lPWb`CTat7(*-IpU~ujWMNYF$UKU=NVtFE#LXP#-5p7W$E-%LC6_P>bfD8LLu7} z52eQ_j2QzxGwc+zF-fED0MesNf~IsTlGrPj-3&EeGdDkfW`zj~h3DXwIjv`H#*Ci6 z8D?KpdYL<#7go|GvwLgOPTVX*8Icf!qZ+BF8>=!adq0||TL&_5OodN`um7lThveSFnP z=NsyT?5|qV5(iZ$ezK7hL8x*mA}${pJX6}@k?m5m=ShNnS?1mz|X7|8pHw9hqASbek$QT37zN)QDPA2Cbh#X`~u6Vezu_S?i z;BF4;Mt|BRb{n{vz(~ACLiZ-JVA^72lBRsV-eMFB9?A+~;U3Pf7rml^4^GaOgWcCU zXGLgZc_7{21hw8N$!y_5Y`T_7i!LfpwddS;YpdK4Ep3iZFP+xf%AD;DP-xK|Z|0xt zm5fxEpmU(yhSlLAhhk;-b;EI3Zw96VT`3ZihSBM8wyI~`@SqL*5=OZp2`|^-m zgzZulSGp0f8&@W1L)|h3?y7ReE?#7~#gT!|l|6XK$;Rz?Q+r;$Ur?^G)nY^_2+?(M>XDOdE}nag_`%TM8S|5T9># zd%kHZJ63M#aA35A?>f!CV1Wb$;mnPYbhVJg^lsvhayQZlE3{4VlVx6()Fv*JjDwWN z+bi&oFkP@A{R-W}O;=Ji7%SD(#`(C0p1Mu3>n*xky^s_cl6r)z+|EMAl(D53?>v+Z z$123SLN8EnFp7l8##@{w+i}LYoC&?sn0hlnyuXcXmf*O~_1$tOD&2o}9zbZz+*m}n zy1C#USdp=vT0d~u=u*a#(tnz_{$JCZn{^V37m&JRSqV#VzqmyPbKSJL`8vKf#G!5N z3^^~o9jWH|6e5(X-zZP17(Q|;Pn`&fDcWtEGL$t!HvXXwlJ(nF-MjU3T0W_rQ`9?k zYpjNln|9W)IYVs1pbW=S-;U5w-x>IP?#*=eaxYH2FLBlgm&Ex{mCc!4*^dd=m>cx6 z1PCw6PG-N}+{Uxp6G0p{?p!+G?6U`IFl2#|mrB%W{*oT>GDC`Lc}ikHZ2e?fnjRHXGr!jl|v`ju;6rtRk_bhTW0eMY`3 z-?q$-fB6XIZho%5!`D1QeOJ%H^AvyU&+PnjT!F%kisw3ot26N4r0I7mY*2dd*7OGz z?o;@H!Y?b#=+1NNow?4L^<3JH+NDN@^D@?5_*y>IznVO9qbwzd%}WS8?`H~M*5C7Z z-?5e5?=rG9&6;(((yR4|EpGjhh1FmCw~Z?+ax%xLy!4tw5t6?rJN7M$e~kWqq}sd` z+Wz)Ya8>`KEkD!!{^VZUgX525U$^C-zBXbC_CA-+KihQtrAqe`qij95Ue!Oa?c<6+ z_GybhEPu$BmuY$LZ_>+;Y5Cwa7VkFml2y-h)5*z$FXf4B0VqtBs7ZTXAM5!>;@ z7Qg+^@3_Bh%Wu^7mA|spT>E1W+VU-0e(W~e(v=@l{(A0ei$C6&KK?_G+xFYEeQaBL z`@K)u@_V#>b$v$r@7QuXs*(TOR>RBRsr^=E6jk1pkugH@*!xE)c#Z6B=4Ic!N8qO! zBdd0tVG-;-@EV9Ri+}dF(Ic~2QD(;fP&#&+rAO;2N|&(~_MU3tiP08r8)f0{0t*l2 zSa{?uI`GjEb8+lPHoxh;HviarEIg#}#Jg?!#4KCyn0c8BeE$Q@H-|RyzO8LGUAfc3 z_!+i-uX!0WzpY+v(}z}B82i1gckJ61?pOWX^v^bJYuRi0|2p-Xs{fF^{6;O`uj9#V zzeCGg|C+u1^UCM@1KTp4%RKKLI=X-eW&R+gC z^Rf=!o6?oN{1>YK_M5|?lJ?Dx#`B#0IaFZRJ+psjzqXl|zYlNk?Bj|1ZA+)W9Db+Y zDxb4CndMG@?fy#k^55$Gj~&WBzkH>y_mpj)IsQK^vGdx0YxeSy^sBASyRJsipRT-6 z{gb%LNhW_3Y5D$d+7_AfpRDEH`?8O3B>U|8clLdMWp?_EWFKAo3hh7BzPs{~?3XK_ zrR|TXKFFN^rCJ`>^33_)r1p3BXD!Ce^?P2|FFwNhm1+4Q^^Y>~yK#;LXDk2g|9STQ z->d82YYrC~&i`*z`HHJO${c^YqtAyd{!IFeG%lC#{O3bov6wU4ztgRs`X`y?@6+5+_j-_D@J zcC|-MYOh@TBN_EvJZJaUT@4G5XVe?hV(nA!*V9+vuNn0=>OSnqBkA}8ZSQi|x_S@0 z91F`c>U~M|?g^E9S9^X&y;jAyEd$^3jC$)dy)9#WZ5j1$P<)jc^?EYux$(Rf+@|k6 zI;QsDdpf8qNo`yrigWircLRlYqV z0s|GPP6~#;QRMt z*{kuN%=RNudr0Goneubu|Kul=g#V@Kk=EyZy02BYG#taWd&0~A-iz9F{Z{#Jj1TS2 zh!0g~q+e??do$u<`yYL+7XLZrBdyOe^)KR?-DHe2v)H8%{X64#uKjSBzCOdtUp;5< z^Zz^a*sG6nc~BTHQn^+qO9tbNtsC>*3NG58U?q^by1#vgsq= zPtQ-jAvgO>DlgUkw0Q5^((6_KyZIs=&wqC+lM1f?(_16vGSfde^mbR{zZ?GN$WQfe zGWg}cdm8`7{zh7#QeB^B#pmk9^gh6Ab+h+B+rQ4RKPS{LsLqHZWb%_6XZ3H>*JWEq z+SU6XhxIi)`dn7O^y+Ex*%dP@X2oY!R#sJBTsb>lb|p_1Htu!iuQ9CFKH*J^LIhq?4*^&+v{_mj%Kp}_ObcyhT^i=H}uDZr0jcoraX z>i1>>a!-w$%)Efh7040r`havl|z9-kB9oP!ym4dvOQcna7hQ7& z$6=8!y7lkw=s&LufclV#D^7?NjcvNHPCYLZ2o ztcp&(h~(Lttd71=LUOz&8={M37!x$v6fL=cooalcrN5y-qxh%lAY5qIR1P7xlAo;i%{%VprCENVySbknNuEOs% z>9_mQhe0~-0{;_$oRaN+^a=!V+=c!ZOnRpuZJ9uNp1<4F-|a__)skN5-)+)+{Ak5g z(si2N>qnoL@_J40^P|6)bc3e%`_Vs0dXc}#v_I%a%jc3_Y(}3`a>$QDY{I8h) zAMw3WI~dRzwWdP8Ed5tl)B;gvIqk`?VCZzZ4*mfI1;J0LIXYO(_{Ie7Fm++@7j80+4IW^mv7j5iJT17BzD^J3ArNN- zKV^DB@Q)1Z%;4+fj|;wyLOLt>_3NR2@Q#H{HaI$k2?ifvS;hyw9FZ|0_%=At4W6Fm zdBwq&$(}bc=%C+tP|SEH1#{?ka&RR&wIn!$(ka26aM*dlrSm**YH%5Sl?Hp?;CW@i z%Un+j&SDJHgEnS&e(>bkoD>th^+L~^5qzT1^D2TKW_LkwAB$8Olq~bSnZYgRd)}Q`8qfQ#7gWOCk9)zXboo6m$bmNB z_kv$Tx*vGKnrk_e#tZfqd)^Pd;KQu!6J9WOJO_Jt!6ztt(hE+z*zwrjUup0YFSvdI2Zd0xmb1IPpo&5K%nK#~e(nW-U^#!`1xsmg z%nPei-UEKH6e{iagH5YE@3Vf;herCGAFM*aKJN!NFtG>y zU?&}Y!4LjS<^lT4^}H`qrJgekY0%_(UxEaz=9m4Tuo^q$2itK@9`b`%Slh4q!A;XW z?`wW=HL0)r!8C;AkRRO5RKDQ{J&^pHesC)Te3&xm@`xY&4i0(L58gEv`D2M;=x@;< zr2DNO$Wihy_*U)yJxpWt{#(7=vk}$_GhrVu_hBs0gjuWQvPW`fcgkgqNldtjHT80T zM((*wE@d9MKY-oOUHnWukyvvMoNmJ?M$HfI^SZ7M;9>4Fj*FD z0#k9De;z0zC6&=Jkf3j#cTYHCRrVw$wC&d_4k=%L$sXX7q|Q0Mm!@W zP0>o`RJ`6lW=fl*{{a1pZ}5L$N?W71BE7|3{*O$uBN~Uji#PZ`HOby+dkx7O{TEEz z!RR~`b8(;lIc8*>q&J*Fy5FGADZvTqxrp?De;3trN^pW!FCx9sf6}CJg1#@E4f?+X zdrk>XP&K-y_$GfjtB_NI6VwIM7Qfk$D5nG`=wD%@;T|r(bCB9i~5Iruf~4ra2`?{ODd(eDSURTvLA3kKTGY>D&A|lRoB0w;;vE@Ab=} zUrxz!KUxA47r)Pche@CCqnAtl+x?%L^hrN@2P|LwezUsFKN7v=T+(;=?PfeXBhjm* zzYq9V8vMH>(bY&%@gDzrlim}FPAMY&K^@=TNc8&?NZ;wd(Uk9tM5|<}KIGqR()%OP ziW#Ku@;90E!ASH8VYd(aXB&DRibNlfmHvp*<8UPU9O6^_Q60~bNc0hz-(F20jYJ0o z|Hm|aEE4@5u14|Qnm!(hUSCc6U>0FA~_(Hcn%la`d_jy_7{);Hgi%ON; zUm~2vpWI|Jw(|chGo)Qy6$-79(_$)o>I0_2hrwzXyYeiVAH?5XdU5K_V-hY#+`ZiNlhV-HIs+JtpQuVXOZPl^6s(D7d_`rwZydr+;=M{hPZbrc(7V+~%ulS%; zMfVl)Q)#dGOS+^nIl;a7%QjUMs}`|-NJbwiiN~H5ouc0Rl-N&XslWDsDJzRzE@fYr z&d_?X5)rpUHdPfHb0Mj3*i?1wK2as#v}0*tO{A~fcZs|`Ec3{ng(pz_=$F8h7yUZ_ z&oVosA9H0UR%otdNR)q^+}ysUG|a z>{@JuAjL1tGPSD0TB5=%E*Y|yd;45!{jS;6x<0Hm7}hdaP1UpGe({O>P`t6_5!(Dg zq(Ee7TQjMbZ7Lf3$s$sJw5eFEPR4N3rix-YGVVXwR6O=m(HVahQHhk4#nwzC^_Lq= zsxo#eo<#90HdPgyiC+65)xIG{goWU2(#eHAVXbr{~))nxmhUb@MgZ z8h!U^BqN&ah>n*ob2Ql-eN-4ASCfO$KdvNsiZ7UriCIxXI#2h-n3#{?!W5sX<(Qb0 zlSz*<&2vgHF`LD#=4%=gGZ|(mF3>b4rf?bQ(VE7@oGpYKqb3a#Ga3a}T&U%kn0ky; z@mNh`Vrubaies9_#M~VdpOt8`D0(WwP&~z~0OD%`1;yw2qOxG1 z=x0D*JXK38qw_IU#id4cA|+MP+hnxUw4>^1t|X@`<_2$6H{NOS`TpnO?sJNYXZUx> zSoeq#t_a6kDmMRuaIC#&k*xGZw=q_4)HkjsJ=1TYB`7ZRe=H~#)R8&c5KX4LM%L&e zO-7?lczVTiGzp4nmy*8NzgtkmieKlC!E8j|8z*zF{~0DPDE?sy$xHlSm}Jx&^*}l4 zdHz4qX4IR6g`!hk27rmJOV~o>gmFcK&OsBNYUuH_L=D$@TJzQDk zV6IdveG5G?YMV%8ga0|2s2TCFY>Nj(os7CwH0&Z@4C1I`Vq7oxA2dzAY?=s0 zal(>KbU;6kQg^X0mSEHmrf}Wpi`5-e%VJrFrT#hODZ_E!&H+A!aJ0PR6Ob%wpam^4(;wyF_-c@WnundSMdRSK5(0Bm8)kz5ayEY`On- z)6dSZA90Zi#mi21=8byqMby38|BR{oU|3fiVOv*>1j7{`$%~3k&5Me7H>2vHX zxTP$9y10|Ee_`J7Gi0?ydB1~_cwiexW38yx_?gyP#$vt5YJ8k6D=OmcxnBG%+b#~` zSs)vG7k*yZqyq6v4dO|o6>$;2zV{}L*#g1EDD&1EZ&Kk$O)6$kO&V)!7R8Q0#4dV9Aon5^hE5 zc)9nX21}-0POCF=&zmXn!e9qp=C(-iUC6a9H>g4nZi@!7YXGre3f#0U9z=@)M0ef< zfwvJQSUgK$B$!TnKPUo0BzT0qW^V8sYH);TH;QBGz{89ocd=Y zQx|DY5jozt%BkP}DqWcUJb(*6y(dbhH-7vN_E&=OT;9FqOJ%T5>vjHmt{L5*8AD$5Me|=4_nfAwt^WJN(Y2Y8LY(No;y+Ja?@yu#H^dv2e*x(Z ze*@`>zg)puP5r$8EfT?T6tow-o$!tyj6x$uf&++et~Yk?bi}Ll>JwBltX;aoG2m&< zgekB2i$PuF<(_d3$r-{6`BJ$6x!0)jxT3PLl_X93vY6Y|Ou7oGJZ-j-D0VdmV79W; zrP;XHwER}7zZ999R$yy*u_us-X`^il-g^pnYucDgsFyF|brTn^zxedC_ey)&MNL1) zjrTYTZ2EX9Kw!LlQMmh)jdJH81Jfr7nsH_4pY?m!{`^psrTzKmNP!VJrh9&=6>QN5 zf-d(XjOqNcuTUj-HkNJT>0)7WMMX}$R8-u!%84u2j@OY*T;(Y7o<=HMCk3J#7ec*> z*9$)BXF1I#w%AlWMip;jt4#@;=97{8+c%Keb|#l&yZKjEe*TvMX7=Ufu8&WEwS2}Q z3Z#!4F<#{rPAy#mbCqA9eRy%Rd(4Xpl3YPpUb&I~V}CaTq~-Je%yp~-t|-6s60>$* z>@zTJ`DJ&TRMZ>$Jw&3T{PK68BVt8TwD>XFz>cx)peS#&YQHSj7$>#FrYd90kmd5F zc1TsRuUtuLnI%beth$L*lOPmlde%jxu8=JP@tRl<98rFyb+nsfUqFz{uaX^qq@)!B z{g9q>kMeKES>j~mZbu+0iarJ=EE@l<8GeYXLi10iMA0|Nn6w^-^C!1-_IraB=X?R7 zh;3jT6%*uAW^*_Cs^Z*FfKd$G-H21gL`%e2Y%_YGB5qSfvESkaS4>g@$Id|rD<<1i zS!^~7Q&D15m9cx^!iw{3sw!5WM{24~RmZ-zgjA_bHN@Vql2n1E=FxhiQH==Y9AE0)XDVqZq% zR$OCesT62-bG~UTW!D}s6o|z-1lLL-qcH9ahE%c2jv*d#*4iIhga;el@HNYk{`6F4*RkDQA8CV7P*laUhMO-^dET$ zg5{JP^5DWkJ4ILqm*J1^$OR*{TWbXMfFWU46k-jr0_%N=6=7o0r<9J!xC zF-(fyY>>Z;|5n7stFwa@x?=e7S0;`66uEiP{rtC6`VLpNmh`H(bH#m}becGP#7)fq zUs7$fD6U-bS>r|GWlotgk96hIxkzwuJ=b3FBGtIFdweS4X$SFrvwM4 zgD|)e@jo>f!t;s-S2Ev-mn(=WH~lk>$8N%u6wT~?7dT^m)3~+Qw+O_dd_FRRRR3y| ziW&!b=73G*#}2T3GdD^j=*FOTbCnle$p75UAe^~LF3-rF`P4(e;7|Bf7uQ%89 zdLHj|^k&ZY-(yf0oyWVlyqOF9&zWRA+KB3(S)*I)GJB6hsv0Ifi*71O5W3)hq2!y@ zE&Nr)t#e-V1LTf+9Bnysp??Y2Q$IJ2l^EM3&*GQL24L(J2jx=Cz}PFz6Z&~kd9lpc zKQhbK$V0ay$A*U^Uv*x`B}i-J>rx;}@h4P{9I_l8j~NB{=-q~jWwASFQub|IRv9}W zl>V+wRmDcZV3F@z<5(R#Z3(F#*i=I-7Zn+K!Ya(B*e3!vtL9CKI`5Hs>ihxNo%QqR~q6vdVz7m;6WHhsinmts01&)U@F z*zKc8{nJWQHYN4|w2wR|=&hsvN9lhi%o}-LF3Vz(zdTK0={qhZ>lJBLx@9?+e_bt? zKS#YshJ^o0mz>FEf+DYYpAf|JbHP%4Upd#lk92v(KbA2@d{)paJ|MfF9Df1V-l#nk zM{@nmbaYO2B<4@VPDFnuHBR&8i5!^K>^~x>tLtAD6?u)E;mg>F)q0~EujL}}j|+;* z$T4l!=_}pHJ0usv_h4JHj>-!Zxz)iJTjDyI>BW!MKqbBqo|BZ$R={0Cab(rzmq`{(GrZ6kurY* zM62h z79~I^vg-9*T0=+{`-VZq{e)*HB~8yi-3wcI?LxKCj?6T!POVTaPndnRmIQ zjilx+cKrEyxFE05R*c2g!DlX26gwNK%3D$z7bNkbfv$cpZ>iy6vssjW@}gV$pSuS0 zo3~6d##Q>!CcGZgi$BWsasqSb=UZut#d?qlzrabs*I8eGw9^jbmyjA`Q)OQ6qjO0X z`e4j$W^AYAo4xiJ5S&sVyRK8Ks!`LCEByPZ61`T~|4LmYFZvmrqc9nbp1@a$TxCN1 zVj)I-SJcFE|3+G}hVL6Q239uv>B#M4bl}ndkFxI$kD_|RotX_Okc0pM1EB;2sUc+p zs1ySM0umqzU6S2U7M2zQfdEPqDK<)Ib_uB10ecrzny82({;U}6T@)1&%YEPPe6uXM z-aqa>PjbF~zSHZ>9PbF3O>ydZ^uMfUE}9hGqXE#(qR931J8aK4#hJ#=g$i3m%vqGQ zb93C&j3&jYpD;2MO#^pT7@f$Pny4Es3DFHOVQ?BIm{^mnnCmY9-YB63G@}yZ+10F0 zJVZ08{lQq1XtL6ZewYrdO*DGZ(c3W%a@Hl9Au1u7LzGjQXvV0dXpUyideu#7Gid@Y zA8tr=osXJ_0X)LlmHaE>X)`Xv0%&?8V41{BPvuxq-_aB2_2lL#6_I>BxjX73$1X~` zScDaof(jMw9812`l{}WrZiZDf>O<6_Sm)zp4)|i_=a1x1UCBSrlXNjiCiSAE-82@p zNBp##hNsqUYGQ}vaM*0;G;4ahNTPoV364L9M6{W34vB6v@f;G{CU6c(Xfx>?lGtYQ zIV7n~@Ep>#&6IOUN}H+Ykk(ezpx*SSQ`4u^9|JM-YcmB0K$clUj1}_&$AiJmxF6Ic z!MUl~S@5E{I|*r}LVgXc)>l#p@r0#v@yg-V#+xn1}rJj$?Pl zNz>hFz{b-!huo8(dM6lOl2!M{MrhgI$;)Vjae0Frs^D(YggNsq@05P@5k@{J25+iy zBLP?1`r$0nTS;z0m)c;hpN$fMT0-MNz&6YmEIQ#EG#&3ouFVk1krn^!Sc{=41)8qOnBX&(K)vB&e+Y=F#o-!ZccuQ$+MStRU{L* zAME8FL}0NpY4*+4S z78(5jLAqCWDu(EG-mMNscT=mjnObEflzHLKU8d?pCp>`h%X{|}&Ct^WfZbzKpOo+t zCNtjc#yezT0q7~-`*UH^IR1d^_}{E?4;r=TggU6q-iJ(WPe^DOh9z08Hx{8&i>TcS z8JjpD3R`rE$6&8rq8G_-pZNL^xzTqo?BOck?Wpjb67v$VYwaXXMYdh-BtDCI)-oq? zM>MXuIf+*c#uYaw@eL4HIEh`5@Rd&DR@Bv1PU4j)$!nd&u2P;>~-GgBre6Ie6^FfI~P~noWw}KI}(?4BVd^k#Wi+kM3Ye6 zQE^R~7)<^W^3V?Bnmr*kF+U-edWsb!Y#j@%In#&@A1h)t@+!XeP4r_eGVJ2m#(%he z#5QsL*aDr{WhP$^%r3X zcRXN5M#tcPimXT*rAI~hfJxe;YPoT~je#giGcqBe0^LPaw3&A#C7eaIjEdPQ=}SrQ zV$u{^#34PlJ{?b*G0}=`z)fM6=O0jwO*D?BB(TScZP;DR zwUfiG*hXey*a@C8t0JShlx&0x5Xb2$M;edc9cfAflPyn)QO6Jm0n0P)83gT{plw8s zuD-% zg4=l#rU#o738rx}1eo)?^o)^0P$fGNZ^wK$ix zGP|QTM_eK^Ui*G9JIn{lx?^STtOM3%hP78&ml@V$$n=Q*hV_ZE`Wx2LJg~+YRx*0X z4s&Ks1A!ot9x;Ip*h@bnWM|XMRb+&0Yr^45Hqrye!oZM)17d7O`DE~D!^#{n z3Uzs~k$awUc!xR&tbU!|M^6+tn73a#;63pGS=w1QLdxqwdB+W9fmvC1gb4YDup>k$ z5JI{UFBHVe^o~SbX=QWMQvM;gVr9d+;{q$THA}1G^qE#{n?E7YaT1`5EF=#Jn*ygI zquIzKqo*dr`45rO*nn|92$>G}2pR}f6z5|DA?ITQ;`~5Ji8ry6jjvaP2*EI4W2dOE zdxxPW7MNncjWOUO>>#k+ct5BM-f&XAH^c%Qv7b2_8C{0|U4|gnoYf6&`zZKQ)mAr@ zs@B3M4Ca2?7<8J>8fi9G>OqVz5uey5HMP62iedf*3Wv(HKr7*jT6bg-=5)Lk}^ zq;@<^?YLaxOcS-^sx}$UM^vlY{E%98m|At1TD7WuJOpYdRBdNS?L?T`i7>Sj zMlJIw#`RjWP0|{pW_J1;&exK??@p}7waSG$rU2j^w!)6Q!d9z-pqFD&t$9S|IJ!`wu$IS_>zkH8J1H_TMk_H8!(QvPRMbmfq|>gsW^!ZSQ4G*%!jUl(;g$eq0p_= zZ>Z2F!Njr~v84H66cobnl8e*K15t3it}LVN@95<`paeRxKdM!iQA74;P-2<9)c@tf z#+bUs>hNxGV9HDqn6k9ghQcJdYg2Z1GwWvc1CsGJ=6}xkx>pcpUO5x$N@k^J3>pip zOw<_>YO2}ToC;A{q71cC7lY~qJ@!}VSnU&Fr1fen6t)4=aRxoiu&lem>^9qSrh3={ ztgOcspXQk-_+G`Qi@25bj^Z;si^)%?ZmEayAgQC05y>2nY@6AmF(WY1&hea!c8-ZQ z8BD5Hc#s-I+fng(9u~Eg)m`!V9#$bMYmnj#Jj01gv{!mK5+Pa(HPG4Rv3Wvl-wR0- z?XIwBcS*F2@lg-OFkm!*(&L^~7|6J0U}Lf>fA5p#ESXi#tu?lfa}aRT8^N%vKKz5)+Y|(O4rdv+cGiNK7g> zaU(Cc?WV+vp(g`f)wf;UybTq;2tfsteC$!n+yzy=;HoYVnS# z$*JzfT;{|Jkbri^fwW7}T5=ncK(GToLIIF=JLO`CvfD|ckCeT#)D!5;ouXKy>4Ufo z;zhD2){VV@FP6Q4mD&L%w|?Jo~ZqatM`d?Q)#02iA+zd)J16R&I+?RYxDY18q)|0Rq^Fw z>`NHf#IQ=}R_YZTbWS-Yfmu-Nj2ROM5`SvnLEye0VYusQ^b%(A`!Xq)Uhw@0Ny1oU zpYuTk6Pu2F$;3X8Fw!%kum*IFN1%>d8D18Vf>>Ke&&rm6kF!?lxye877|1q9@_km#8((K9OgIeYRyRP@@A=pSLCf2inF?2*sJnIb&~ zQPUdE$WEr@=^5Fl?8fQhU$TRl5m5&^f5)+sW^_S|cm5IBO1&3@g7Z&PxqoC^J>B&G z6Bh43O{Jqs{jd#fsEZv#qJM{p{;i_NSulU8=*W=hUtywusp!{ZA-YQ|_Ew6rRqT?A z-FX6b#&$WRvTZ-=i2p4x@o^rL3YKvl^TNOwOr~Q9%6t#=*tm^S!L5j1XrD5>+$gil zYRu;1HnNg=d8`n(nYGIMH2%fi#7;gPGu^m52w|*`yHmK)Bf%9Ag?~{d;yc{XjPf_b zx=gbUn`u^%seZE|Ykpeu9Kc5!O5L7E`dc#PN-Iqd!QEtA_Nd5YOs34yhBTQWySMMi zeZY*q%|JiakS>`K_H;w7!hc9a977pN=IuqOzzt2M*bghFhiZ7PhZ1{MChw%ynPlWn zGkfq=ND$C?EblAG**a55?TE?C7HPt@nOjj9&Sh}+TA7PbhvNLkz*5jn{`w_j{^_(yxA+#B7l^@L3Xe2}H%XzA{ZC{WLqpb|a9GAZOsoK;wz423W$tq(Pr#jC_&RCiK(J9oLVW#U@Fkt4H zayP?D{gG`gLf3FN(EJwq8Bt3r#xleK_{S#jPPSYlWqTrPAp|qz+^b$KaWOrkX$y!p zHlvZ1dgV}HIrU8;d_c3(SLf7c@=aD4I3u$@B>M^7SnOY4GT=K*M4a6Ebi+y=#wo+( z2xHFQ8zy9Yog85@0gZ5Sgfv1n%_-6^XZ3}cae77s`-hB&*iS1wHVl@fZE3_;9>kPx zG!}+w7#Pp&#&<$pZe-)6^8OL9w5GOk=MBWuxq>*;)_I-_VU(B%a;20GU@+Dz3@10# zX38>xDX_FruG3}6m~UVtT)OCY&^^30E|TWOWXv`c7pOPfFQK@H{qiEG9no-6m%TBMVF~aW}Kp zOkM=+FtZF&ta;w~C<}YLG|``7Pr=(!VeEVP*o^lWRtg5}$eD+IA8mO%w*>Wms&$-z zG1Pv5#yVmhYalE0d88}Cyw1Q5!Vzv?40?i|W{&OxR-wtbYm`+etV`{)Xe#xG+2)DC z=fF(sktP)OIcejNLEsAgIn3AqOY^~gAr05U{*V2KNqmRCZsPx77ujhGyU#!9d)8@~ zMaN{HrTeI|ytHFSNCVH{l^qve9|rG$j?z)N(gq;sH#IRy@FS+qDBn%8BbX+ovZ)D6 zC2brh@td27kEtJ^!*tSVR>9B;C;VypdN6h+-TZTl4{ zcPInM3gczU>YBGNcG-%gI=iE6n{Stp3b{LqV1}H5za$kYLypH^HWe^3n&;`M1#Hi& zl1|-NVZ$&q(ZT*s0Cnu+z7RiD7rhnZA<0#u)==Tt5nu{hKV7YV~gh#<5;zFYXky zI!rDHPDqycQQ6yA+TI^94UX#9HibHo(cIxoU5+)4(@Uo)m!axQU(qXU?%gYV?%i9a zCg~Z?QGJ{~IuW;0c@fy@pjKA6Ryu@P=@4!uHQY+)kd^MWVWm*5yx>|X46{-gZe@fj zrasJK8K8Q3ZWy=S92c9w0rS8VRnrEMN9T(-Mzldaf&HfJN4 zVaD#4)|Zh4As2q0mJA)Mh}Z*C?Yd1bpX0(ZEsOoo&dNYE-OzK!zF~SDQ-fna5)HhF z!u}sRl7uq*Zba*u1L00nFr!H*V|UfT?=J=TI+E7u`L?9;Ng%7sjhu{Z@Ywb#$eVqE z4Q56DJZD22WDmjYh-@&c^C#&AR_B{^Yhu6Rn{{jAUBz$Gt%)xczd3Ac;uhVS=(3EZ zzZcQ>8R$m8H!S+Svg$X{?={hPfgq#bAGSGgKsN`v_|ZW*ufyEcA#<;XnR{LKBFr#) z_}mu7o9-4xd(5<)528%N{}U#pYxzKi)U+t{#$d8cGh~JEk?GB3gbwNhc&dFp5aTNiyB&JT0(*OjhA;IPY&FS7CG+ z-bTo%kM~8w!iq+wbKe9DX)-NZ(TLSGErY9ym5u0F+NGF%JF6PeTw0GtfUo6R-0E5n zEysDGkSS4-?pn59eScfVXFNh{}S=Ke$(eEHsW z=K+DO)QuSbozwMAd}E+xwmDDNXIj!TzNcQa?0F({CZkz9g*wApM`4-G7KY8R44g5# z4NmflVgYVXSVid zTzl3sYfsryiImPQos}kDz;1!rsOSj}la$pHrZQwYR?o@@HH_Aq z+!Ww)o<{X#-y6F(t07$Nh*?MMO^nOR@&flV-Ld=VQo5JvG;jzzNDj*RB!-=cejZaP z=0h=UeYQ||Qk*8o#Qi*sH$#qlb3JIIP>V*<#(klE`EjbTdVsVmvjA&#_+#kX~EDO-n#-7z!W(`HfkODbtMhq@&!IfCh!~ZS2 za+tNp{v))mU77t+PF4}73bJDr8|%<}*|AbMJ!1~zh;^Q05_X!Kfy=^0q{T7>DfaP@kG^je4M8CdmN zhv~IeJ+q4!`~Rh5W!}{rS=3cB*nR^Mn#F>OP@tld!X zatapPN2;IJ%p5^b+&$0_M4C6r*`9n9x9s~x%D$g;agohf!_CQTbhDi-rqpDPK)q_4 z8a$X<++*t%HW2hO%T%mP4a6ZKTZV)TS^4*tg{hT#0On#l>$d3{T9WG4*^vo~R5vr} z>x?g>Q&OrPDqOnhLQdfDS-3fdc;d|5|(xiS}tJLG;^f) za@c9v%OaCef;JYhS7b7_!+;BCH2}O%$MCK>UnFl3b-aY*RMqlL(L zr%3lEZlPnc*H9#T4QaBgQ6zg1-R2|lK> zySP^B?)IR!i#G;Z4TFKtP|%>Tw@;Ie-Sz^Du@3R9!D(+$sbf6F#aL=Q<981Vt?pcx+>x=sS~yzRCAl)Ex8LY zu^cSU+hu1k;^;sm)5`oD#al<0{p+F8>E5v<@D@l1o=Vpl#zSfEeL0|xkXD>I8@#xd zG7i`uQ>7ycEw1IU6o88`CdIW9mC0U!ttrq^_JS|sz+w7>IIrmsYSWz`A<^qL__8y? zy6k&YDmy_&2loY^D;CgEWahkRI|UoC(`WYIB^Pq9t zeVy)gD!Y)yJYl4|{h+x05oq~Uu-+W>!OR-xVHt(GV_BMe1dPEln=`~&AR;Trs=);s z8oeE&cP~V8rq>h@8%E%e*su!bMO#aS{+6Je70G_v1^&imiLnNvYn=i9vbu%;ya``y=veICCu_MoodBShPYethPyu6E(Pg*LM0DsI9PTuD`Xe*e%Kx?JDKyu3tn|X^;j2+ zsI!|nCS_7iY3TV?vX22pCG;Pr@c6rqGY zVgwFI6&`LCT$lpw&B-=*sq$58beQ%g)!r;yenxw9GNrK#TF{%?wn7wBeZNy~_TyE#1-DXvTe3V{ zv{dyrgy|1c{cWQEw(4&S=|4pM2a@d*@U2Sqo(R*w1^OdUS06~Gggs&;mf8g*cJG zMx7BGBGgiZRqzKby_;OFZtBVE!pqzx<_Pqz6WhQ*E& zzeXCe5BWwd96!%OwLG{{CKe*{Vd3j!n|DQ0RI^Q(g^puQ&U}5Ig>U8Yj-z5Bffi0C z+k9{%T{Q=WS(ph6mm_aaiiHMf_9h*_$fF*7?$Ih}N*iaAZ9d?Uue#TT*?2^~ICGvC zXXSyA=fpxgT5y`$pTfdA)!Y?k;gni%Nd48C$RRY#us6liy(bDYIfbGl(+}6jpnW+@b19v z5rsJKt|u^G1Yi{$!tm}SHI+JkQtkW^X73T$GoBY8SM`KL>A!qFrkd{~Yr%5i>`Dv!WGXGD3X<#bl8ooOuT zie`^NYBD4>wXK35XuF$n$hG-JnC&ZR8}}}{HQfnUIkSqvbl5XNQgBiQ8?pn$k12Qt z3Rg_V9mxrV>=9$90G_@ZaF2M1;F*h#{LeeUMO_m7?}{4soe7#HgAZSX8BR0IXCGZ!}SHiWBiC3&0T6zOXC?OYWx{7J_N>$@n^*NF5srWcuwAp z^B3^(zp5RH%o?~L9Z`&FCR4zCHC?J<3q)_f$~e#ojA_OPw5EZSGhF#oG#tfkF~{GG zD^91fWWv6#mgUM=C>*Dx*~Cvkvy0!w|EFQX@2Xy8Qfy~&#yk%-tiaB&@GIh4xlHZf zelY7l|1#dJ#v;dae}He7nEXu!W}_-IRl~^XPeHKwcd(i?4+C;)3i>RV=?M{E z41f{Xn%+KwTpL`>0-bNMJq2WNtn6=V<^4xFd7Vv1CYoqEKez-<&MEIa^+raGVj&4fUOza){oBlLu1cR@L+n3SS6X!J!x|a z#7ciu0S;Cba3R=T35QT&0#g)uA4n#&DOHZDw_NF`K`$`$7*AlZBWbXLcPP6a-l-jU zN|6*G3qv+I93sBp-^$J5>$e9U?t+>!$J_u&&Yhx0XYsIdUtYEmCO~ zh6aylgT8?K6ctUlMRo${;N=(soq0`o9Vd8^St8FDWj+=k*sSJ)gH|@NSs)6)yWdm+g0b55l-~Fwqxk9$8a-C@JTqM)pZH(QKv3y#{D4 z_KiWL3(0s%&I=o&zquSc&ju?YHV4Z!gFXm!&>W`mWjS;_O}6ZLzbwil(H;i9inW3B zitwKRUWoR#U$}`FpYpRk*bJDAtdeuC4~0<-Ms67xrkNY!1`r`%1@gF%{6`}HD&>!a zz!?Jl&X;5OwZu0_@8zp^d5gBCU~38ZL+IJL^;-c`s1 z`_5_DUVQd)3b76EPDMw6y~miA#L7COfxnJ1)S%mmcDU3yMxgX=%7Ahzy%&96l29l}gOWqf%GFPk6d7RlAthigrJv;s?2BO4kMRYSAZ%`o=! z95D{4=tPJvRMEw#{qHJ$G3frE6uAkAaSijV!I*!1Yj7;bk0s z6ExQF#;oBy1r8*rG)v2dFsyP4bbfJ-Z>dr?Ben+i>Vq2Eu$e6J)0MSJ!(OmzzYa^L zi)|>!ijRVrcfCri)9^(IjXK3nzOfuKI&+g|@*$v_a!zuyvS&aCKc^;d7T=+r@PCnK zzfF0*D+@U|L*v^ezV9yv=dE~IQdcP_@di_1|Iqiinc_Qz*r@)=;^Y}uAC3vy0c(xI zQj9I{#`8N8w-A*}690>5Kk+H>{3^8PF*DqOAxfV3O6`UQedsz9kK6Y0k3bT;K^T!S zS^rW_r}80K!iSf#t~bIdwczki@jt_0@n4`n1cBm{0BYkeua8Rg*YHV*l{dZws(JI3 zbghQR!1Bd`H4KWD-%WIA=zTgg^hz;QtJ>!pI^V??vl!;#FQ+Ec$8xysKRGOl-T31# z@V4got0;@{NH|9T%yQ-|(446dnwdjwQ5t2}oRbagR5~l!_AvQBmHsv4Upz;jGhGw# z_BmQ$r_wm7`PtZx@jT;pD*nS^Y-tMBp}d)Pc{Z~CpiEs;wB8)h@N*>7K8yO(hcmF+ za{FT?1`RpiGU#rgGBK@vi1me!4UL^*)qZUtki|f9OHkZn%dOgPaGW_v_DrkxVX28g z@~gmp95G0@Ui)p*bFo$_-JveHRV&a>33es=KPYH-5ge*??h5z=iZp=`1x!cC4o^BI zY!(c^9JOz}x&L}ZrN7mXn+3S_r}NG6awT>VoEaonkPQAL@Nuq!-P6Qlb4`m*Q$Ii} zoo4mFt&j!$4gC8G#M#&E9-P#;;%+p|pJ2~^0g-a|ps&0npnFf$=4j=Q)|6CEM-*K3 zXV%JwMsq1I`z#dA#qZ{F_nC+Pb_*UMciNuff?n?a+AT@7<}#`TwcS%grhCvVw8Fz+ zu0-s`?*rIP;Bx?-d!e2E1Yjb7@vf3h&#ctDl99I7^^7||!U%5zx2`A0)pE4orXHzj zzan<0O+AbNRyVn4*F_dp-Ea(Gpp3i@kmy=(8zjv0F{A5cJqJ~DblqFTt*kdflpLje z5~Ac9iXLW7fFb5rsToHJQR|E$11%sEz_ zz0~tmRxKI82X5-@^xRD9Qd-h2Dgv;NOaT4a9$erk8OrUbTP3 zwQnArz6*xs=F4T6lGH_OxUH$_mR0*+4NoH}cGtOXM|GP#i#M%5a5;!I_}#!qU5wt@ zxl^|5oyz=?vPj(0^jHe0l_mbZYR_ITUU4^0`mxW{EvBooq@O*S`D6{;Q3SQK=5psQ zRb8`|8Gu%R*zCtp_GYbqRxW(z=ejN#{5s$xxmN#Mp6FuPjT$@{M*m6L2^*fuT}uja zT41na5H7?s1P1Fm0Mn1RFM#a7a=~W|@%zx*DZUnX;6zw@E`Tq{=}?+}4y6ebTDNaT z0zDPGmN11C*;c^O#BhkoF!~V{RZAkRK*KQ3AeVC=IlYy`Ml{WEF#Sa~s^-`*{tdzh z2bydui_lc&gz^1L6lrM+#29jxAa7Ftib7iJ)HU~ozJ?*W7gVP%J6iKhXk1;k54jf< zUzhv#RuKzio!b0d!+pppdoT*LcptcP2jXPo2!M3oNBI8^(BO8J%!U{Krxh6!?$WuT z&a#FMYzEKv*SGmt*-4ddT#4xMYlfC-M=U@!xFb=dIKIzBu?_kXtrc3t`Q4O3OPdQW z<3=8EdBpF4To=2Fc)?Kc57cK8KOo)&)kE=1P=!Xzl`_M}5mupG=zUehSAadZXEekQ ziMhkT3%URJT7A0QdkB}d=t}W~qHcYBAZ}d`2G+9R;N05X6cNrIa7w>k#{`;g1RbCi zXs!hAFXNIEYhR2f`=3@KWd+76dmb`!wPDNlMPPz5R)cYmVMzB}p>%e!uY~BVH;69q zaG2JIA+8ntQ|Vkj`WtF7g!Z)m33WKB12OhF`}FCabQF&So1_vdrjHCindY3Lk|?n!q!=YInh za%u|5oIj%Qzc`%pw*v>i@gvlpy&VNMe%5)|wc(iMe@M|#{twU*!?G6efvP>q|3pJR z!fx+^lfnH;*^M}?1$>aRS}Ff(_%LNZqU@L9vR4+SAe*-*+tzw<*Q%%C8Oq0A1^F1I zi0#xHVcY4h&tT<%Z?5cjH_y1q%-6u?l6+6|jN1ZQN>M`tH0(DFQ9J@hadZ5u1XkPu zz##y>t^oL4N(s}_QWci6O7v>74ZPq*;a-h*P1+nwt$}x-n{Ybo`I`#;t3pTaA$;_#)(P@Np#^W+?@iDfShy)LE!9&T!4wn_({P5V~qm*u`;@JX~^E z`sa?%6sl*;MFJ%|OI&~ThI1bKuXy0i0!V>#U%4OcDyyK%UH$t&cq_{gH-T)8t^aAuCsVCRaz@k&-^V7H7}o?zfL%NnKt5U30=Tk*` z_5r~USu1}JNSP$f1!)sVrI%`?%;5@%>&*iYpFLbm4w&teFn@MX!qI{0D!c&Y zbPWV)MNh5rIe)7hZTVNL49_>wB4RvULcQB)nfH&u4!spPs<}W@Z>lL?02$83lGw_& z0-vhT%@F!Ug=B>(hIrBuOwi~ahlrKqVr`V_TMo~UBjGs>l@j7qf^)$*WQj}BN{37- z=*&HxRp#PNl`1}}A^YF0C=$8Vvq~=BTnaPeT)ur2p1@X&XJ{zl!$Vhka(lvZiaAf; zqZZ!|vwRAc2gy6pQskXz*U_{qaL#m*nnrg!vJReSm?6vQYS++aBm%#ep==i{M=v7} z?#$qGJMrT&p#PwPoJ)^$RQjCt=^^U_FY5$<=f_Ag6IAf;n~eEfn6jf*GApntK3}d> zb(;wP=hqV@vc4wXVX)wwzT6VP^n-6JaITEuzTM@hC4>3K0>wW8E~nmC#c(MRr!0ERRM-_HI`;usMwVu*+T^ze-dK9 zuWY*hoy)%2ooD-h57QRSUtCRW43?%~{W^Ix@@l#xRl~a3l-a);jzGTI%T{SMo-TJ$ zj!Z#W$-LO$qo<-QWW8DHbccE+@WI*rV05N)yb<03Ouihcl!<6ng@VdkUfh@~&8m!T$^zXxKcs4xBVm7@P4^sW4p;50*o zhO9U#Srd>$$V9;`1o$M~$7$UHm_ zy4=I|F@soXhKs%?Xr|YSTOsVkGO%Y_aVzEZ1e<}4edHfC)A7SR<}w7Bi!$|xvU!C}gk^B7l!bqTF6 zqVi_!nOTAM>JDqf&9Gvsm=)*|M(3%RsV#xwVdVWGa_}Z4OH99MwC;%vCc-?4;}FT+ z>_RCHd7?AsdfjDptSPrOKr>y9Z`^9tds)M^NQzzW25tANrCpiavAIn+H-VE|0)`Pc#5X98rVjGsA^F=y-ZK~SdqVPtcnOHev&QNg zXREJ6k9h`<0_~K}N#W<`=)t~9?}DrkE>nb;0*7x<8qP%g zHV@X!fO~@sxX*z&XsIn)Y>rW=Rl!eHV;G{euH07$Zc>76-A?~8!__bwqV~a%y(F=B zBlYX61oeZ-icAMG&ec8t*4@+>3;4*UovxzmHT;e-?7Gn%(8qE>A2bhFGWph%o+^~9 zVXUtMB#SQw>jlUJUAiP9|0D_{2YgvQ#QK@kYDii6DY4iW3o%N_Xfz*;ys>I`x`tPW zgvL=Qk3xYv7R(K*#dwNzYt%tWN@+{!=S(D`*C%8Xp0{Z~Eq1ATHPm z5R=Wt)A^YO7u~aXz<_}+`aLZ)9}DzK_QjscBa5d$OW-PlRxh5;k2-i3(l<}#$;Hz@ zrAmUXv=i`HOq_#%D0 zov%T_A+$%nJhy8h&yN&&2gqc;t!A`pU9F+#o*?v#tH7#_j`yly)_=&1EnWaJ`8hT9 zean^OTdM$E^LJ6}H=EMrwk}2l)SSI*QKdSyfwPZ%uo0U@FgajYeV~u>S%=j?>HlNQ zzlg=ge?dk8$zKWsH^KmpwmdJgcq&0%$W#s70t~-hknrs802xWqG4K~LMK0fBL73E# zmzxhR%0Hy^Ll#VL1i8Tb5V$C z1s_v7r-rcc<((3f#XP!O#gKk~go^zLI_)mO|KZ$$k#iGlHp7YKmB_bCSkaGHBO4bk z0h+;j`N@|+`M?0Pv6|WVFA-D&K~^j!GRg9sAnQ3``PDGTz2^bV>q7q*Ch@YXAvM+V zoT3nyhET~+^c$cZ%Pr5ZJK_C8=IujOfbdI+hyL%2*5UdCYfCQia@LM=)(jPXuZkd| zrSRzoLc+wug>#pJfV-QXD0wuY#WKwE8CmvLqrZ##arS8#kh-}a0=XngX%dstBw$$+ zSVdN;W;Hcy+or~2H6``KWu`C>w6=qnTLRqFaA2l}1CU>!q{;v+zlq2|mKEx`f3ed4 zqx{$m@@j80dhcoY;Cc*`i*gWg3;X+x_%H@yzy!~eBG0MZOAN(lu;ak;Myuj08qR`& z!hq%JAX#N&=_6S+QQ1{YQzyF>q$H~rKp>YyNfqnbyknQ9lgnvYSFMA0NB zngo#UXH|=bh|CMrWtHfB4(L-S7k{}5sCJ7~gU*NB>MEPJM%R*+E$G&rpO* zZB&jJ&mLFKlGl-N1d(e4(OA-&kL#F^>6owUM5OYOIeti|{rBi9>-4bggPU+cNN!y8 z;Ejt;{9H+$9^K(mRu{1FMvXd`4FuM4MgVV=&89eB_=^AXexN#o*gKlHE*KcxSs`v- z7*}9$*M_)*!?*&2`*4UmB#bLC3)ZQ0hG1A*!su}jz zJrKfg7;1<8<4u?k%1a}9bJ~--3cYVO>UP)7==2#yTwg}91@zo9&}GJFXvaW+#?}rq4fq0RrX1B;&lxl2x<1G<~&H{?5-hW;uQX^VrAhUC|lQph0==~ z@CwpV%niI3AW>Wkz;^)h-d0m7n&t?Im8XC^yFLD~ZU!%Kvx7}4KONRCf{>4Uog=P8 zI!ZwC^#^tXFi5NeK7bP3{CtTLdnhpx*l8ni68Ka~RDhO>#Yb*RePGLgO#lWP`M__a z#759=p~O;3aJTSHk;s{@Uaip3w*$OdSRUleugQ59oOa;g7g(q1X zR4Ht6v$Y5E?I%Y%3TwNlTZc3p1atOGEF{fd!%q(D#-*5%%c&Z)SXL{Ea{?WAQt&#f zv4Mck*~IXu`J?X70=i0;SZpk&Fs_xVfdk49 zP5I`HQ7@-zc>S$f6Yj80P1vK7epe!tH7@78tjVuN={^o4rgXQ7cPHR&>28f7RJtij zVCg!@pZ_S`rlI1&d4lV6&C-=&D%eG>JppTh0!6rY(#e=MkD6iz;=eOS(>^h~ct=$3=mVx8FQ`O8et|L1w5(5L7jG=aZPT(ok&1kVxD=$p`=PrtS%1Pq z-55`aX6WE?m~h2?Dq1`q8}-VCA)HAXIcFSRMsD~h-oiO^@&0#%HbA#w+MdB<&=X_d zRk_~+8(i8gWbA2lCW8ypfq&+ibrCuPw7tB^_nAa3*KpJA5aRn~<61_vO~IoFsNKQo z$~??GU8o43)m#c`mZRK8wlgfhYvyCqZrE{I`3Vhh22Z=v&@YjP!wX=ywETV(IZdEM zFl<5cn~-EPkz7T|jWs0m(v{HL4KYJ9yN4N~#ofi6nnK2ba{{HVHXYz}*2;4!qt)&_ z+7-Vu#qKG3QxN8jq;M(x-Wrm`C#T}DX@bgMx=rg0BM`|wkbEs986%RHP;z&eB=aIK zpoE(>^k6w@Jc$#nnbcZ!PAj64*Y>PHgq9DR)8)`X)HOTHt>K-eTMx}l5l3(6Ewk}} znwsJL*zv{;S3iNVO6OxJtCX&nKGU?7T7k+iCz=LUjISqe175+k=$JC%2BMIXQZW@#KX1Hq7DA zl?*O!qK`VPdadA-aY09&-(W;W9ml$|58L#+9^3UL?m<>%%eoge#GYP-j_A$dBEf2z zjBe2M0`EyLFdTT`q(;L+Erx=rGv?W%P^pf$)vir%tjseVG5u;T1B<;CO6EPu%^8V# zpR%kC)4iN4cv`+Kg*@%v2q2fpXpo@hc58S&Jh8vSD&B1PT|z_GqcboYeuBONbRN$# zJ>9wWiD7+!ypg%bHYB$$n$ik@H#x|z;KPzwGqP`oviy1iCnC}fd)%e?@Yw5HJFuoHVOU? zF;(fByWF%4VOlz+Hv@0zhbaL00gm|mADaN=sye=aU`Ku&Bz_pTvb^u3Qp69Zth@_0 zesRy$13|em>v9F+G;_qNFb!2hG-^oTWfE(2DTbO^$YAY#_~ zODl1Pmfn8YfbVK}0G8xEu<`p@?AF58aON{*S`CrxL)F{i=Ma#8hiAoo0Q6zrcLh)h zAeU0UD}em~%r^jANI$c$lkHC?6hnK6f7!H{3fy~F_Q79R)jE`g%}dST*Td=S7m0J#+R{R(Us zFyFrbE`(}DZRBS)n+JXs^?>YAB)w1?EuuiAAlD?Hh{b>D(ot4q3xdF z-VSc*=!RQ#zR2|W+!0W2X7dSj;VvX_43b8*| zHn-Q0s{d#_ff(&tnCw3dz1FAhOTugzVb1Xy~|SNcZ$iB;ID8TOe8PN% zW}R{xK5qQv?L0r?8o^lsgt~)lk63Dt8VgP5spQu@7$&i?jgtlEY2h|NWf;saXehoC zcy0-5`e6Co)pH{BmeiQcJ3y}6%FI*lLo6M6ueok(HX`{lYuz>j34(SJpWDaRhUQpx z+tP=0@1ymgoBjk~ya`}P7a*hU6!rSTCxvW9!IC`z6?uSs5$B4pP`NWuF9z^}f8DVh z<5vU4*`GmP0g}(xd<~_}5)?_@s~KA>WZpt%L$-;}I!VWub%0bZ!P#ZtadTnzRRFNw z^Q}ZU16sbd0A2+!nO`KiQ`H~Qux{$TXoSTOTiaWQ}{j{+zJunBp1sHH)Y4&a6N7WL4%#$Vu`idT!;qB+w2P-gBeF#7z3JHPr7|)83 z6jY9|jQI;5P+4BF@V}{u`zi){07o_JuQiVH6sORMZpBTdn18Vd=6K_8qN*>d&=6dW z;8&y5)!REXJdLE=Gf_v1uK@Qm)XCxifYFGfxC}rwfV_b!T&Uq;B*M28+#q5ZGDN9n zmB}V;<@uC0Swjw%zDj7^0FBZKN@YJF;^j(Ms9`5KU}q;YK@o5T1Amrm{2J5Hx0KTwDVAri!T6o%~Jqc0q{HxAQiw3 z0P>zx;XN9DKv#Q$+u#}G#q&zl+Ec;2cvWdfHRLzieM6wp6&j^)DwTOb@!UO39HScp zwm5JP0lM@vfLtpHi5m;7@3*S@enMO-lT8Dw7Mq-%`~>Pjp>;kyceJubuMJH9QOx<=Gb_(ma=Rv9f+(niIfU3Zqt@ zOU_nyEd27NfPFXFIWF1teReun&RnpH_~GDu)p}CHgHWtyltZaKFSfQzCoFH;*)(V`gdje~ zS+B!3VI3(1tEpk#q^#z`D)L@}d8M0msDAu)M_TQ@kE5{rf$J;4zh8FaL3@7JxLReu z)-ZCo{R1opzfk-=^hbC&Ajz_}!GMnjhU`%z4*)1(IW~Nn(O{AfvB;_RDo7Te1f2r8 zB>K(*I|a-a3FAFpLVsKjfIZUJ6u}DM6>R~OJwq!PP?+Pc(P|ofYS3damEIT@E(h;T zX!wQ$NO~F4-(D;DnDRg@HWT>@21!}DERe~?8#uR7- zK5!A_(O~FF9#}uN5)bgkAywv-a=u}^GwSW3aaZ;?gL73>?nPTcx0cLDEWy?q%e8be z_?A{-V*b;LgdZ0a@k`jd)Ltq&R{l;QF?N9CRNST5z}pKT2|(mN02czN1dx}Y!miRl zSH9_fl^;QX@@oM2FH-r?0npQ-;`c`=FSJyt4)Ic()|GO z29|GmEtHQsWyk|^i(>hJTsps`xk{wb6*E!k8rioR9)NfDml&6d=YiYy0Dxrxz60P} z1EBRm0Ji`r0#MTBQrt99&6ADc+Tz&R)XfE*y169!3V|(!c+L?O{Zd1b>-y?{aLTFU zcjZF4l+c!yO@I0MO)Tp@MCaQMf0n__On%yNf*N0{p>soQ@mrwZ!+2^keIJ2y5FFpv z0KNkdboD-6D)9slsGXZxhl=>=@smpF&9M%@_(RCE^{7w9Yr(w&Sn;g@HUP+9+5}fb z!1CP-%Ilz5IjvQ#hlZl%yrx>+0nFr=&})i0-JP;B&})01(H5}9f2o=XWsu9FTSfd1 zdcI0rt>GM)w>zR)6dwS04`Y2Bz!?BJ6IEuRh9Z*rx{6E#Adb}(bH1?Ev1>+~;@RTA zQcZ*$b6MgTKeWD1C4ScMZkV^9qhmjVdy=vK4WRuS$h(;CctjjP&O0jny@n#Y0vwTj z@xMgMsqFt&6+-@m-c1RIQX4fu)otUk`L+|g1=_!Sq`i%ti>7(o2oqMUu9MmW9_>l* z#&>;X3*UU6v$uQ_uv;mf&FkagJHPbtyWt`O)gmU%!aRn*eVBCccNz}cuRRO*-vIaQ zn*iP;a0J8O=K#u7E`L`Obf}Q?{QzqG+W`ImFp59~+`S7x-ZnLUM8ln6_}GuW4{qrJ zrLs3(h^XiDvw5y)OO40r>#^xgJMjLZ&1TAQ1x~@7a9bROjo=A2$~`4(PPt+YVM06o zfa?@f?^U{4msMai>aXTmDuu$uQtD-`-Io8kFgC`h7|;7I%L;VR$oL+wmFFV7+U}za zdk5OQ$ce}pxDhMKc^dDg$Ortzv!-%_-md87OcGcUCIAjLMTb@AQcc76xIE&!7O z_?`#w5rF*aCg}Gd<2wLKn`6lL4yx{sf`Q{|_W<0>hA0@~Uf@S%@Th0BVaV_ss}@4T z!70rJcS&1xZ%<5uRq9gA=z64)p{LHDc`5PE=KS4Hsuc8SsN&*j}fM_ch!NOZGJ{!0spD*7*Ryw*Y1U$a`L8 z-qCQ5EB2-<7X6|2q%}pIQ*KY%y3p-O-&Qjre_a;xX#CyEwB=<93p)3~{9Q@2_CNr? z-iXYehukjC2KNbI`3cFEbqrql@uLe*J;Ib0{z5|fFBwgG>72+~6_G0f zGD()#unt#|cChl8h!n(EAi@0W)Xugr<^`%$hFSTVnwbX=?hB)Tru43Y6tJ>F0Fi(4|CX{I0`vctz;&v^H12|i+u!=PC?nLc(n1} z9iaR^ufPlZPBP9NNN4e_;8uMFU^{^K0r(yTQ2%R8LT$c*=7ehgprJFQNnSg(;##{B zhRSFt0%OybGFk#Od`nJE!E)O6_fqwcvzLdQwE{0{JX4Wv8(`NYakv#ct_;4ECfHC- z$Ri>}{4jXFQWk1hiWJx$=oB9T_gP@&9{>mzD_>rJG*^*O$9?47xOoQBOO^k+hNo!s zFpbvfkJj`JfJOj529RHkCNmu@--V!D_AR@nrr5e9C0!|&f0G)zMk<9I#^v0nv^^S% z?YS@@ws!!KnQBcjr=L^IDfCwm@V}_Kp)4&qm!(z_zhizxC0g$_HK4(FNXjiB78ihf z8?fRc0Dl9>&xYgO!17H2#s57hWuRP0N`+D^|JQ2JO$vsW97~NSX(+Zg!GPF43_y}n zQ_RUQNs0Oa(KS-tP*Ns_CxstVPgjXW8hW8-PXJPU6S(&RE8Yem=0`YQ1;=f$d^DKs>O18IxZsn9HTA`tsUITqGeE@)@q^6iN#-zmh2`O=PLn)aS zo{|^f&{DPjhK8M>W~c5$EN_Ba1+4f30M1FI56<(~=4Yhj z3{w)7ixmcT90dALHFmL%OG`YUMj(|87r_gEfRQ&ux5j+w|iEan0W^>ay;3oN4`|6dna4yt-K)iayH1-Zbo zAL4R>Wl1VA+SF;_sM-d9dN*1(q)$TqeO|TANXE;6 zatFgo?T$9&G|(@+J`N-1)jJL3t=RJR#zgZ~S9v>6LwOswybbJv_}}_+RnF&|oMfS+ z>hdGADVn{5UKJ0m=rhRXdaogATfx2JPXK%^+%p881~Bm~a|^&X048n%ke*+Kw68eC zBmvF*3ti7iP%>cAR||>U3QFm0c*~!g$PyOiHyU|LbGVfszaJXKYe4@WG>WeQkn%SG zJP~D00gy{E->twN1(sI}0DtisRx-ZrK+b||1D}1e79sM7REX^{)fH;j zPP@Q>Pb25!Y?m8$=wY_N_sXR16jyh&tLyKj4uyK7n?mhuLLcNmw;K6dhom^^@r$Q{ zR$PLA!;zfg;Q)34$R*o14_Ly#@OPssokf#;SK`E#7tFMoo&51tooAJU=q7r2p9Y%6w77F^JB77xk-m8Q9w(`3xw9a$4lb5l%`5nBTP?I<~sj%`YS_pmum5@hFTKAA|QRS-x@fs3Nv* z^UJ1$HJ7i2+@q|wHRMHyG;Yv63+C^Leb!+B)+~Pi%9_aUV%g(dS^Gb}P{n2Sz>0X3 z&Q$aE!D==9n}&UC8xt+W!1s4gm3Ir`aLmg2T=^$8G++Ok-i#lZ#+47hOK0w~y3T_? z*1+yXxGvJikv`Qz5%RZ3!vl=z@i+8t38Z)+_pHY@FQZZX6z~ZTFu0wqGS?_FR4V7_VqI|zIWAhs5O-vLY|;0(aJfj}&PR*|+1%C}SjF?wQp)Fv22%(&W8hqhgUI*&d#A zQa$T3J%bTxo-)f^p`}sCv|=Avw@@f>K<#tI+X*bwZAu^chTBgCz6=u@dA`u7!N_0y z(2?3*t-yO456xY5zT`V0b9GSz_@hwO`9iOSgnEPt?K@xSTle-#U`m+Kx91BTEi{hd zV^3j1b&s5v#C@UYUI`P*I$x+nlZeazVM1fh7fKIB*A}JVrf%{1LW7H4pMqgRcbzZv zT*#+~!-Ni=FZ5w33yy>d{cyfeVaV}QVM6uMP{K+%+UNSz2pQ-)-tBy$H$u@}5++o1 zzR+VK$BV**u0CJrVOPk1U6@dqKS@REk5zPS53G<>>Ix){zvoeF?Wm)u!?%L_JYFqR zydA(5^=zyB5dgEE$G>#nLHz#(v=WZ62h~P3TD?;{e!|<(<|x~)KD0T~<`LjXy9_`s z#bl&?6IkF4Rpv;W4NbbbFddseO0V%!?9eC+tJ&(a>-zzyi`%stsN1~&coY(%C1^vh&=8-M_zqf0j9kA_GJLMv6)_0#{B@T|^_;O`5^_;RUJ}{QPeE zL-W3K*OjbbyvE%V69CJfr&wr-+^#*y@*6n58&WpQWNnGcy{F-4h{|5{u4FBRn6o)e z+?+M|)4(V2Ho!zxN@)p$<*{q*_C*umZzs&!OW)I~3@Ikyu4ey-viFXUs`%c=@7*jRGzlm@VCX1> zB=k-o!V*|?DblmMl!Zkw#Du0oh@gUs7%T{i8aqWLc2tn4s0gUo6}i$HZ9SJXb3Qu{A8aKFkvG16pWtXB7cB-N_&jc>h@ zt5mB%DPlMZ=8?OZqGgh$L$#Fh^(Y1wnn+8 zs{S_moNTC3P_5_+m6dh&Kru9|W{fXD|8-!bD2Ru1?3qm(oOExLx$Snw&1?PY` zB8e5nN*i?{0=<&tm>qkx;p`=x)&d&3Orw~D=953ZdmaWpHwAw$AoIcY0P3`Xl^K&^ zFQ=79B;8BSq4=8(25T`-b8W4PGK|7N(re^e4%&z0n(9$X<)O5P%^1tN;BR)+!xLm5 zepneTw2l1z1#x@eC#KIFF0Qn-EgF`qCyNvtp062}?tZv*_s!d(p}~jqe&G&tU1_<&5|{&x)+rQ`^YfQ0(IoL|Xv}BooW(yT&sqG7XDnob3z^tLrnHdB z485<~Vnwq))(BdWUP|P5E?i94qLG^Gt(>F7M}hx3=|dYWEigYAGHG@`#CMJ@!KDFD z#Yfmk6=4STg=}{|9hD*YO?)zBq(!yN*U&)eecaoO<#a#h^ibQ?!Z zt19LQz3~&8+BL|=Ca8>+_bAydV9FK=a?YZG`=~_BTn8%MC*)P_u`!}`E~DWu&D#+f z8(UN6(d_XRsFgUBeykk-+8GDjI8gdm%1Ne-6Ov8nq7KgG+zTO8Fm2BDVe?jI>iiWJrNbr!4lYlq2NXUqz5+vxQm#_0o3aSU>AU` z0H(3a=TEi}MH;(e`T7gG69xkr#s@;TDLLjlVMBt3ITpHhdw_I}Wy<(FIvoCL^+t(# zzlK41{IoqFy$_Zy``FfCxm(v)p22-O~*o>N!wZ1ZBA(x5&jPW!54YM@;egM7-(1SMv zy&j>^&l+W{9yji2>M_QX8z2_;0BokvD8_S?JoS$N_^-I#m9VLSWI<}H36w@ zYKse4s0aK#j9!Sp-;pkR{~;Y6fr~!SCmW+7esG8|i}^c-`6jO6YtBQvpWF_MG!Vpx zlXi0%E8=rLE6mOM<1~^0SnO8zH($d@++_bQ7-XA%^PvE^alZ&acDb@w=u;@Kf>OjS z{UZ4-LZSDR9?N6p_I#Y>u0+;R50Vw@Iqp}2({q#{Nza2ko>vaoZ6)12;BdUBo-2%3 z$s65ayh=Wj9iyY!j?_~7v4y`=fjWE`O8Hv=4-xnsz#jmD9%#+Z0dNL@nE(o#0tmLn-!%w@nX@CRxV#-A zFR&X?+Z7#%0#jC?SFXE&aMVNC{exD;Bx(5S5Tp!G>!coYVH4EViZhymH9nvfm( zEFz2ig$ydzmMxAoIM!nJ!mU)sr%z8H`D4byp19#i#KJLqZvffxoYE`L10~d1Wlz^D z`^%MRtaT0yHIiowd4?vl7TgF8QH~P%lN}!4Xdss64`XSLe53~95IqV_+I~1)?I@_j z4@Fn$THF%Nt)Fs*SM(nhXFSo`8V`4pgl>+Hv@{lJ&Y@aJZMHK(X0mb7mlBt?2g$e7 ze$bW~TrBK;=bOTJ!rluIZl54pNDm-9enK~dhv+O=NzwSV7rMfwMdLf4i}289PM=&} zG@e~_EL^f|T%P6e$($KR&PC3o*)W|n%QBN@?8mbzoRntJhekJ>_8m%>ec?tVLi)mY z39v6O2*B;wmtUzOB@`LhtRY3%nH~az^yAG(0boZv8$e{8va=um_*)i$-gJP@H?mcU z?7;sNqMpbl9rzG6HI$62D#SRxYxm|{dPmZ*NACUqbI zCUp$}p^GIxLMU{`|FT4+eFam9uY)iLxx-0D{2b)qSWUtlq;V$cE=!yviA(iJ;<6$u z+E=qx_jU}3vNgZ~(HF5iT9FYh{GW>;@RmoMlF(xJXE8{=1k2A)zMrKvC;;d zfwCyA@4QRRgHZbM$%2tiwPmir>h zSD@f`!8lat&wn%(dZ%2l+Hbt6&`x*(!g98%XIFiv{mxp$tE`mv?`~^SFP<{Qs7BgG7A>H=jW5`pTA?SuC!Z=L;{0kt=k1O+)zk<2HzS#rh zTn_vvlfcRED?3bv8Az3HD<4NlzODQbz~Yw>p;1s`%Hr1A5B>xtZ-G{S3W^|}LB3}k z0g8OjmO!tYrkLn$;fq6uw_iM{yQv z3}0;ITxFrg|Cq+i7YhDvMbz^7W?HW8e7^Zo9EbUQGXRF{c%o#t5ERMoIsnlMm3Oj> zD^E1xtbP~`nuslvAC}xR5R{TT4j}Z8YKUdQ^{wFS<#_4v^sR1Zsr&|gb_~K5HvFuM zWPRnr!s~zwgkjE1;GLC}EV-NSZxF2MImOuPuHq#ui3_UBt%Y4fSP__|gvI*27%Jq} z!eyXZ5kuw$HCKVeh6SU?vDYYjC|EkF@kcs!v zVYu&Sy)5f3WiDspmL{El9By(7_)ozgmkhU?ij;n(Tu1bICfEvj$*|==c1R*YbKyL@ zfFzd<&x4>9N>y}h?Q(l-mJxpe3nPcrUtl&_mMu==vg}Qen$GpuG}Rm6@S-?L)?%Ln zQPyI;(@>{Kk)_nB2>HvE|3iIxpjd>Gr>jsm0NL?uqG0@KDO`(P2a2r4J_`W9kTGg3 zKd!Y{OibZTDXIx5VZs+Dd0==svg0#okYhbI&p>ilDc5>^UeDz6WRK&Z3R{B+{Pboe z$D(tc>|t_Rp*)+QLQnQEg^{Gze-$J-*`pVfT7H90R`Owzd9ue8lCur^EF}kdvPUsV z*1QJ+nlx|Jh&@Y^*zLl*^&_oR-4Np}!ZkDDFNJV6ISOXPM|K7)=(GLXBk( zQ5KY@$_4h;ls^WcmDZ$%j<8fP-!&6H{^oD6VU5A)!Vt=B0ARr^6kkgKqoeS5)`1cg zJiyW^Y}}P17X$wo7<@zq7bDbuHrTn6v{BiUJA!?BSg6PrBBbS z#5@Bnm@xcuzH5VAl{w>!u=3q-)FEbH1dHDEhZ$d#$@t>X95cRf z!Y$^S@x^0id@)i6Hjm3-<|2>-SuowC-_bx;r^&b1&w>7tUC)le_kqa@b5!!ECLy23 zeztxuL|()ZiHt_}fXzpWj6l9asB#3dQw2*YcyIl`5u1!aT3-wqB4q?J6rsr5%E}SQ z5%B$I1X2X6d(;M1M8z&bp*$*JkK>4c zH1^$2lCJ7Kpnb`mO#d}GhD5or1LId>{AGc~Gq-x~37B_$F(!QHp&@%si3j!B1yt$8 z#)E1_44IwSaF9$Vc1+nTJF!4M)c*>Wkz6_T1godC!)0htGE$}|LXxU7gaf5ue2R=b zKh+bC5qt+?d2o=2nFMRz-RI$;aWzY-K0Pz4=RN{_N1p*uD2yn;dPVdZQXgS@PAR$js?b@8`I z0DjXDg}wG9$`Y$Ft7O%r{w3I^g%uembO}P!xhgVEC9O1QySCJ^x0l;w~uV3FmJ z3IIORWjW-60<@6L!Sy_Wa{#m`1keq@EC9>00Qm1#t@r7(K9W+H1B$bj`lF(=7-@0M zS)j_i%pFi5^D^ZCe5A@;%vT77JesxB&Ba8YQiZZYlBS%pLNY}IY!C5E;{vPa`DFVZ z1niW*@Qx+U^1RGtrN4p^3aFogH~o(@0Pjlvu_55( zB=eoD+uz7VX8qwH?iXcNw>nVYv(WOq=Y%sdWp>C@kFRrB89BQL=JU^yx4nE#W%KVz z!M^_aD8Etv=*mdKIhN|*WXRo!3fb279CJY6D|?RYMug+(iz|y#<=(z}({mdVs0H zr7$Wv?sgMc1Bx+%-vEYM`Zv_x4vq+v}sAq{8!!&5h zszTnz$Xad7iI;& zR#R{c#qa6W^rnAd$;*Lnx)jba4?uqc(*cA5_{bJqiO>p!BDbqBxArZCB#eqvrvGr% zTcO=bt}-f-QR*S3q;^KE=QMqiv2v994756XraJr}X|w|5Xxa1watu9)&1~d|OjmhM zwRM8I5OMre+xM~BfvGl=<^OK?lWl&qkri#JQA$&t7Hx=#H+yY<#$#WFIMRD}6bwzC zxsDC>R_`RVf87>>nE6j45Zk=u#s_`BoQ=>^Uit(+y&HsHzgi!8)wN#)bEm&^h@hfQ zY$dDpX@aJ>6LnVWOPP+-qgJ*4GpQ@*Dk`4dT%?oLP4@gmz1Rj{1a~=T!yP1T)0uxH-MVQM?gS+x$6)PfZ!u%@M(lLAQZYnbMVMor$v>U?rS8R z&_bhZs7MnOYw${9F9I-X;Q&}`vh()U*<*}4nHK1pnG9MkoxiKtHz?q^M!<$l6ib-0Uh0n2oi9Dt;aOiOoY^Gs*Pw_Ge`B?)2^bC3`-oF}*_DIC|%h}I-)T}41T0j|Z#sms~B}k5aQ#E)aw^M+NWpVZ@ z(|9@I2?&qe15fwVmT^c0!dJ<-!Ba;Bbg*+qy?dZ?q%8c^t;dDG3D?-x)wT>_n%9eJ zoMDb7CTl{38uwIAsI|GxK;-fXbcLRu|(N2f063m zrOyYvC=QM#t^|AJPQ|jDUkgfQJ5(dVHI|Sbe*#~BLXW6Km7zqk=4OySzk@0rN(4gf z6nXlgL?AYlFv7+(y=B`{c&-}m$93?(8*G|0j4 zOz4${zW7&d=p+9cGTf`kA_|2NHXp;Be&g*gWPK1EXPRY`CeS$UWy zE^_l~Y)0iO!{&O2TjK)iE6}kv_H3!wBGI;zgl~)Rd0JaZ((i4l*B81xt&@@_493$0 zYbVKY*#wiV@x18Rv$fuOM2H*B?sKv;GJtm1^Gv-vfK9pHwranN9F2dbC6Le7yBA25 z=1AEU@SMbR1$ahwWP`t>-nme*7vZbz!lppfssH*fk}rIrr#byVpKl@Y&I|RPdgu+T zOqpPC;E-Wj0eiAO#||g6{O75{G5W-Pv8v~N(c?^1IPjTk;Qju|%6XAKyT>FxbV)dH zp-2=c=N0;#6_YsVl5pT%lvvE!t=gD|;%~G*JtyjY0YRD9ppCNQ8Dx&*56DMas0imc z_CZG6t8y=>v&v%hn$g5UMix0&)5zB9PZ5>FpCd;V&ql5V3QgQRHO)gI1e`PClQdpV zkn|8HnIMVGP&_9{COi0qh0b<|*fLFYol7|Mum(n4;tVaFbB~;(kuvdGLm#4>$rVLi zt=jbQ#H91!1ah_IKiESWrT#o_i?1*r}-y!U* zp*7Muu5e_6Dqthh4f5`Ws;9Q^x~deNt-Nf?t(+MgXl`gA zfYrP77K9g(|Mmu~#@0G~9)&%dcQhb(7@_dp-LN{VNvU9)e}99{HQ{O7fd3N=mB1^& z?7S72X8|Ox$G~H+$~kji*rp=a95@SaqWEWJ$jE@=O%3K4#WNu-iUpwJjl@v#y8xV2 z)&HF-Mu5Vb8@yu(tQiO#u7&pLMjH5WG4Q{jNKSdo27duKsAp$`1>h59*KTwJ)cOuFOl-;> zNbDJgI6n?G2uSR$_I7CSR0j7Ef^W$vTPd{o^$5>k$-@Lmug`}x@$crWn861 zXrc=b?GCp!rTr)j0+p16aT$MYkXU;_T_n9XsOR5ZE!7@>kF0KT#Y=L1N& z7w0w<14u1cE%?%9EA1hGmW8?BZo4Wkr?HmS|L6>;<-WRc5R;vDYY1@f-Ch7bvdMNk z>pl*J&_}ffP`TZ1GD5N;;C~tErb80-gnfk4WjNK1C>UR9V?o<%18|uiO)5 zg;M@>vTZsk)(0!{jtbF^cRE6{Z*G8cvk-SWc(Wa#2xG;$E;1VDq@}jmHfKdPD~%n_ zDOKt0d2u?OE>`4yWnqnJh7yo2Fsfak74m8cRlZ(T_KxiB(Dv^d2YWPkx}s!dzXxMq z{(9e!f<2Us#`>;$!o|k>x(9TqcD8H?8Mz&dp49s62doFpD5_ zc-z;187gP6P(4zj6f0th`bd}3>;aUN=0pIMrMUzlDa~9}7^cDkdn^=6Y1Z0=(j-z! zvok`GdCJPt900z!(&UUIe^pC!qGDN^a~&biGL-Tj#j`Z8bMU4#Nv?2_Hw)SQ_4dCm zD$Ba4vaCZ>)#PSy;V$P)6w^)?Qy-_8%9QtzKJP#_?JMe`nB=9bkBk_;0n!;UIN?^C zQ8rSH{iNJ*Y)RxzRlpHLA>?72*feRLHoZt_rSt2HNVGx)S?R5`6(f+g7rZtnGwl7) z<4mKxAXj!e(ND!52@Er-o;}{& zUw}JnD_&ZU0;qX>6$Ip$`zgX<5JICg&HwjwNhqi(h*jt9rlv#Jlw+m+7G^8IM^#zqjyx0UUwsy2*-X!R z1OOZQ4*~c{4YIZGwhbm=i$5Mf)fWG8lGx(^Ly~FqBT4^Q@?(a-LK(sP&|*ppc1xx6 zc?walx+yC=h(siWtj-G)1>{?Yi#*ppe!NCAm@} zrf8t1Kpc@ZS|qHm9Z{(6`ntT*WL4@bcmB)n!{TLD^l4QfYgkulish?;Db)wUKQwZD z35Vz~L5~#MGaDiOjX_O$96)OTvj}ts(Bug;&bEUKZ)+*ApohlrTCwRps#{{ z_X$D|A{0CdAmJ$_=2rl|R74T9;co>%1?vEKgFq7ijh;qLds7p-N2W&fhPi}A7Vbjh zk$v(D1fb+^G8^D#pBMS5tYTo*_Osj?EF?{ba-=rYl%*yye*1-XrV5#)!dJZ*2 ztq->WnEqukmbq0hfWq{=Ts`*`a0fulJq93gCui3|ISZPCb*{h?Coly~0I-28Xe$7& zHOmBmd8)r>Dza`iR3C%|H5n^1ej2CqcQz0acoZlstP zWi2S}LCG^1Do4%XZ?@H#-FJ1nRHYtEu!S%j0`?Orm=)oo+@9(@O%Neg#<~|6{JWHRK%YOb)Te`bemSC!7&5o6 zRD+-Ola3Vo>HH8{$`=0`tH83cQyiO7W|9FCaC6 z3ZU*JiheZ(sJzK)Af{spOyys!2xGa1i0%LMtJTU(XZT5T7w=aOE6-{DigR*~U;U~E zp{l-!lL`8dUnQt6`c+Vw%tWlV2${;__>~Fy6f1spKQf-(LoqQ5{b~Lh&9e zr!!0B-xRs{qg*9(ITwfDcM!6#X#wAwH|-*FvGwfx65qNm#%FB*rtr3q>AcwDHI?Kp zN#JLE2%IffdXU{mv|Q(L!0TuZlmOEUn&mo=2D<^AfJl%4uk+XfK+X&~p^7WOkGnbU zXbzv@-5kGw!GFT*Xgj6P8w~ZrmqCcuQ?#5J;@_kplZ5?XmdimFgE{XNr5dlDf4L$m zz^2HEQNbMl9mAvY^Sh9CYBctaDaaYn?wdTuxX41PJVYe&nP!qVc?3jM>ire=uS$@c zJmxqQ^eq?SULZ|gtS_#-y955;u|I}T8eycmW2D=WO?z}p*snjRBVNH6C5LRx%q-yNYdzCXU5c9VRpJtyVm*Upc!HA6n;%N?gEI zW`X2BxDC;iPCD}DBSwm7Ixl0{s=~ygh~(y#wP2IGSStB>4@-cj&vb>Zd|uB|Ghw3+ z$nO%~kEoj*a%W5Z*U(&fTYuyj_*2!b))D zb08v)90r5`fNFbJpUn()9jLf?O=TTN4nu>VG18Hr0Yl!EDn<*6BllHA7;MI|rYeq( zyj1ZqNB&)j^wf<)tm4QG)q1CMa){M?PAK4?WOYQLg1qrCA}O6u zkT)MOQbgj&r6C?av>0sGaFEBVEd%fWLBWvGt4t%@UG4Iv*n#F2L)6gY;^J>WNv zoUfUVIr6!Rpd&vEMq}ANil-yLU5O7(QT*v0*`$YlTdvuPIr3v}#FY2?VHct*yQ-Gs zc)uaZ_Sfx@^&_C(|2iD`7XZ>CuTV z5+8a>(-Er_Ra#^;D({=pxdwUjB?BWxB#yjKg^5KGi6egpHfd!m`JEOSJTF6+I`T_Z z9J%WO=*|L%IPzSC0{IBd0l#tNV$F2Sk^3luj=Tbl#&~Y-TO8Go+VfR9RNH_?h*jv!dp~9#sDa&n;>Ug z(S@G{gP$vE{LRqkgYDJ9Q{JTuzofE`3+F?_hhUJi4Bba@ z%#9ZbHu$R*PnT*f_$uD}fQuaGy;Flqt9q84b!l}}vSUg+afXw%1xToU{9NR#38)L+ zL)+07K$yw-TY1Z9o0BQ`p93x))<>?uF(6BT5d*&qj2JlMeKqjq0K~v&)Nvw8#pDDG z+>lCW;77sWFV$4sr_UrqJqfB6ZLhN0*+IiOjFE@+HU9t%^Vcdvf1qhNyo^M4D2_R} zQ1P5`eMRG-LFWs;ib213k>d;+TBtNVo6nhE_($W3D)DP$#4$)(c05(AI*$XecnT~l zRemAFq{^ROp4H!fhQ?*$e1~zCfpU)#euI(6vq^jKGbnz4oPtZCKyKLU^C9dRX{cnj z25UhwHa%DIYz;Om9ySdbb*FC)K5&iCs;P!pYw(+zPY{=OfzMfW9ZyNB=REU~B>Va_ z$*L)Kgam|hg0kG~b1R$>2LX}uq z;+l_kgc7>uLtyZiB|E8jLZ9~<>TjT0(Vi;nxMmhK>;{9lX5){+F#m34_z-Ag##aD2VJu+5-$E%d3ob07dhTFie{P(DZRxNl-*Gc4V9!VoCDS!u1%WpDUiOY1EzG zHGgoqW?R(|bIk^B#FY1tgj6ko2hKuL@SBMw*$uiNhetqd_yu1E07!@4UU>uX2~X?h zS7(BYu1T&yF_4!4Bd)ms7;(+#3D7lbe5tP4OO=#SN!^4aG$vhhAQ=1^nu>1v{K!xj zfNDiYsjTCg$DpAmW29@Y2SeTorPG42lr{f3MYI5$G3zIaqpS8%JY991#z|kiQ1De; zb)kzK@2W{kbGvFFbuczg!I1ehq&?2Zu-H;Y?X6UVSWn01Iv_V!2;7x_pG$~d7`jJT9!w7E;dN*j*#LCOOd9RmGfHR+I3F;czqawSG zZ_u+%hEeKv-DRQrIyFRD;P)I%ZZGbpi(KI1wCr@)2 z0^nx=3-1O{*1)k#AS)XOV7WQ6R+<4;q=eTzjkSAOk@J=I(e)l{ zn9$@3w8)K$PeqNG8N+i43M!*1>IVEiR(@TU!%w~A?I#hk?*#w3a%atW-dWQT_ti{% zn~ZZ_z!I?cE7{SKp(;|(b}U!pC_L(wezx9r^A#m0e}k_?hD@dm)LYLYIBaZ71ixpn z`nR|XXX>=s8a(?uoIc5~U%Ws3h21Y)>K`_35Q7D2_%ix?+vHZR1!`@-h+))A64|Tmr_Lz@IQhjcL0DsKSNiT zy2c>10-?)Wc12xPxy$wGeJ{5^(ECBp?E>Hg024=VtON5`#yAGsPn$TJ9oIMp0`QS4 zaZE!9)5Xa{P`ywjqo)?kvb;G`Bp-k@@}62yGu&p0w)q9M{%=*!+oDcDH)~Z9e7rtZ zOZl77-?oyWNb#Zb6;FP};aDrIZt>?vih)c9vydF`llGlZBnG+~QHz1L0PvA2iGLj- zF_4ift!khqzp8kCKb_h8@}oMhSyW{1&lwilzG zTnAOYGN4E2MSxr{axVZmZq{@hMrMz|H-Qvg%rxz8?%2_4;XJ)}+3TTAoTK^gnz$SQ zmau=PY^KV4AF%g>J)gc*GoeGe)0W(oPnWWTR^DT(p5?ZL84RyL&HX}46gAB9UTbIc zMm#*Mb1oyi2f%#<)&V#OAaqjM_sORv{8mENGO-BH16`%mJ2!QbAE3rZ?VG8Q)#4v2 zVv!9014bcLisUAQq|^tgT)sZFSoVP~)#48TOf^g0@DwwS$LwDbM-k%?{Y_6mKPjSr zIzpn~$ZV>re*@^E|78I9iEZytmwr>9-iPegeZWWC9yJ1I{Rx3EwGufl2{CT>4$P}HsCI^loQ#Yd;UZz?9UQimbmt?XsslA`YL7XTJ@7=VvdDT;LnNl`3q=E#-lQ;Yfw&?P5zP6<7f zs&saNrn!;w>8Ry0!IV#){Zd~DvwSijELx^ei?B~qwi^ulZ2P!jUuM|1#@MseY{u%| z?RLw4s{IYa-tcc|kIZf8_KO3;&D@e}xPGtXhEjH@NVv zQY!U4T8R&(s7JX=FzsHpQ%9T=jP0Mm-5FzuBQ^&S^2s@1wry6Iv?MegJA`1T^~V<3 zNGl@9*r{(Fg5>Mk4l|B5pC`8K!rB0Lar|JVMX*=b>vyh^u-S8TmQjm8frF3qMGlox zR?cWdZGAU zpWfC9%?4=6AM<(~ze=fwJP7-@%2vCjBj(-Y8E)7If=k?R4%wx;tWvfxDulN~!WOc! z)mlSVR+rrXe56WsX`P7A;@L6Ws&XZib2_VwK@;s80N@uW2kq*Cn3&JAymb?pX-VO% zR!+)F_35pj@V!al4x{5Jb%YnARf=FrQGO_A?^y|hp)mJa;A>S!bTQx_U^)}C4!|e? zp<(8)n$}Yk(Ow{=5wnE}>@D)|J%5*6VQqR%n8z)A;W)um>`b zn(ut*h{cD#@X&{t&o8BL!-J5DCseM43IEb_MHbYL0seiej{$RlIU@;}5P&=YvQyN^ z9-wT6vs3gixwunwXbpUm%AKOQ+$FjNA=xNevnEQ406KNMP;$fyLP>tdhG0r1U1Yd{0Xer@fYBj`G}`@DDw6t z@c%+j?uP)*qfFBm0W0^}&W8_v>j@g@w46hqb^=t?AWpcPldA#oIHU_vNa*T%IyzF+HC5DHku&yT`?QLp<-!s=R-> zc%O^secHu~^k!nI%B0~)JntqKFVZmD#d~IUoE^4RW<6*n_brVeet}TtMZm><4fK@;(5Ed z(u=a_fa!Z<-_}Fo?9i+#?_?M61@XLRxOh?DR=9XCkLTU(N-unJtBd!+c-}!Sy(qVL zT)gkZ^Nw`!_O>F4I?SLQ{*CALxOicQ&Mw}LXm+c#sqJ07$lFvG@A!CLzl*mIPPugP zR?(T|;zJ)E=3worwoYM`vHAbrGsK5?omv=O6Xcjtw!j=G*vJ*B!7Din) zcNOvDhaz@o(v=mlD=Xsn4nESQ3%eHL(uMs=J@TzX25J1(AzDwnu#X6^3+rAVUD(5# zFw=#}N9+IT!klr4>G}tnA;7Pm`N)V20p>uN3;}KhU@hjr^Fn2tZrFeH>>@j_NO_j* z0|9)>L>LYZ7{!#EoL8u28TgumgQwS3g-3nFd(0!To_VImIuHOl*D!MXXpS?0`cnoL zBYEPB*MX;jNyajZT05n&S)blhp8mr$BkPUI-BcNV2Q$7KwT6~LyZ0YYeMC@n2zdF+ z{Tt8`3jGYA_E|a}F){}z^SLbpk4zBd6Bc1-Ns`?en6MznA>_0CT9}t3B!zh=04+?? zSeW0C#_>q)23nZu077T#7%i?aOJzJFg(@wA*kHQyUawDYQoU(N<4@M{O0k&xPOb!aG-8 zI=21Vg+J=zKjp%w>B|lEpEaUV{~{N@lM7$avNApARpPI(KURXwWQQDz?0Jr~ZB;3< zs8S^Iyp|xNzM&EyYOhuyUbAcE{9G5+B+Ys4EYpT{K)R!N4J>6B__2_3W0r7TmyQ|q z#<-yOVSKg%sr@uO!&BM1c20O3;oS(2l&S9wd6D`X;ql9H{**T}VJ+l2VHal8Qb%J6 zqi%V#5{4iisROA^w4nR|tjN!rD5g3WJWTl_IQ5^3=c}^ftSPVH-8xJ4K8!Ux{^miA zJ^6fS{{Yl^O+8k@mjG%cgg3VmhTsnf-rme(E#dl5xr&z{S+(w6G!nf8!6282o(EF_ zSBdaRlq?d-*(*k(nns9)qA3uQ&z>of9nT=^M!$m+c}pYXy3tU`AS3@-H!^CgtQ&>0 zH8SV3WOKDtCNku|NlC^4??LfOo0%`lj;9qe?{W4BJ)jC=tKq9MP!i5BvO<&0Ro}lP z$!JK9k98REhUEC>R^{R`CaJJJGFG?H>e?n|^j3*DNX`|{Kw*Na3KLgowTmpvioFcU zN}Gk{1BLYDzw@Lu zlY2sz1AkTv)QrUdh7-6Lz=HsMWDBlA=u?D(8vvYnHh}v9+yY?XqX5p+L@#^>fqoj0 zTTwDKGHWCvJKFS;06dp>fqVv0xeKIEDgfREvKfH?7L|QcpS{RW>gQympr@q@wgnKm zL-}~rZ3=iRV#eHcoAcwxbG3iR+|BR0Y#3eFLF4(QJ!Jk=<$^&}NG9!Qpx zIyNO3X{FtXp@}EaE63j1#}JKk4{V|wO(69?(aXx!Z8>O}VXQlOYB|Ribi0`txi6rV zmz!;^ZjZ$<9liWqE2Af>W2PL40P5}-b*LAEN?^W-VTOAL10l`G2(Mf=o8hR=^@h<* z;4>qd;8+*O&V@ak=P$^nT{;1kWFn~dw?f^B0QkNwM#Q|SDzmG@H%_0P7T&AIfSWf} z1>1p}H&tB$AUmE@PDg$klu&<_J>BWZfeh5^mSeH0;b}xGmpELZ?D?$mL%nB$D3>@K zWOT=1?AGm3(Qi_&TlM+j80c^=aVY8Tq`6d|e}E*HINS(9D`c`ByM>_g5{KwU)%F0~ z5ZlO*g0nA#-jz(-MLn@zru5|Vk+wG8dLZVm0{$sz&RqhaZ3m=nk8*ve&yCCi*?s|4 z*c##n)6lz0jwK|ki`HFy{itbQqR;1`BDeu6{E)!^R(ugY`Gi`d={b%71{?PxIaYqTDi(!}xvyLj?f; zT;(d(XH&!WLPur$8bFAf5+v8Mrw-#9_hl4HtI%h6CL;^3XZb7CM#jWrL6XZTns%bm zQhPXBGxS+VGQX!BO>(xe_$(#MWfa$vgo*GAa2^@iA3%Oz1TNG}eKp zAtWdKAfyai7>V@^_vV93Zp&zfgDreS$_*K#VxhMovj8Fd!h_MSj?rjJC_mEs7Uib^ zzX3eC0RV4Nl+<7ppgF3rjbduKMm+>xO zN@K8^-80eKm2KYVpf&D{nBND`4?xIpw7XvVA-fxzdu&AK)H(*Qk=n+9F!XR}0F_@Q z?oc!fD&IlZNN8}OWSg=HxW~zgzOG#F??YP8(xk-7){0}das~#G<&)K=V<}elXL~vR zRe;3WW2RuN#qY>Z%7qB$VEpNvs&uOQHe@{q-K@Ooc>b2}$d@5J8b`i6p}hzN%3{X#Eoga;bQ*JG`3^^z-$M`N4DS=gpMH;dBj+ogTTVwSz6ksiUHFR>4@IGi75@%KaL|DZiYp6Syfji7aP-IoqN5CGe#u70;9*cbp~q4P@uergNl_Zeo_6?&W zL-u%+27_VzVZKvTOS+>5NBjqh7PHnHp?6itQ$1-p39)vZ;#DDk_d?y37qzeyW^QjZ!0j-0{8_c8 zV(96akrakpZZF_(0z>Wv0A3@I4d4d=KC%TTBGjZ0DoX^wbO3=c&@CVunUq^Fog9sqw{UwF;bbxO5kajr*$;QaihO8iit zc`!G&ws|I z8lbJzPDtJKng_89Pe~c0k+XS8xhcT;p}k?6G%O=CaoT2esK=;u`dO|dEfa(4&#yconI0tna-VcU=;a6 zCg8UOvRjEsXSYQnAK^zuLu<$mJNt1EB#}cUk)7v6E+vsYQcoQ4I;;k@SW`}-sV>*N zr}uX}_8M5kUN8;zsm*D=fhf5~0Gk+S^(Pt z_(%s0NAfdSVZfHe!su*{nM-s5k z!ymi)mBNMg?SOIGNM{%MAw%wfE{#8KwLnFS>~}HkGfeB-sN+X$wFRduzBT0I=PNnX zO3AUo#t9QU{BN|Tb&@`((l)eU=fSWIZ8{b}c08Nd_CMHQXYelqKYn30b{U%Rd>SyN z<|LNWAHd&6<=+GN27r&$U;+%^JsVS)bpc@VDcB6p2|$GDep6IYDHZLk(T;67z=QZv5=A#b@R-Z3BiX`Cv)M4#8kq?(IVsvlB@NGT4r0%7Ri7vpR!oY~-<|N1~D zoxHP<+^7wCGvne6ltKDXOuC*(UkYg}lBKC=kES^RS#u)P!D)1iDwl$)rCJ#X?bJZ5 z%7nE>VqLWYv5hW>U?}~g*nJyf8hIyL3(rqU(v*%w_~oGpACvGbgwc?)F)KzAv?0ye zQWG5K)UbbI(>BP-<$Lbq*w72=@Yd^g_5uC&Bl<0Qdm#ZGazH zMx~iGsB;Sm#URurL5A;LM1seAWSQDm7uC&g5C7ggt=+sS({ zPF1wEB4|l#+Aa;*5ooq@mZlCW9?6-sJ-o|An))S=4g7%9CbJFN3Z!Re(xNEZ{n zk8n@S+hxjGYSOyfgB|g5WY*KY=AoHr8`!#!7>y=@t@}p+e56Y2-hGU=?rT*pbsXeo z)JUZqM;d#22WH)#ZgWQ?^N2uOCc#eLOR);8+N|-2 zVM|gz_;VWqUjYUmk-=67MJI!u*VewO>|wI+OR7e8UR!%77-Yut2mt>_%Jr!}_oABU zjAyc@I#r+FfFv`X8B^fMA(N@tL}TTQr@Y?b=snuX!j!u_J#QpUWg4DA8pc9Hc07Z; z-d%TE3SaNGF;?X7OHHZFrs5?P+1muYnR3%%nV8H+WTv!D4k9mE6JeSlD|B4d6m6_* zm;whNSMwsYYh26q+$_qDBHn0Am1luRI;cS|+JMzSL`|jei)lR+Z*%(03ZzcJ7YtD5 zOqj1p!n?dRo%6k`R9P4do{}V)#Ldh_sc^3MG64Qf%CTLatDr{MUNUTl0fe4Va;ykk zbG?=(#+2fNP$9FmHG)W-KTF90eZE36r-IXjY|s;xe28RD1&<;*+n}c^S?79jKbKmS ztwwV=y1aF-GM(JCVok7EXxiQ?p)ae1es_ngoD*lmRAZ8*R^@A?Sw6?H79dG>#auMZ za(B;|WZvD=FJ#sv$H-lTyAhT($qSSD8i5(U@k!P394FTrVrhG%+@LjHg2`djp;BnM zQ==+nN#!PYL?pS70Y3>0F(5lt6VgwgMP!k`kU_;-(Z!f0)}Q}9)t;p0z@8+Zrf+?0ak&-Ya(8TYQ#7{`DeJJ0o4li%QM)2hsrX-y3KMc1| z5G|w+kFaF$B6npI=Q6p{Wh3Qe@T;1zq}GAVQRCH3__Ee@wlS@Gs`U?0wkj{y)` zuN<*iaWqS1ic8Xbe+W^|F5fN%a1F%#N0j9+eclQd$8M#v93s`Ut+V2EaBGbXm83pBtljU!7mHO$Ty zi5w%!3e#dlHYk|`z}F0UtI2WbGnce9B1zp$)0OiMUrX@CC+lyjR{n=BaEw}QE*gRA z3rr(WU#zqFV$%pX;V&7MM!*So&eKNVENKL|Nn{x(>KaI`XKVcvs->r)R#HnVsd(HQ znt(6#>AAGYlb5K+T?W14ad!d;8IG98=?YAs6!q`ELKLVpEiEO|_aG5C212I-5N<=? z=Na4NJ2-E%d`$Rp0q7F!1mdqqpPuPW#LZ`bK_XoVAY`bnNaYJ}G%*>IFzkzI&uGF% ze+y*%N3mgrzv^n!Yr!-+l7~jJr!ZAe@o&oXXlw+7V&Zq@GU1G)rIpTGBkq9$dig@M zGvgFbA8~MylR1V!7zz3=mY~5+&KiyR`b!WOchK-hCsRGnR93kXN+Ib5c5Fy_f@nZPh%0tu&skI-4CX`3zUh`a`YXotq7^gsTyEaUI}sK z3K`Y0s{Dg-Y+WcS(?UDIgwJj=cRmu%g`z!(vl8G!(Z9g>$R-O#JqvW9sF(m3iarD2 z|3cLzt3BF5pDYxeRfs&;iZ!N->`-<#q65In5m1deeOdOGY)S_UnF#cS0L@He;+vNUMy|1j3P2Wuv-AV6BX+n-%KnB1&A|%D9mJkg-o} zC?Afswo~TgL%o2?zoXCe1+e3ji&)!0y#b-zH2~%=1aKRG+(j_iVrAyGF#cXbstUG( zicE$K(#gFs3(C%4qU_u?#@|VbJ*Q%KE3&E>`UAgV=Wa6oGLgE1eJZy7v|`A)->{pU zZGhMeW+6#()Mqhr#5}G9kR8ul@UiNDtBQVB1MaDcl{G9pUpZnHE{RzWlAe4xpeWIrr!_3JT zuX-{P*{I*V9MyT+f|;0KN^FP?SP5$@imtYQss)BO6JJIfz~9w&vz9>YPb^YIz?zH| zhs9_UWq(&6iMinls6Lac9DOC~-U$2h!8mdj=V(VHa#;HYk!3)RzPNA}`Yn+he;|C_+?Kxzhmi>z6u>tC0$EdV&Who= z_A2FhhX8p}uI30BJi&_)x&k5p8=5WdF5_=3qze~;TDSs#A%iwoP|B>ibW4#2V;l*# zNyU&t$<|0H=>fyy$2Li>N|et>L-WU1@(N!EtcEI|^dDAqx#pDWu!4w0CN6=IWy{>P ziEK^wGQHI`of-PP`!chry(V!mm`09Dhox>1+n%)&uLfMyHbNE-eekSJ>BC4n^2|wdZ>oerXh>wiwx78mz8*|6NrJ0`4Wsu z_Kb5P=gcfxYee$iQsY#YC34s04#XE`TYgGeOPS8)iHpG}ZT5g`kxsVaw-I2QcL0Dt zRXw_&KA(rP3jdYYDgPz{a+04=Zsg3a!FbXrU2mUv3Jdv{;8{+gM?q{b^d|11z=I6T23n6nGGw7p;hM z_9p-zsfBW8*a}S$9U^px2F#gZ^6j>B=N*<`LMZ8C<1G1!M=&|E5X!_^dTZMk29u{S zanCX>{1c3p&hi|Ficefs>D^6dMi z7+zEC>E$^HFmgwgb0E@NS&U!(PkD|8PANxIZ4DkW`8|o;Nq$>kq%Zj$1Ry(}ztY(o zRBcb<@=9+H%~spS8kEW*fo#mp)x?z1_VW|Bpp0Y|wuDLGWbG>e{PUD+zCP=K&6yDO zFI3bjeezy<(eS;|P#4WeXt|PO>2S^C8qw>OXC73@JZ^VLVp>AcoAkMcWX|JGB01Zj zO|i-x?lO`vjjg%oS$r=-%(P_pyDEj{->6*W`mA{cUPWb@@@^Sw+{X;ur^I>iepO@n zbG0$OO`j1+I&cWI(mG0u?BbS`) zIJrG4X&(z40F*l%Mu}}ooCuy=Kk%<2l|CX1CLly#_Fts_QJ~K~NI`HBsLR)~1uq73 zKZpls1N8t<)2{;Xhcc7uDf8w&1l&&`=H3lp^Nj%30T^-k`3e2PI0M8ttxa=%Nx#;hoZM__Z@VRtXa6 zxCTs$DGm&F&?P$uOhro79{kv1Q;ZQWf7+wOBAzhLv9*pTF)Ztc0dh^ zy1KUmU$6a@T5PrTX-2ZP=3W@x|&OwX^H^hXBV7Em;HO zMgITr>U&rqbf?B=h6vKpxn9Gp$O7fy%j-}i$*J}1hUD`cx$`b^g)*^i3Mv!kL8A97 zUOa+rn1(rrdA;!A&7fRI{8nhPD=rg{bE#gJr|aVl^B#HQv&UbJgNyz-g9w6MhvAhV z={~;5bschE3_KH6OtIIDiGjCGj)7~4y`N(Jxr&oi-mL|-aY8GpjA*M{KO(qNne-eH z84gikhJ>=iMG+W+iAkQ$_=dhM=SV6V+V(@MutTn4nuIV0vC?J1@{5M|5SAUDUo_-< zYI=k`4nFhNdVs%bNcFN8@9Tzqcg;MN1oR<6XMTG&;KL65AYV_9IB@^wfR8%xhg@#? z#(@_h4$rp&b4T5G4P{?mo`Eu7=gRbQTsTC%bt^xJgZv)`DAtX%tm4wXJyw3z@|6G=x4d|m)A2U#c9-QlqY)3K5c(yzANiM@%Df&we)N4nn;1eX+H z|LRAo%9;kwf6l%J+ipHn6pxF;ls5=(-hi=gun{yk?HxXKx2n#F@JBbS%fR1X=8mtd&<9oQ;q$H<_!7-D} z%q&eu@^qx*iQW+K5tOt~g;aEIm9z)4K%7jqt)X^37<|QKPe%R(iqn@bMseoe0DL|Yk-GxG=L8lRU=Dx@_aU|958kef!3P2C2Rir| zfMW!n2N1d+z+M3V5_liLEe`*WNJr`x6j~NA!SfLshY(GOum=VSP6ci?IZDZq zhtP|{;h&&xSgg-}QA%%Q<*KTJX#(LN8;d7K1 zUytA``UA?j6kb{KKRN5Gk$9=%HpBTLbs_s!q@R*G)_dQOH)&K7HIFHc29!<49f1SL zaln3kr-{ zcKjw-wb@hWT+|NLa&KK&xcVIG1d>|bs+D;TS*u?IhEo33E2uEtT|xn*Vr zV|6tSvgSQ%Rxs99V}v^&M_9Jy+$j8`pWv=6Bx@sI7ws;aDj1QgAQiMWlHMx8tfEDBgPS>MTXW`h}8!_Pki5EovaY%#@ z+P3wHN*w@;XK%G#h&A^+;Ojnx%0*=GcZ4P&6tq3Ib&x=906m@ty@K?{2$dofYz^Qg z0QiNsb;sL~W+yoc)gM&LMgof72R?Tn{!W51w;Vvt=b(rz!7mWnjZpA=026lr_yfR` z1Ux-3*4_!m5;E3CXwVDD@`9O;!D26;t9ncHOoFv|C%m`5a&*$C=e=q-BOSS4gLd{F zB;g|fg9*F=AOawiqO5bop`D5(^<-Y7EbL-XYKBp`r&?|Y;O~SeoArzECF4yfxn2X2 z=`G?SFMveLZxze8e+`zu43)wgaT1?A2b|AUn+d6+^}rXc#-ESa;5~po1b_BzQHQro zpSk22vKPswL@|K>uoO}_WCZwPCl#r&%R*?jH4S{LFG2zwzpb|U2rvug^kkahu)o91`i33qRhoo#5^Q$C7-lt^HKA|PJcfI8s@RCr4%j#-z z#GH0R5=`5*md*NYkGlnLrr(Vf3>%hoSr+YDi;YV9uCsveR_nQJymrb~n*p^bl-YeS z@Cr*KGq4tAdwe|+_@%Y1DQvy+wK;ocu4C{?NRxf`tw>=t#JS~76j40@6$bz`2e9@n zRKRlp3`PSM><-{M0)qg21YqGv09kV!UECeFzN%$=`wDcjB%Ns*XX>mFJRd2~2+U%AraZ)d zqxjWm&VH}NNB>eh$48+D)fTa=C3lvX5qVC_hRDlLjb!Iox$-6CJB4sF68QgEd++$D zitlgy?k0p(5;_86C<;nR0w{v0fgqtIu!LT+yOaxSAp`;ekrG7^6g6O>C=fst6(J&G zLx~>|v49AofTFR1Vj)xk5r6OZnR7Qw#C=nlVitZ zp8CLkbWF0MVek^*1NWgY+{bIPALB~uz!PY1-6w=U3^$?=9EHjm#0zI;{>kNwlR}R@ zfR60%a{L5w8$GVlUp@%D$8|xx`&Yo_Yb~d0L#y=`aQRBh>DqMBfv@!etATl!5qr8b zwdvHy!N}IrU?aZ9{n4@l(xZ;22xU`g3EqB}SEOsyITFTn;3TVTLD#Iqy0Qxb8Fg|@ z&Lrz|)?&2KvXqe`Ovk~L(@cphN0gCemyI=2EZ~)pAc31%W@*i>?EJ9E`${#_J@Wz@ zS`)iQ2+uFdGlT7uG)eLa5?@#436^rR4o)d&IJ5!Ela0h?%ECrZvAgLZ)QgHtCSitQ z0vK`}X(wSglZ%XdKBy~GbUi^`4(n)*(C9J@A5)h@pe{^@(BoNSagrgZtC#5d1FY%E zAQ*WQ*yJ0?FI2^pHv@D(*sfiQbZu)04`?s)L%^C&f{`x|%-J{2lu3E~g6kuML-`7uOZ;+IeLL}_RVMBF#m*$Z`Y0~?(*oq=-e+IDEQ8z?JpU3(jRFeLOS zct57fm!(XXT)UR>i-tP&^xCJK(##O68-0rssK{h)b}$UC0XY{{2h%V8m0eA}l;_p& zfksfw3NTi1HxDqb#I<~e zA(9==h{8Uo?_|ll-YE5rvz34-K2~<-1d6?23sR&0OVQ8;tIxgcNFLQCbl7ls) z%!$dm{=t^GVXwB!<;sFw63@T^la<7F8icKuPecQWak<#sxK>i^Ig(>s zFJZ$rNv>FraZP~UBwnqLa5hu8;VC9gT3NG*7-K#og(=0#I$%0ww0#Y2*MajCTb$-N z&lGcpv9!4vjatl~G^vE^>+51Z}kEO*M`^7*62ITZ_h9tSb`hP9w0V zSh!LweBnFbV&zJ)ve^%4BN6{%nC%pFI`P2LnQpt)gA);(pA=RR$0czFI~M0Ouls0_yhoc>FRX=@};ZwlZ;AF z@;Ds)TaFb1e(9>&Nu={nB_W-9|7yl_YQW3-Tu*@#2+W0mm9bnU9Hrlq%x_)2NPSLd zxjv5{k-Cuz`P$VFWZG38sbsD_N~7X&&<0?IwE5aqDlVl{8rK?c6dG1`aOJ#ZFH|+` zmIj4ToC>)0ZjIOg(#&Jj)Hi{0!L$3hGU3dSv$cR z?_-Fi=6PhoU=3v^z*q6fJk5a6A~k&xl?C!m>SpM30hGxuQOt13*c^x8=*zgEjbGC# zM)E^Q81M6o#ErC~krKs+3i%NsPcd@#bdWb7yt(9kPHRL6Zz*`|!K;iVw;M|qmGhbT zu46m%sw=pquI?@G>Lbw-JRTl-v94vWQlk@|KtTv={}_w_Kuv5CnRtz5|EUagnTHI6 zRB5NrX0^XZ6Ls(RF6#~DF^9T1-RV(8GN@1qcEjOY3Vh%`m^u%9myup^qnMlm{QsIsxFq1P8#Xr3Op^0PBhZ%aw z-=^CAAU#-%i@@%%Vhr{Mu^b1h{SPq6{V3nrISEWYDi-sTbfR*jPt0M7^Ga8kmB}ed z%n`v?0hjMh?VD&y-#-DgaCgoccrm{>HOL(n0`PlNZ!(16n+gjHGhaJ#WQ!pi{*C$C zNfwCmwUeg+lz;8yD1&)#RQvESE1d#zRs39Fa=Z9v0L<;;7Al9_E}mKmG~O;gj{vWV z-vhwcT>As(c5#`ZY7;LL5R?qgSwhQFq{TRN9dW#R5n)!&$xw$b!P+IPkufF0aXkfeUruz=oqFL?!bCgLnH`rQZ_o zvi2J~TLF8&_RsHpf$kwh&axj1X|Std04zy{k&ecPw1sDb-ug21JJr+KEcOvPCMT^1 z>IfsSU&*xJcfS@Gtz%iTeHzB36l#fu-(&JWA~MW!EqES&!>)2OFzGyx5ny-P3>z2H zZw?0_{bsRh_)eebH+xW?{pJf`N~_3F-fxyt8T-w!=rGf7I=q`4WoMdF7yC`>vV4b> zaM^xSCWxMdiIz1MQqotphvpo&CXOj*9)?t9z@(GGvDd*0_HoT zN8gTsS5mO)!H-?WZQ>ZH#hChFdzDkCwsGKUv%eN_IhfOYiWR44a!Mf-w{;JSra2Ek z#Fda=zG!AZbDk$|4>jVK+m~}mokuLCt$s|3jT&wL8;UMu$@37 z0Lk$HS^!u?pdElO0QfpiGf@P~VsQuKe4KDM2wRzHu&@i-2;^Dlg_Eys=CW#4$BKUe zBK7Wo3FoMFFMy;3b%Uv@d4@jYzPj#3>=w`stT7y{-LHg~9fm_skbypzR*_cjZ`+_> z{Ot$;-%BbRH2+^iFi#0gd;xjqJp}8bt3vu`0DS@EodhtgQzphbs-_IQaV2rgX&-{g zo!u9}ascThPPh}8dqFo}buAkGkcfL)GgkQp-OxO;DM6Q$JPA&~c>h5xUqC@luFBAb z$zwaw@&(3jU?lkZR zs9CPpZ-((`<1OC^O)%$TPFrHNycuVQ<1*aRce!F;GMCIF;4sz&lHSSyG1J{0;wjyl z0PbyIo<587NH5tg*NW>Sy_wbhu8s&EV{{d&Ns$G{+0G$1T&p+eVlTK@As?<0W)^#a zvkn~~-W2VH;#b!Uvj&bE2HcD>IRziUGr)?wJQya$-67GBCvPT-N^x0W?TysO-6`{& zEud#^W34y%Dd1UH0*Sjz(%PyP$cxfI9xG}547j|69GBz%X$3!}kor|4R z_Is*D)|{XMg`|_^FOd+2@tc1*$cMF5R|Hwga_i8v96xn-;;4 zgJ6^4d)#74OU|dt6ZF(QT7rDrv=Isp1YNMh!@SF0MSCp_49fEdqXU)`j+&TbE5E58 zwsN-`J!VYdYGVar)bh_USh3rOWWcB(rxoZC%G5g~E%St_4=2#RF&h3$$gqbKeyjDt z26)dZ-FW!tkiZI9Y&zYoxjkjH72Ew(8-RD+KEjIaaUP)6eH#SgTDe3bLH&33eI^Ur zT>(Fi-sJdkD;NE^ecdpthjcEjMCd4RtaHUB3-)e3xCv8#rRv&EH%WHAzY%XfvMsM9 zP5Yl&#;*vNPx}!ECOuiHxOVmPm<4(47QWOW}df# z9PY1eK8r3YSdN3Dg6+SY6>>TQb`4R%9s#{TA{s5}1-@dW>;_@)4P|6+FwTUV-k_Bd*c&{i0%kWSxS8jht~?cb z14ih3P_1@40rpAONVdz4yOc2pu6Jc`LfAEl>;n;y_cpM+9r&BJ1yy9bI%P7>1IK0# zdp5L^M8f+0sKFS6G+~L0FthTyDtOaU5md@fq7p6FyB9$Iti-fx89a^d-$_gcPTs)tTza)9GE z&i0rQcVnc)jHru@NGFze4WOJCG~4L9Qja~UpcOH$wxDl8T)03;3y3X@eV4}EIm%^y z13pU1+E{o#76Hu?Cc1BEL*viI@&Xm$kmRfp2+!yAKJbWA7IQ-0K`o))8{nb;zj}Qt zz~%gG5#W0q&NKwe4HAjXS7!KIh#|;5s@IHt(c=edXvN_7VXW4v*W#sR)BU2zVAlgyv)NtjZ}TZ$s#vx3+|H?Uar?Q6m^X z->kpFj=4{{1%S`>A=;*#cONlnW z5!2!#$YemKTMBdP7Z%e*hL<7yBC@92x3xqY zweqcIa-{~c#@S7k#_qHZVnp2y$JiIkUujCAE8Zd$J#`~=oiYacDVLlx_HBO1*b&@F zUfaqH(vT0y_u#G?=*i+jL~OCF1eY>Vxgfj<;j*!*46QKG6P83G93y#==1iSTE@ob3njHG%#Bs@((=$mY!l)(u$3&zidWTE&|~ z+RHb1o&h!RyHa@>pM6#lwxn*bF<;@OzS=4p>;uj=HKm5UHQqc(274J!9Gz6)Sz1a1 z4 zw3Io@`|i3agP%FN*mX5ZLGHV|4OYp0cL4zDq{@AF4*~NHQkh^`hFpI=h5cx6W$3F< zDDFwc>`dQ<1}kHdQXbXky&xN}UMi*kC%AGRRHEiSRy{kl50}tJFb+VyXD^W zFLz_(>Di5h-m(=5n~+7v|V;Y7TYp4AmXDK`HFiCw5ol55pq!lD#3uR)%iJ z;6PXPKK8}FJ1V;3jTKGI3ggFYEIU)X06Oy^(T8M8`)MnMBaiWhA}(t4?Hm4>{z4&O z=uppDKDUQzYrw?4;Ao^v1jZ?aFZ$Teg|K}V%4Uz&WOD>>p|6*mFLsvqkzm)2vs@ft z8*>Um*pn{H-ZqqdX$ZUbvg|3L>>HGw8zM6tcBF=5L^Ruhb|Gz&Z-62}&nOKJsIpA; zZjIL$t;&6+Ho5je-*p`L^yR>(4ZWmtf3~Vt%Rkw@mbwhzw0E&6CbAz#F zGtHc3QiLxw@+@TRpN8AI`vex&~)|$%%LxUJqOHN3g8fdqX24l18@d_pMbj?rk(_10h|Dk zUkAWTT67uRHMW8Jyc5xRuLei2?o7PH$5(#%TS{_kkjI0ZoR z07C;l4d)!d`$Ge;2qIBZB~ zp!X!OkAQjq2Jkz9%5dwdJpfb((3Zee0HzbT7Ql7@Gur^jXs9V`qt9vEkit|@;(H>6 zDH_Uza3q#-n+EjP=XSDZf&DhHr&XkSeM-r3_#H)7h7)p!YC26#Ip7a4VkcB{5Fd`x zOpue8XF~GRj#dR65I05Mu%Uvj_LUkgV^0ZZVJOv?s#Fe^8HuyZ!qzsKWqC;J5BrH3 zDvs_gFkbzaYcPSDYKS0CISG=l`UQC?6nR_`Djx1QSov3h208r-9GDZoxfhX<^Ergb2oy8lVRS2z}|&i#wu0%gFZ{Z>pcwW zpP-KMb;4ejQa;va<*pBcC&2d``IA?z=ehVo_GcQD%viexo>O!eyJbiJAt20U))L=I zXsR3sXzM2SxI-vO8VMNXC>VT-Pa4-GQ1ixE=-1SPxZzS&JWAeA;?<|;-X~1 zP1e_278=b(pd-8qSY)sCFoa}@y|o92SGb>=(L-4u(dWP&$aC(Zo&$?4uV38<0GHSM z5a9CqbOKynC*X4=gT3wl;qv;i;L!@aiW^*bueiK!p?8<%_2(HWm)E}qAj|8E7noFj zq|dlR?hldBjTrDu%tF1dNH1U9S_HBzZoLUWme(ELWvVOY%(uu08Iw~N&NeF{n99p6 zufx^_O#yi0N~Y3YZnlzJme$@2R1P>_?Qo<-*-kL^Uu+Wjh6NnmRfrHq_2>@wlzL&lAjz-H=% z3OLOaI|KTBKzW?y^?bA0$_Rb;snwS(uluqpX5x;J@vsbp{X0K5+9*(7IJ{ZU+ub!_t%DxQ13XU`u2Jw#guH^Go4z@5;(J_Ylnn?0?+jmT&_$ zQ8!?vu79f*`jPs$UGBQOkb3T=jfEPi>pKasu6G=aHr9H~B&3Tz(?8MrUTX*(mfLBa z39!EB5MX^@N`Up9AwEYkSQGwl>iebJX%2?gtOUuB`o5i!vcAU;)%u?MxG}w0pK*sy zz<8gyxdN^ zA{+I6ka}mZzB|#fzOMl*378Apzo>H7_jgRVOhD~0)xi4xy$YE6Zno1{-*c45sqc9q z^*!rxlg{$`&YqFeZ_CfG+~2P5R>FMP)S7>C(_n|@fx$c#pA~JrgeiTIIEB8wY z@H_VP{a6OrsON^a;nrhrtDgyv3i(!jlIAL3OS((N*lb5=tXv;`NWwAo zFaK7(lNt2gmmTuIzE$t!AHP-qp(;l)+Z|Oozg7QTNccnzr`F0SKV(o;*uTD2KU=wE z{iBO|Ot2DN=3DijX#2&}708x~CoA%TJM#QWfHr(`vZ9zLEA$3$wvo6dYIGHBO*O?Z z>qXdSUNUNGUNVvwi<-(YVypY21h75tmI-^Inz;HYA-gGp&KlVgNGzBFvFlLLp z@g8{la)dt#h8YV1*h3bXwDHu-Tc4?eyHI}N`Le{+aIvBDpzJq>9+uyYYbz1?Snz3_ zjT0%FJ!Eks29y+TD3SG-2(D8#_Te7o5T1Y0y=VybwzaIM)Rx3qu=XAIX1ZLTknR7c^ zX9Rx=z--EtlEzJ$I(LA^O_^K*+?071fbXOl>TJr$gxF+@`OX09wI}g@Y%lJ^+C2BH zcgmji*AULEi-~^BF7b!qce0$Vm`|lte*=cmI`G}%T7E9i-KY6q1Z^<~+^s*y2LCjK z%bsrhT}UL)vbF(`P8QkIeFB*5>F!bCG7499o!$#M4uM;a1v>-FyTSPgl5TJV0NK-Z zgcD~&_{<*4vJ0fF5n=|aEC4Z80pkuf?5_HJ$H6vM-X6bWbQ0g0z8cnI*sI!n5cBUh zOi^L`om?<868jTn^8AJuzztLIJiPBojW>AN?2=#xSiPqYK?S(QC1d_#W&Ci3@tGfB zwd>SDjQOSczeV2g95?}E{K;sYAcc{=H9Zg29A{WkMMdO9VDg?!CwWiiJ>qEkJG(N_j?##g77W~&&=%s<%2}|K@iOQ5`(2XtC5e&&-W$RdhnP0 z0CqLoyH{7+2PN_X_>b^D)-0;W2M3RP^fn(G^mM=pSKq-|#iwMIXW7*3)(bHwP5;lcS0m5Vwxb7b_M||uW z5G-GbS{Q6O)^@}kR(|#cwSc3c7eg$YqjA%xcW5{V`&?rTVe?JRB!wVK0MC(PMDQt=2ibV_0 z+rBLNo6SHo!9iE+B4g8TXp7qvo&$w5IM$NCY!0@1f;F3it;Ye#fXk7w=9Le)z9Sb0 zT*A%)7un@lOud-^IPkg!KzcHSWZ*Rsm<+t$24DtWe$qJby0t(DUULa>;Pnmw-*alL zGw=%T%5&W*pIMAbH&~fieI7t^SUI_IZ{MWZPv3sQ5ajGQgexuBf)^?A;V@;PhYz2o zh>ZE6C4$@LjR&D-EmX>74xw~ES_93_D>Yo#HNt9@@IQf zcGg&VGb+wQh-)|E>iZ4c>=yE!5iObX$%iv1?mxxoMZl+=L8r87m3ost-REmGfNb_v z@a$4BWmo5}>B9gb0VDyi#!+s_Y9lvIpYBREMJ9`^l$qhktfY+PZ;hODm=hm_VevIr zF`_OA-$vdb&>JCfkD#TPr@9~4r*{}AX`rA!d7vT;8H%?}-PLO{qeg>Zl5Ftn9+f0p z?iw{&Ov8cNKd2^F<2(pdhkL^-x3_Wu2hNn{c2ZBjD}@rjxDLsvOKd*4Jz zTErT|UPYf`?+H-QVKUFW8h(#H-A8LYNR`a%nuVHgod__mM*%Q$+m!!1NACL?|8e9V zaO7TbptqLi!x(S*HmM-{4knou&$Aneih*Zmz7EWNL(L6%oP%s2QS*WQ1m1WI z!EOe-j6@4kLBbC?SN_==p0VW8(i)A;^fSVM=55PljgyI*Cw=`b@Z~6Q%hVT;YHFDebF$5a- zXeu{uuU-m#GTo-_n{Z^6Y(YIrJ2*?m*3Pkw}d-G=b$ z%i$dD0jwm@5bMHQ>LkEx_SVnsoTkXtmx#DfS zP;&ODPRA=e9&jz7w0zsGwKNO0*I>k0Pa|}C556vnubpXxd?Vj}N)dh+cq?>3X^f;^ z@73@P)Y#di%0>Q;VLtOZyC70(@YgA+$^u zIzQ+tjolP!G4MIUfzsgIEe($B3rd4ya4c@ymPW_h!qy-*7_Lj?QDL12IW-{*iqV&r zS3Fr7_nV8uuuzVR!=TIxT&3FB0$bhlF~D%gRhIshZ|m}RSf8=aB6-t(HtXPE;&^Ba z!ZHVShERNEHjvGqV>9+ZCIS*F^BrFP9&~vX8mUkFeg#-QouE>x@eXw%x3o(v#kEo$N{0P6u{ zBr5X_`iyt@KLb_xqn}6XSCK7`3Ve=GaDp&Q%L69aQL2$1(hOR)+^i8-C_z32Z*@P9 ze2uH?l3puSN$ob6B%~p37uT|Sre7gkoc+D?f^#sWt_a=tq83VAeJRK`>tu!5io3G> zJV>T0EFCj~IC@)^DU~yW3qq;#n8C2OIUQK`-#Gex2 z2Jv46xIs+7=SZ6B$kwBS$gd9}@H;BWKCJIzM5R#;^ zI2**F2SQq_eE9}3eQTXM8*546bw$`lTiw6D4$Vr_>ZW3-;@93XKG_3la=m%lX?vSi zXWRSq%TC*C@O{7saCCNUbv9nuBAhXh`)ls&gdL6TjLc=6J{!E@Ml{uXZVlpL_=rH} zx7C0*ug=D97U-GFTL$qx#Fub}(xN)&l5<}%lM93Wvk4^uL19WTM)1LI;`0-40ub?9)|1x2mZ_vek-vC;O9F8@$5IDZ&^d&DJow!J##^?Ab!(ZpttD+ytUE`@S#>2p*~Qf+9s3jQ(B)Q;f(F3- zT1dFmmYZkp;c7eq+;C(nrF?hWa3~di>G)c_F+nRqPjqrI~|1%B4&@9Y{ z*|}C)@bff|p!iB4f7uvf1%|v~5Y{dGUPahU+;EIK&>-&b3=iiouq>2!UkL9chu4#4 zc+tH_EGV6ZwJG%Nl@{!mcz+8Ozv@jBFQa#$D;BfL_Zg8k|>E@diKcn&toMKIG*^IZsw7CX_ z>Pbc_k0FVfIrQ``)w#@eH{$RQ0I*B5B9~e5ZuJe!iU7j*fgw8&K!f+u;*&aI1~B=W z#asdKHH*guz}GCQsl!c%!!3jgSS-!4egKZca^DM?4=6m+vR?Z>#Yi> z)4#(P%;j@Xr3Lp-e;l9ehQ}2UfX~YmEl@|3LB9yxsR-TQ_w;L~tS{A^RWYNu^ux17 zgWXa8gj6Lfu>55s&pyGP_liL{{Cx)AB_)#|EDYGWSnRxH7(!p|w;cd|bt3^*g7^;r&}qj5 zNSmt8?{tj9au}3c*@q5ZVX-2Ybs;(gXEeYyCs#;pF*`K2Gy;rdDgfWcinacdn&GHG zj{Of;W}r$)BVcJ`mAnAypIRg8w5IB%ehEO!ofyi#0pN828OK$~QlSio-?dBmI{-+l$d*S1!_TU)i<|t&DS69b z#IH{13N|Q_syKAY*FAy@v)iI&c$laRJ^AMlwpYxo%;zJPIqWK|+zMo-q*q6h% zZPBc#YxZ!dAG;viqnZ3Qdv)digJ=#Gn|_YrKqG{^cSLjb@k!v=S951852$oowE_fb{@oUsPc(5{07oy8bN+4}ezz z*gvY--$9=jidk~gu{c)y9b>ZVXH1Sp@MTs0%o+kbhA%6Bu7QQjzQfUbn0?s@KMK9_ zvU1#4C?itkW#wdGz8_U4_(E=oD~#yk#3EmW^B=(6C|83@7{{sT^{8XnClTHk%Cav4 z$R}_Fz!FAAw!G+6P+}Rmm1>S|pe%eIRTbJE z-TgjVvs^9muS!hu+z6Xp$1fm{z6ABbL&%!%0bKtLYDXEe#`70ez>gs$?>znjOH|B^ zE)pNdn+=quNC`wlNwaT}tt5FVcRw&MWlI5gauK`;65h%gxZa`^q^bb^13(6z`_;M< zu(_+an^89ho^jtnHwT`#14t+JzYRRks}>GCW1xar#;noz135VKy{8EY*1eE{r>6`N z^q`fEVBGtRk|EwC#gHqBPrxn6aSOu!1_$1nQ;oc%c&fzOpC2kPALMAQ#M;=Iq7%p| zB@AHYLYe2)-q8MKoVNq+`B5pSu-pyYxw#0B4vX`du5pF$fbs-a_#6^ksAW=n#%6*{DJuo2q8e~BD zkMN|r05S+v0kD=p7)d{&pvmuT4J;Fw_Z9$)0C>s}{P9JUcMpV=BE&A%2#(?0`zTOY zs`;oPZ)>>hLGD+Cg;OX@=*loFXRg6z+G`$>yul$)amc>)A!M0UG;>InJxDdParnWA zGJ3n4%CLg|rDo+JoG&Qz$EfNeGelqfV8@b2LdfkMa)~qk3cRgkNz~UNytc!8R>z%| z@3fM?MD1hEgH?#Xn%c`rQi%wak2rq{j#)1qaheSS9-qeyY%(hCgQ_HWKD4=$0BhKk zOhogZN#w})&9mcS_}(-(t}S{H)MtK1K|cu~>=zX6DgcKFtOwva3g8U@xdh$=Pzu14 z{3I^qck$kNgm`|%sUy19AdRIE)VOmlajQ8Xid#kerf!w|ySmj10O{lvx2p07BA{D! z0pKY^a3e-Qw|W>M_7|$0ZuJ&6mg!d0kbh0Lm6zW^35O>IT_x~@lBIw)h44l|yOed% z>wFhO$Q9jco<>i%>R?1A`c##nTV+YOd08hXMAvvHs&cpbB7|J%kjvdFPRmKGZlMT0 zbc@4V?pA3^cH9b?f?q~A4R(tBMwE6gOWV~qmu2nBPOHe0$D+?;vFEYK^H|(IZ%FKt zDQkmu&9ZB0t{jI;dk}$k<93RM^S;Qj8qT9&eQ;amh(b-fOWxRP*?$NQ96jNdHqzA~ z%xyjeju4LY+sTy;i`;T$1Fm5(*L@WxZKdNUGdhn(OFa;X$%|{ZBc zT)13$G)->vdtI;#Xl_=nJdVNG^xqwcdXZpKnycA5=40c&7vSTrRx$X}jBFPr$h(QX z%Ct9t6m|RtJWFoqtS0!^$AM3^;tbaF1kSw3rM3o_*AlDCn+o@W#KVa--0YZYoy5$B zeTCvnh`*Tzyr#VMF!L0v_##|9Q3-dOMQ}o#l8fC34uA8{t-_Vegt3>VMEkC=I zNKHfmO-Xd$8x2z)L3rYMSiryuOM&sFFYmJeW+T{J4B+m+aJpiPkcwyK?*I_^$fVa( z3aS6V0PjA8{tUjHY|RSo1>i<_xpq<{zJY!OEPh_^IbH3@1tsex3oqpQi}g2h*5SG={f;zM(oxY0S&+ zvowa+fL`%8-jkB6KuM9SKszExt^%D6z>~NXtLfmD>pvNSqmT&N%^+U?`5l6CGBl%@ z8+kAw@R3Hxoj_lyBF^=nawb>SYQ%N^QgQ**#%^+F!ftV$+85PzIsix~Ra_?-}(fZSiPOoct*t9-|kQIO^R6@&hPEW_mfibsHD z{G*(=YJ*$=Ub(+w8>n)BMP;Ql)o10dJ-`!)RW#)Oik2Ew$XL4t!WEVKD;)jK{S~al zK96#&e^(at&9rw67Y3eHv%b=2<-5)^5v<$iVVKnIE3I%VtsktbK$F|n`$H>e!1qp`CTVGBB1l$d)q zhG|^po(-LPiX+&?yK&P2*)N= z%3a(lR=9DaAbdmBI)KkdB&RgR&XxOTi6><2^0kG0A$)XLxaH?C z>q%8sf-34xuH=K7?12cMh8)k%05G6ZxHTgcKss5xBLP*82*-Uw07ep+3g9;aa{y#l z4!80a0`M-!-?zZLF97Hj8E(zo48YGd!IK(i!qbQ|qVoAT$o+%xx4|{zB!Gd*#Mm2!V zhm2A@C7?e}iA3-Wp+p%aS^_Hsmh*9l#5A!iaTykzDUk}E?Ue8!#G4810woTHNK6-r z0?^M=!VjL-agZpc#8_YfU^z!aB-l+_8Lc&>n?5_oLwXwcmxDj8T?MLl9w_fplf%#S zYnp%pZq@|EA%{S^JBS@Nks8mXYtAh6lT9zqXZZ>iNCmUH$COA!-!3S0iH=AOA$);GTpy+fi$fj7WYT>#m_P6YI%?8d* zv5V0+A-(rbER^CkR?>iM%y~e zZoc1@%-JFhWqZ@IRv#33rs>UGA413s95SWnl7T~}^jb;MV`WN@mGoS52=%JORp+*E zLMCMr7nQRr$r5vN%Aee!ywhNKsS(BJ{=>xJIMbeerc4{wfKyGl!s##nkXT=>#r_g* z@<%0(O={MLQ?+M|e@N`V5f=-Ni3RQ};6_8ShTuL?X%BpRR9*B2$t!@@!u)VC#}$87 z`U8)bK;SzR7sRqN#PCv^!S1Q2p8B_>_Di6CI{Pg3{sQWYj5tsej`uXe6YIm@3IPlt zFdM+@1nvg#2LMkA_|w5W;Vp!)DVg$8d%SMSO_4kqOA8AD6fJ7ck8J7Sbiv3zN4-elX}Wv$QH!meF?NOu={DqYkQ3$iA6}( zkVT7Q_qXl|-K3|A7AN=%qiZEWSgRj(I#SM&j8IH+U>gRbv@Pe5GP^JkH z^gSMKl1=!kGT5zgm6jqeA>pqO8r@e!9IdUT_#zmj6u%?DQcOz(z*5`=L&?@83}Ed@Yt8ihH!}AkK#|}+buzoaa7s`hG3ryF9lEtzIr~upb&PWfV z#waW>Qp4Hf`{q{E8qq(fRZe7E!**irrc~L6ePN2~3nbgsye=~GTTrWAgS`0_zPlfer0p1?9 z0majfUlMSC5CxZzn>5`!qS%k!P{QNUr=!dphSj3moebhxyb=NYL!bqKiPvG?cmn`$DzWBh8)hP#=Bk=v6sh~R=ojll!P5xe3Wn?j z03L0@mH<@mT3}6DLXNj7Ui+nqHhDGVMnxTl$#R?G2{2gpV%0hhqt$;vLYeb$n-%D< zVzPApq9XM7=7<r9>~YA=+8DBSCw5nkL-3=HaSqesCXSBHN@iR7 zh(kWnOUb_PLZl`3vrg>DVAhZQYJ;E2OpCUezx@z?Q!8XoHvrX=0Ne~V=K-wHINXBjrJ*&?-SE3WBjhx>Kxt!lMlvR(NwP!c%Ttb#>!Ezcb=oFv9 zh=M`w5Y+s7NS##WltK%J(HB^%H2}*IL_HiV;tAuG%@3-3Z&Vp{h$pNAgXLSP)cB`N z&6d5nD1OtP_klHl)FVZ6^rz_(`gnaB3GqZSVVx$!rK7SD)LJ^k;itz_pqu64n_)txoX*Anyr!-k|w$H zERd_=GAZr8G9HeRlOVgAiP~C~>GL~8@0!yPGX*c&Rd8*+0mmELVJg5o?SQjcPrfnS zyrPqvz!n#$5eCY%WxP<)R}JLOtb0NNn`yi(Y0g^a2|5k3{vs&tqcN7!P47&A_^10-g98!mQM&R&H~weHS@GdP7d^pI(F z(vd*dp2o;XAE+H}LPp*R;8y~Z0X*Fim3bC`b~mFCSjw%xHj=5xuGseO%9LG+@JhEp zWD$T-0Mbd#TL(-wRvei^gjUWz)(9fpSP@Q!$;Qf3$YtzT?e)~Y1K^d7mEEAq#!9Jj zxRj%E*VW(&{G`Dl8!MHSV>e^%7C59Fva#amzhq-2Nd+$1SQ$RpiIDlu_6DBH=p&?vFvh*S7jBf$M!KVjNy zwS1OM!=NfA#?y$g6_*tTRbk^`c0vYKkq8-ydvFy-lCpwALxrau$C1OTa2%Nu&Y@U# z6&WX9-?<#F58v1Dw%ZX!iY!g!3!~NcFhZau&vGvlH9A0hPNH>=b+}6u?VgQwlsMaD zkzb4M`tMCuh`1G%s0Esmo{}ZDq-s#Awt$dgN)`~8>>DlkA>ae|F>3>^bxk=#E}EIS z?MmRc3;o(oSUfokPf>g_@R6*kcWCU^v!La=vLlg@_d(3Q0OHM^0h9sAC-5VH4FJ-~ zn^yyj6RyG^udJBRT!69}6WRg5jOQy94}Nmf^e-AkA)^@Vn$rvwmN!k`kp`tN0a!(V zH%(XVf=V0ljmd`|`g|Fi405ylC!orU#AgZcMdBv60pN?o9s+!km?1t#GT5sA-@Hid z+%1jwCXgTp!)lN99GV#3PB4v;@E$rI*IZkF;`xE160I$lUS~rCI#)83=Az# zDFn_zm%K{+5me+Jl+^#As z2NJWdiN@l*N*sFEbZgBpHiL}Jk)@xqnR47FVJ&hZ+x63R$cnKDx4I!Kh68wpzyJX4 zdmvB9=Di!(T43JU0Q&a?Pzc~<0#5^|nE_xefENIG{E&DX+q~Y75wa)~U0~-de8NKg zycksXGga;eL-w5rF9k!kA3&X60Qv#w1t6Vl-pRn`0<%9>;lI$O4}c`o#Wyw%X}I&o zhMYpjG1tFLy+o2T)@pXXtIxHxY(Fgf42pAjRS(^B4im^}L&mM&8ZN&+ zf1{2g&~b`7`fDh4a1lCVl?H6n=hevK32%U1-0Bq#4PD0~0jmn_l*CTcKB5RM@j$~R zWod8JQs$b}?Lx&C55A0GM{9~$Umi7tsIWRZWMfY}eLuXfzH)Jq<$0rAmNoHKZ;1R3 zN4_i_{=uK`ypn@GaL6K^uT-1B|KYOgMZw`5UKw@TPC4LEYF_UuV{TjBAFKu!8CqLf z^i=iqnLnB$sNEag#=EV!Z-c&XXl?d=FZRI-`#9VtH>@^0jbT~nGT0*Qt=D|6u*xE#n%8xC-Y2-3*>zO&>@6R;U?mZnr(yh>3*?R4eI5-T>HV$!i~gi z0^Ce20FYKu8xSPj-Ri!?t#kG8MpW z`xqu!Je{QBGS`AfM`_;CF$;tbiz+3$)@b>BN;c!sf5*dVKJsxVB+Uz}v!v{wL5}3S zsj^NZkx`%lOY|8Ae>75aMd~1>9HJv-k5~8ThS_#KNRYsu;K7jaHX4puxc!EP55g)y z9}_Ou^)inv`%9(%feG_CL)FZ~=+vIBmhrgyvxXWKwjx;noHa;}X|rTqS}vLkELX7+ zFfs6>B5X;lmNPoTsUI_y(zPr}hr0-o5vR;r4a{S|?kA)s$$<08+T?D>`ngD$Q>1Px zEcH@hsbh-`PZ8&nOKQt~X1iGzm)5R-4aTjTeI?5TDxry^qZB$bs}uF zEeM7jH6eNk=2yXV)M^kYiim6k)vces4et*>>tZyn5-4cH#nJe+M;d`;7@M2|b-AU7 zwJjQgwkUv=v+TW~4j77B^euo#0ZjN6fSkZQ1K=x$xS*2$KOq(X=JFHj$kXF(f@hCm z=s}YKd;%b^BY?ba_?y`efBx0@yP$FV;iT@hwZ|vp*bHIsCJp3}D5J=@82m z75+5xcSJ;ra~11YBcS!dXbRSK4g$kZCQ%VbjH%WO;Ak8+`g&9@PNE)x7MVnCC%{Qm z{0K~XsJ1+*8_PWGo08_(8U=}e*on(oDs@j zz^p6TOl6$mkXvRrMF7%C3|^HqQze`UPUuxha>T<^0`>#YB=ej7P>{1{7u zesdhGT9fUC%E6d%|pDL!nG!83b-_6|E(2|IKpX&J9ZXg;HwD`=jD?*lAdML3m$>Qx zO&VG;88GSfboN0_9Xs`rMr~AB&E8t~eNN)pRUt-mwLcRm$B`a}K+IFX!mX}vVFe|! zo3s(uFD69;e>2YpHrj}fZgN|l52TTay?gHHaI4ek9L1goHaX9V?6C(CbIx%WYky=< za&jJX7c0Ai7R~I&UfrPIL9*Mtz7Fac6K=k9ADO{n_)zXM8ZZwOeD*#vlV6YB0;Jo; zDv;_ma1I8F0njkSi0sXw|2SZiM~}YUiuABCV|I00ITXBoUIO|tsNMLP*~lzfmvuYP zZfMFP`x5<{=xykuBKr~b-Vtt%U4&(^$faePDbu2_$JbL7DMMX|wCCT5F0MX;@s1zj4W(;KIc_!O10ef_n(8Lr5NhA^`sZke&-6xg5O7 zU99H_9t*%+4qi+eS5iMDjbCNCdMp554n7osuS9KiE(e!2OFgd=ydB(A3N4=?9o={^ zIC2>izW~zd3G1*3z!$Sj*f$8vnfj~o3piBx0y+0!WehlK!e;8TNqa}voz&Gl2eSx& z1s zAmc-1Y%mUtX(5cPA)Zn&9tbAmaWeJ;W12^!&eo?fP3V(BN8|C4QjY60p@WkEAGIuH zbPlaNv7UsNFaZm)&LHbnvev6$S;mzb&|054L7~|c`kq1#jp=4`?CaGJIEpHU00?M# z`paP9&B3O@;93Bx3q~xg#FsWbI92OtSm3rkG8%M&AX-a~J?3$tV4_vfBdAo_o=~ad~^C@(e}~waV~lJTScXKw~(JQZ{yETO2led>~e{o)^Gc-Dg)u z{~BvXSbnA4{fDU$m2%N~?z#mdEViEDVi6^c$MOW4PemUADleSJRS|O5xVzBR82BsD zMzZ}Lp^8)CCUMomWM0v1Lbx@GGY#w%Ay}svg)_aJVmtt%PBCy17N;08*D!O8RGDM^ z02Y~JWaV9cj`6cbS_JKwW9;jQIR;^wV{C#@;ATyy&M_YQ-6VUpKErRuP=RxdqhQW) zLg|$<$0&ua8_2>rM%+ZSI1G_F2C%1DrWVrW)qe z=X`LPIYxGl6XvM3U)6N7b{qsF3A%FlKTk2(E#p-j&NO%tk@U_O%Ubr=s*TQkT(rp? zBVNts93uf9fk;B<7^zC;9HW^bGn4F58qPUJUk$&^9D~09kg{@?FhN-1&*gKBSj`I7 z(*+K>e2&pd$&@a3$mMg4i6LZZHp=H1SPTe*ce}5RF_%014(XIghBS|1pKSI1?Mfi` z#mE4oKozY#V|*nICG9H4!FRcR=)M^4MtzGgv+;djj2(xjcaqLQpoI8C`Iv*qZRhvL zaIgD!;3@oCxO;ZY52z2BMHqp&=frTepy3pAEcSsIuFVa(8_?286d{8W#TmZaZ8{iKK zz8Cl$*P}?I``MV}VX}7hRztG?yC-lqoVN)HOT8Wzlw$__rfA>PP=~- z3(o`hltAzi3SQS8f@g$r?S04;*~AWkNLf-;keDN}J?GXI1@cI(sKCnm2G z;#dq?gE>$=AHZDz(kgO#SAnvclrq0>%=G(XcG0$95q=xArZdoc2G~8oye_xPdY?cnfGTrAFC)DUutC7QjRD*P06+T? z%>%9`o`6oaAku+JJ7N|ttDZDj!?S(S$anH!ecNuR;XEzas60H-TEn@Z>FcSrC7863 zWp?`-O%#{@?lc<0aTOXDSkZC%Zc*~<$bFwB%2#Mj4kXo#M59@Y>RYra3L&v&4gH?Y4Z)h!Jy$c~q>_}qoztcY8LG8zTTqMNGH2~|0$EV1(0!Xi%Ei5I^hYWAV!6yHf0kDI~OS5W0jjCtWFvWU-#*hN_wA2^QF7n@769pFll%57Jp_N| zefzxtTzcRB;~KI3zUt4xtjScbp4$<3UZe91W{t^5dzMonp`@MC*~j0k_A~kc5{~THsv~&I9Yt1P4+P-k956oGUVx@d=&bZtC@EX^{9e;$2428FuWjCTRMXsB*B z%NiBtdpP`w1E@&TW=7AQ?A46^ka9D6E~o`|YV_`6+cEq_3cT&Ci(T?nb%7sK4qvY!i)AMMDO?@s?m$(QRk zeSfGMbJ!2tbww^J?4VXBNy8<#js~a2nD*7X75#IY^yqEtkHN0fd8 zkWP`%BT5A`^@vj8%*!27s(0SloA?T18tl3@6HYHjl$JoL98n@5N0gSLXKb(R)AiX8 z4U4Rk|OT z5v7?IOiEwZXWXHGV7wers=EvW%8K;zBT6@eEJu|50A!`!;hm+rV$OU`U0kWBF3ZPz z2>A=9^4~|4%9!KGZdt&e#VELd{|SKd1^n#4jhf_5;4Qg3195NxpWL#5Uwb)9oJ2jM zgz7z2MVu9UJ)*=_9bNA8#4CgOZa&^*hol(z7d*X&Jw;Oi#(J*!Eu`+=0vt@6>66B z2}@zV^a&RUuupib2zf#_=@Z;5k+D3Yw1EKogqT$T*e8r5z&;^-HTr}yNQ~`;OyLow z;|P%>N@twv@v8I*^}!&0LWgG%8;>YWAizFhEr9eyut}frJuut)%ak7bgmWlqW+MB9 zY8vkJ37pKM4-Y+}v|F?D7k&1mW$Y80uR(GBsG(FSeZn7V=KtI$jMq2|_4zavvX$>e zg>y8N3iFWV8J}ywpZeSf_VO;|Ck?&yyb^nm!0k$s?xDUGD$R;RiBY{%u+p>!J1u*! zva)-)Mp(6bXr*aoP0BEYOS=btyU0#eE_M&2O-$N7R8ps-{A@?QynAS*#k6VH{AR^xC8qE0+}gA_T*UpGD+4Tv0* zs25L(wp}5S(!UmTw2B{s3oBACMgUHVAB`E6)pii5=CaDv_?sAAvcb9<%<5hR+Ys(a z@zUY=HMK{g%wS!*)Bo^7v>Cvf4V%4o{Ij6xX;mKmnYwNgrabp5>{uS?X z8#Nve{JvRVm?=q^DM|3Z^*U}!(g=%Le+uId^+EmFkMQa*q1x;OkOv^0)R{j5^OOMk z08HNBfmL0P3VIg65CY+E;BXTFkF^y8O$puLMIoX>{s-g_)x>;h?f1FM#J@xx=`Y9?bXr{E{`9ko$2Q|*Y0>f z-gM8p9n*Be4kGQ=5%njJ#(QHe74GI1}z8A!^tE28DzKldi0_e68i6%Aw zDqzbhn-qD<5aI^&gcbQ;l4Io~-2E4BT>aGWa; zzkmFq%#u zvbf}K7xXe>F&S2Xb3HusFDaT0jGd%(*T8lxQ_|g|o{w`asWtCNt$7`_3N|XBe3NxS zvl1r{NN#kP-h&?>Fq_^)T}3$eQze|I$`ImF z2Ij+_fsNr2-7VQ}`>Zjd)h#3Hz-vbNZ*DzAf1vFXGt`Jqdrpb&!t)RvL#5~rk&ZrT z9ZIeoO|3zVCcmSQ|Gs0AYBc)*C`a=-PVi_hJ0b&oxWwFGGQEdpbqT*DSq%WV)OMAG z=duKLD1QB@Wj@|Ec_#Qhj&k==u*rqlZzA_5a@ijsG3*5heZQ*1@qwIYROSjVL7F$y z+)I=3bEyh`j2mcdI~=E0bGjn-`yeRIiA3VxoY0UM^&&j?9~FA6nsaqvsAL47teH9O zRcY`AF?hj(ygiI%S{nt2z^iobQT6Od590T|ko-^`y zQ=XTa7yCD8p8G0GFqivXpjt8=MN3E8KFcj}zh|O`?Du9QCNWg@`;d`q>97If6zFX=JH;O4Dqf>XuM&PDCSisGEm6)N?;q)Zg2Lid+A@BIcsQsPL>pX=ik;@r3Hyzd6BOYkLyY{%U-6 z`x}iMyrL1fWLH@jyv;*NF*xo0!-CV^56Rw#woBqL=sY*GM*_0;RlsZ(O9V+Z7e9xhM89M8DbvWcFuZ~ zJ^UK_+fxl?f_i3e2E=??PTSo3)q=<#=kK7$vqkRp_$~v##*+V}kAt5;Q&WStDFytZ zQU2qMDZSSX*gZY2hnc=pwHhLHjDBcJE6*{)OpnVj)85yOFw^7G>tFo_)>9lyMApgE z*_qgKL>`b34*SiNUo_P7IK7s4E_=4t$-jyIMn0*fq5&Bd`a3AesL&sr;Hc2#H=)pJ z3f-%oi{@Z@Mj_(!GoUgm)b}kUI4X1#Cpap!mJ=Km;*uPrCihrwhW~$!3dJ77ROc_Q zJ;sf4ROn+QWK`%m#qxLR8TnyMHag2+TywvT0lpgE5*6A3u#5`TBO#+g2JTTsE8=nh zf{;-mre(@GuK>Yb{&!SpE?Dgeam%RChuj25h5G#?G%D0x4Za_^k;m?4emN?{*fJ_~ zE3hXqFnFyqN!7R_C}ggh%;A?cCj4c*3G^pGNydblKw#-MRfn~fadM4jIVRKyR9&6% zb!~;nF`-ZOay=%LuK*kqYK1;=1%3N3uP-pw9DZRV|6LUm;s$f}DREsH6JqOb%I%_H z9JyVl(+);&uZ4BvKki-CSb3WXv5A7;R2ANVo6^@}t75k3U&TMBnD|3Ie@6ecxVgq@ zhDCn4e!@SE(+oXdj=cOS2%)};pTQH$9In2JKR35oQDYXb2QhR%$YSpn7Q_GaYwV_i zUsQFS-KBA0SL-fkt*MRPzq{M&&y(OpOU%PAewiEZWzo8`<8k^O^^P&EJI5KK--W4U z-zZ#FHoXLb)O}7a%H9ERjthyU@8L^AykQ)#u=q8O{AcbF_8Yn&H;%L32R6Unx*Un| zS7XXe_~uaMMb>6K@|s=m*;vbd{e>GirT{%D$E6N zuwy>x-p0J~4=uf-;IV%LZ+*gU2T=ad(sodmKeTj_dHYOZT~N<|GjAtQ-Q@UM6`3OS zHscKnGd@%lRv?k{vqB5<81frTn^e`i)pIIH$X`*~jhZIMC#v^`6qYdfJ~aLkgU1^} zX{V$hf1c?agYaSoMN$6Fl4GpO6{%sB*H%mGZjnaxC+A@8738DED)q(Fy{F2 zS7AxTSPn?eGzIxH#lVm9K*o-RklcMN{ZG+@{R;mWOFu4*0FsRP z3DnPi2Oq=1ncTz}XbCT4By3^d@<{L|W-$;ZaiQGA_=7p##5|20{^Zu=sA^^|*PjxW zfmY($fj3VV`U{ur=KG%=?MiPcEttWg;K?v{emhQSxnmq~t0YVK$?!u<8SH$Xv`C2;r~ zL`AB39=RVR5N>4*;syK%F7-9>eudR^3Trn^wi=EchiW-E?xw41V#(TeEu^+9Qmz4h zg+DA>Z=ezEYo9E}8o;me+7+2FA8YDoxc3pNC*iq_qDR&f$H0 zZ2zV0|4L!BZKsol?f(Is$|*knJTTezkG~pAPVYQ`b1tj;e>S}{zC*LO=R>)Ic7Kd& zCgBw@G%;*7fYR>Y&P}o1cif~fW~%33xV~=logH)@3)C}*L2UC)Ifi6{Q#Qoj&r+0h zd%p}VmlmL6(B40x;BPWdeZq19l=l8@=4lNqj-yFoe4(EIVYd0V_r_gNC^?@gP>_KT zV?I{#J3&1=bMtJiO%9_g%M@q`gZRhv5O`HZ$JBEQgZPK^Oyk=rJ&09L^&@%((-f+1 z+YN5pwb#Y=IS5GGz7Sl?NU?#Da2!2XcKtR0rCn#NNeq#L{a562eo~$Mv%yAm1h`@m zcMZxVZMo6%F{U3E_F^H##;@Z(4PyH1xQ8j;#;WH`17+G53MIz?1tl9|jd!YQd(`t* zR9CiskCKHU#=98AhT7!#LV= za1Mvq?ynV0+V1VD72S4EP@uW$Ihh3}ZTA#a!nQjJrEDzV{uWGE<+|-QDQbpJb%zyb zvEAFjnY7&oS_b%r?S2IG%Gq{L;sR;6PXSfWvEBX_Is8exeVuAz9oL-_CeVVk+tFVt zyKP5e5<{ikUTWlmc6)>(@Mm^AO2PiiZX1JP=r-(j9=FVPdkdNmx0-b3RZ!2Z#E<&2?d18whJ!XU+H` z=u6%7N%ss`*CsFLL$^YlnoR3l)eE!aU)WtpTRpAwK8SrB=jB(Zr*-}u^;U8|mp1_! z68`$X;i;ETKrmEwf313&r*|$Yf`2ei<>fufj3+QORx~*!yE91K()qerlWF2N(2P0w z{?tZ=`U#KjjLx5zLB{u>yc`H~d`Nu$ZJ24Mb))qz%_?;maARK zPv{n}c3dZ8StBB&OG9T&+|Q5;2U3m7PXGm4uK`PH{Q@9JZ)Fn_lNc(s{&6Fx0;#x+ z@z*XouS)IZ&Ay<+B4_0?h4CG?VGA3_ZSbsogNbpWoSA`Oj%Q}4U*ycpS*Pk66Q=@t zBUkX~j(W4B)DtUs0~6*SFiA#bY0R^c7=JaUH0#=GFaG z29F=B%twZL8Y}$Asxi63XUs((H{Xih2UpyGD~8|X-p7Sa08p;DUxBLJ;H>`*y}w3H zu?Y37<;HoX`wmc($o>sEkA+=ePm~g%h$cA5+~jx)}vVQ_mj_nHi zgnFixV9?~MzgLy;s-J*TUa{6-)qhx(%T-@)Yz$c$s(}UaPE?Q!q!ld4jm>oCWrz~n z6^o?&alYM;pj-m3PEOd#I>3lbi5rNpv{ad4ZlgG}J7Z9Qb-iHeLj zK_^$P2q>uovdM9aS}lxK<7a?NcLSVztAecDiua+Q6k=wwU|au6mwF-UHicG}hxds~ zG<-X|WTrkH_{ukafgV@CU3?OsW32t6={%uuiK(nU;VllOXpd3coWreeZYt94w2EfOEsY(rK_EJC`dQGFOubKgmaLx6A z7jw-pRcb)9Hv_Uo*39L1>+>JW=`GZPoWiPh%CDA$Rqf#?Uf9Yv|8x1b1Nd+4X0z$n z|B2aF33VrEcEi9+n({j-{5{XykqXRjP#R}|A5~4srl&(~3+xJwk5CGxDJ7KWDH*2M zUVi7#*3EfRgNm$o-DoQnSM5xy1*V*s1`2jB6|h&M*x%{9L0FxwXhGy*8u< zW+Q4G1N?KYu>&|yG0xwV7@2B0P#lJ>Hmp}+8MN;)pqCuRht%R1Wdd4!LMEQ5$X%jl z3=4b=DuCLbC}z%m3Qg(S|4}JTxlcvwSl9KSZhBRNcU zq}^__>6ihLdahm*#9u0!sgQV-Yg7oZODs*Os1&L`deLV(b~Wz$nqsS{9v0Kd3BI7wohjZ@R<9qtCwEVlUVwe% zbkP4+(TY6{`Zx4QSc!=n-a|);z89BXnyw}=$`K?m8wC0*B6P^2X&zaBVV#(*Xzf9@sNUbK2C1Vc-T?GTT$bI4 zTmy31|3D(lg2YEiOy$IvNK_(G`aKeBI4J(CqV^qXMhxq*3e?!${sc(ULFjZ1$TCnm z2=kH4c}rFKGY26f;dPTK6;w)1konScN-hw-v{!3hO~bc_)cDT@YDAB}a0kwy_;GHD z%d)>l?sMcyK0_j$=04U-4%6D0AzHBV9knc!L)MA$uwy(*em%P*uLVA9t@&N9s?@cPehthMRJXTKv^#ql>1T z2USh`tkK8)Ddn#wT%^6vK<$tt-Wl^LJG-_;tI} zvkYZ36|7K$!@qD?usbw!KxLLh;&(p9^?H?Vu%XPk`qKEL8G11mM}2*9bXOxdRz16~ zfqK?Jdp-kaOOvh|-`t_9kuNdpQh=&UEuaseDR)u`c$NV^_K5)=skov&P*Vf^xSEUX zn87ExiC5Y=A?!aW5iy?+DnwImMF{u}1AI70C*+-5rrfZRQ5$5OQrM_vH}W z{+PqkjBLvZ!9Dh)>Px{N3YUHMTtkX1?&*3(d890*oV!j*@gz)1rG%;r7va=?S_tt^ z3_0dJ98!aaPhG{oXHE!qP^>UwZ2J$WI;J;ZgA#l6D#wrNe5J~aX^?$A5C?@r{VyxX zPVm$UsB$113<>8%DIMfDQAjDgXn?RlpYNu#Q4fb|oKbg^p`-=kS{=*>^0^5rGYjpw z4cv7f^pZ0kl&Lj-Dmr(j!eX`B8pQfu$1>$E3IRW9fQ`9|?=^;i-!i~se>ZAx2?2j+ zfcN~z06!c8Zd;)w5&Y6aZhZ*YYJgkb!1j6wc!~ku^Q}Srvk-8R0gkxD?=-+c z9m|cr&Mf7`zohzC1Ds-vMD7p;X01CR!I&ksAb4U(?JtblGlJmUklNR*Q^VZyl9AgL zxVztM8YRK}R*27Z&ZSDsQKZzI-LERJme0{E7e@gl>0^qjlEaW zC=AlLppg3SF`G_ZiR1}kX^1KJj}XisuEgAMC1yf*UD8Z5a=lan4r%8uQ{}u(Oq1mh zu~3UYTTwA|0^Un0tk_YR#RyZu234Uw=0@%dD#IdK8>ITbtjc*+L+%}V^w61-dxxTb zr{gl)_3SBy(UZgsWC^2&fEa!*m`R}X5k5g+ZXE%ED>vStY-c2$Z@soqJ<87n#SPg)sJl z!)dO;eOfp~GD911GnX1)JIegZjMAC%KoxGRfqTO(D9u!*V^wMEld*^hqkZ|tv)Z9XVjTK6xVrPlm*xN`;;7{9v@ux>NIqcd(`od>OmN=2)cDYMfxzfVkFls?$zkq*pr?3b!E<$9DJZ=*}hWR(6MhtgB3^ph__xG6Q-!Alp1Kw-^qwON27 zh*4o>j(`rBYn8efHZwDT9gg|lb~^4JR&xAhE@wrqZl{ZUomx0#uirP?>1E1%U^uXz zyY7_U&gY7oeITH1P`$p^l-VDfA@hpv7bTWq@ml|5pvlzVz`Dki`E6%l?dYD0B1qwJ zomQL9$jaYd>I?QSuFp$bjnQo{|WGC%2 zi8VG9tII|umOD(Db#T@r`)dM4m_1D)w8o%FPKgc}%jh;hOVX?oZQa`;Xn6)2yvxk* z@!iBow>CqfncfURy9-59nfID9A29>#VQr1X8v8~F)>8&CoPK5QWVGkCeG={1YawXw z8EE+aU*?c$KzmI)p`)D)LDOziJ!r#|dK}O`*1nTydrpL)4KUCi2iom70!=e_Mj349 z-$T%*8EEjtGatnah@59mlW50Y4MFpuNOtr`Q|4-1hls2(=jvF;L$Dq|krb`~v6sgJ z?Q!#+5^c{bA!sifXbXXM0cI=mY4ej3E%xOQw66@b^+0P2I~Dnk`CW;&?xhg4_M23r zcrj1rKQKEZKf_xKWJg~NK^tYD%>i0w7ofGG{t|873n6IPD3To=V9I=`Kd{EpREae< z6l;S)Y$AxALXbJ~W^zlkPmY8Td)y#aW6G??#EP6vyL4iqSZ^6vmra?iuV!Hho_f;PcGdlvk!W6oZo zVG?c6Ga+b22HIhueTRiNGBs?LMEm4vg~rBu3yP%7x|lNCV?BirS$~s3@NF|}(H*K;%~aGMW}$V& z&ywDEAE>I<1em?2yZ-_fv0SRs&DswzTrrz#V4F2F z-{VWUIBMEGns)}Wn`t1HMb5qmx;=KP>}G9Vd)%+=#oTL}v~3T8KR;fws|`bgy++-K zELZCX^WSf=BDz^ynr<=;Z>?9`tlf#|*YFO1@2d0mGg@lNJvj*95S8L#zK=r!1N#{D zK0BPaC-}q5C7B zH*%e@{*7!fayMaKk9^6<%}4)6{>{k!gfScWiIIcVF(p2CZ%@4sz1t%9ypel;Hgfew z?iHBW#0Dd`WhQb*jNCX#BJrq^`wcph_=1s}>O}5EBliT9Eb*9;%Y?QjzGUR?gd`IG zX5=0if!xbRPJ>($U)6I}nzjRckIK`dqwK&(@d)W3P!P;9O)H0jjl{^vp7J(JzVb!l ztiw@*rd42Q`@LY+5%`!&!WhC!e!t@iVq-`$Xhw~I%c=hc5pZJRH1xA69FC_+NK`X? z2NM_!gG5Jf&}n-a`cAA4IF6||h$Di{4d` zIf=1KnxNMMnafbrr0F_${IjAhWOQ2FHSKR;abzY~)wETtSkpC)4_|dm9tLLlCb*X) z3pI@oX7sjD_z=9lk#0?UfD8H8qgy^$WWPWVBbV!KbNr#DZH9h17B>l6>x}**NELwj z@Uup=)2m%H06MpT-U4kO(N>3cMAV{%Xi(_WzodM0O|AutUpb?sQiTDidhH?U|D zM)*6ufgMI=1}ufFW8TrJ@^|lAx3AUJ-yQM~&GXxy_(kNF#kAw5C$?pT6G&(r(DUr~&LNF?17IQ^r&dV|Y@ zbmefMdlm?w-zCyCe(9N<^~}q?Lm_f3?JOO>NfR6-{w>4-aXK-+O%}!D&qnVs*88!8 zv`^U?0f8KNKxr{L-UY^!0teuq*uV}NrUUrhr$MWI8#HkAR5h77_OELUSiBbYbaVzr zAc0GHgjnCR`eO1wru2OQL*B&_sS8bxBDbhdFdifx%GOv5dnA}OjZahcF2VL~VGqEm zX?*_NV)k@Vpq*ZQxE;mU(?&%M399})7FAuE_79_2Z{C=0l^D@}#mcsS%Q$bFO(tDG zteA>vU3Cd_s7YrBf?ReJXzF1I7Gx#VWzc9{D~20*Ix?WEG3k>sb?D9i1$`WvH7-qu z7BN)H4uUv@Y8_@l5Z=(zM`4ghPlud$220Vz`&bokEY$Vt5Cf!MK`?7uL7E-Z0PqVh zS~{;=JX9t~AZ@nBDz5SCD0Rj$@5Z7nHShQ&TAz13PEosfuuyf$EKKP^x}xwqSArTe zA0E`0Sk-3+$axZ+EKv>PrHnB=TZe%4rC0=w7Fbc+0zC3toi3W05A#3f20hEK?GG8E zzsJG(9IJy4Gic$phJwivW+p*wxPB0;@f#@hS&mk0*ousQQuhJC$-TXheM-{;jKhur zYw&ZBLFz80S$yKD_eALkh}_>BE=O05-4I^WZ@&fEZkoownW}przVwF!)?jltV$~jF*9VAS$lcPdAj*Frx3n2LQOgdXNX-QQtNwz~nSwdb zg~mJ@fVDPegjw5D)E13P7XJE#eVVv&78)BeLaQWMbYAze`TqNcS+OeLruA6qa7T))@-B z4^^a4r6>)P@(zq*YMwGF0~kk6YiZb}JVEA1h-H*AYW%Jk-S?MEwn63`7NyjQt#r}w zt37ox#-zP-8hG!l50%e=a;N4`g~?Hi+g<|@v^&QzNJ&My-0BS|SL=lB?7(;(z&|Ri zw6L0R|=O9pS5fSCN)k zW}y%EgEuJ7XEGkY7l#4a+}AAa0TXd=}^`U14sfCLF%vSB+tNN@O95Gwn$ zo0r)uKbYXt&_}SSSNWK$$dAL|1HYhk4h3xV=ZK8(9pY5@I8kvt#p&= zGwSiw-v;B;#Z-+?z1l+tP`7yxXkpdnSd)AVz@t?)4d$$+I?QUd>g6|Z2X|v9-Qfo8 zaL{#)uj1;QNuwq8-Qe+81Paoey5>Ya06ZQirmz4i)gw~PqW%mqxc?Zlw?}&gu^SKx z)=ds-_cH@$pjrDi9PQ^CI4so}5dGu`9Z=2ymMS;+b{mXdg>qGPhE^%!B|KW^@el*J zS4=B18zZE2`kxGtgCqNAsP8Wjb$Wy@OnyU<&ZZnDV`li^+}$utV|~^5hFP$qJ<)Dz z8?`L)buhiMGzd}{uuW?qE^7pgmyO|U!MHD7um;9VQmepXhRD4XH>-QnG4KoeT`+6; z9G%)0B+Xel+jT)gAzlYpT})@0w}YUqJ;S)1(iH+iVAv?N{QmPwC`|2BGw=&6H))>( zpjku{xCMLj1X_=^s8O#5#h^fRvS|38C~o*ZeCiGJ%aB7F29?h{A?k8S(~cmTq0M1% z6~;Cy3E8MZ=5Qcq`{0Ayd;}JzUwbv%mov5$Av*9BpJUHB}R8eO7^u!3p(}%VOPi~ zHpaxwn@l~U!E6eQX)iDKATFW(Rl{;{1}Od{|_7)}lrqW1f{jp3f=ZfHQEYa`gtE``WNhmlH%et4+ae@0#$lY22|8uQRJt()itP9ZOt%h@ z&0lW!!gbfS-`HmBji@!@4lgcDwyxsz#Q$o_a1bY58MQ(8uf5vS_RNzSJIH+98L26Mx;Z~8A3LpIY}MvUp+9PBh# zyCs;z_pL%Wg$QPb)I&Biggs=PA^kws)q;E-hAc~w;sF43mV&DBm~GV(uN2apR;ENL zp6p>Nk)tz~2p;El2l{mM(;4BCvwL2UX$H?n&Ll^Xa|=R|O{RrRm^sQd=y9*}T1NMZ zvC8MlT!NP5v@FnRGvUG(0qb?t2rRmqmMUM|Qht?26e&q6;VdyU9WS@SZ=y++#1G(w zumaUzCItjh-pT^v4wXnrp`?@(cqO4;le^~$%Gc0=vev+1`pZK`0(Dn}w!&3c2CEwS zzUu0JE4^MFQWfm1;j9`YDY~_x1^5COcK|PlWk%SY!=B8vUekHT1Wc5Rkyq<3`IG~I zUi&njl8MoBN>(CdZCFAUzy>3asl@q>nqj55qqpHp2@n)kpG{iO;J|Fku`|SSyKK+k z+GM&zi-0DvX}B{K0#5GIS_~9hw!5z&des2qyfw(_m^Qqq++&o0SG~lq^@IefTF6Mt zmm;m%mX=a!==IXAEv3NK%eH|nWnoo)lWF@EW!(C`dQDziL+I^jp@&kP-cD7ZY0sI~lRy3S3 z{u&jDPyC1vGWdUiDc)0B5?{D}nwAtUEu8Pk%gZgX7I05gUFs~%1Ah&2)Zb{BioywBJQlJ!+Rwn_j3k`xP_~y9mlm!FVxSSEu@M9I!rVNh;gsu) z$(jZcU;tIp(~<<*6yp#=+y zm*y>a@U^Vsl2YKHWIm>KC>yM=q4{MigV^XhMxbyh4?WZXScT}g-qgav z1y}SBb6jbt>J3lt5)V%pkeN3hgytCo%@Pi65*155%UYBI3@lZuys#*50ngv(=kl|7D&v-qP2 ze@OhKBbQ?hj5Azn@mmDm;~b{lN-swQ&`gb_M&V9cnV02zYORBsOrrMxN|uiH4@9S) zjP`7awjYVEDTo$5Kj?T;V6~_A?wI)WRM(JBXNGiiybzNxIn6#Z?Fl413D3rk4)YDs zVn~c#)bx(7o7Hi!gWES-@D>hyau>`l{#ZZtRJ3PX%w$JWs=cfRFH z=E2dKB09ZheSW&@MDJ)67qqoiVRmrc7+E$mfuByQYs+z?n zKbN@{C(?2owQ;7q$P=IlD};HxmGDbhSQ;(MnFUKdBg+qq@Nhakf5obDanMDjZrT?f zh^EFB)%3zOetLO@la5|vqm{O)XVUk0Xy>i|Xvz+B+(TW3jTZakOB3;bs{D*E9YVK_ z6wP6+=(!0tH2iv!6X_=>q#*rPQX|q&PjDCB8apO8Ubbox9VFKW?%sZ{NR*s4$^ys9 z6Y?3bxO``7(rK0OQ)?TQc`3@t09xjzmBLM(YpIYMs=LA2_C>>V{;` zephm8g6N5+<_BaSx_iZH7aDqEn6OTjGy)cLpHB87`y83ev%GG1P=2*=Q5P!}dCyMX zJ5^*&q32f!r?5VF^PF?SUv6=-mFo>af=I$SUC$F@t8iL{ALinRA#7)Vlfrw+YR(idD42HUfRSbGV3& zrcX#T+cRA?0KPZD8!cV~WPL9X?ck=RUg{7_OH-&r3N5u#2PY)C==?dCh__Q0(Sa5> z3$_uEsf9Y!`}D5p{nW>o@_-d7nvYI(g+G8DK zmcxp-w29hy(f)Iol~b3EMNOTU+ag>J*@0)MR5Vk2E1g`?H0|p-YY&wT-YD$psSWnc zsUp?q+MViital~Ps-yob79F;n*qyp>vdgjFkxHxF^xQQ8G3HkPEcBw#b<-^~?OA12 zF5ly+uFTYP=Vpm6QbHafr>sZ(XztsQnitpF4|?bw4@TnY*8U0fp2ti3TiafmKyP~L z=`d#bDUXewXq|HMO!{6r?Qvs{URu={E6&8CBUQsi6K3hwwIT)O?@i&dzYdX^rYU*I z)DCf9Pv5j^JhgjE@?P-8EF^wFt87L17vCVI>lvzsP8ypU^4Q|&@T$P9Zwo~XEv}|+ zZpw3JC8Z^}rj4@uTy`pR(zPkHLZpniPt;*ty^eYq<{uT!nw4 z({?*Wd3Pkkh%EBc#pQn5Cj36JS5lo9tUE-wvR(+|0e1yK5 zAyG-UU}kl+QIVfNqnfG2EBbg&xwiN+?a6k1GKm!C!Xh5#hbR@F(rgicz&5RE=8>x0 zTI!jV?vY*voCw{1;+bFNkp`VsHE~60f-cg)es<2$Np%>?h z4xomm`bdS%g@RX1&YG*1hILHmB2Z$4d*~|ixP|TXCYX@sV`A-#uQZ6|_z|9lBd;Ez z2+{P=I>#O{T*NrmrAbxVhPq~YvO>;aGrftgxU=~+Gfgwwe)Drf?2AMfQ6{2&kl)F) znU2fPG|*1iU;5JIr5zPEJRvPk{0jx!E3A0h60lOaX*t{rTV;~NN87a~kxGx0H_-?9 z0qTF3i`c4tqKln%(=4L-Gm}4f0XN@Mcv7}CM$FviNT<)sZM0YOPDH|qgn76|AD5@l zgPL=&Bj4wf{h)B~HhQfbOg*dl=>%##tBJV+qcKtBx%h{PR(;3anPr1U-qvbsAW;)A^$ke0d>?Lst zn?dtib6us=K+eNDr<3CWGt-uGHd$u+PA5lxRqs1Zu8w9D=m=kHjoF?Rr>eF#cve-R z3XX0q_J#)9QxWj_q>|F+3T{h_yC5#mn_9Jt9xShhwm(~e@vGDI({IuBB=`)Au+WOe z0`thORh#DsEIa&PSfp5cW_?)1?28vKhD9<>HF+*lU8_KUTIt?_e^XZ6Uo%UL6Nzxc{% zzCQgt)ZI#DLU$J2s>gaxUnoX$C25(ZR76L~(R?8tTh=x$j&5p($tj>w&32kn&q;Pg z773WV_#NV$h~6q27Ls)fuWXV=I6TEt;q+0Ki0xS7&|MLtk5+i6d^_u?FMHy~EXuUe z4JrIN*nfbQVV1PB(#_SNP6Oc3M$ua)Cxyq-@)QaWxVELI*&W5xs7?LUW$@VOW@pWo zy39+-W=Ax|)njxol>1+zl_}$~M)%8eZ9_?p4Ma9;Hk53ws5aly31ze0$n|yC)zQjY zK)*J*QFy651*HRQNZwM5Ipgry0lQtZ*dE=4aE)QW~5hS z=BS?e+Zylb$qw3x$^MHeg`b7z(wF;^JtxFQiW2o(shHvVpZS@p zD}di20N(e)>|h4nKT0&&#^S5CecDrRE6r`9>jN&zsin>VsPTXQ(Y1kd^a`v)jBDV9 zU3*W&A5W0`f`7_^<;ksC*b*V`hL5rQF;LDktP0O!{}k4icBI#1V1C&yVs>RdfrX1o z^C%Lptwl|)PnKl#C}mYX z)mI4T+f^dbm3-s8(_!sk^Mw;EG*k%dW@?>MfP@S_|(?xJ-Ag7S0#p+r(3`o4R^wrFE8%IytFCq|hN)?Kd>{7&?H&+nO8C z6gax{LWRwauG#2lMGEhcj+wlLFI3X4UaZ$SVeRSmiu$_bR1imi7@AagBq?pleLmlm zB!}zVbUP4Elvkfi&QB07;5@Iv-@wAcCMJbGgvGxF?wdw;RERudBo}ipuvzugjaVxV zW>JY7{e7bg7KU6KU0X{FQ|z-}p!dq^!Htj3hC2_?I4AY<`s`TQQ^=ZEMVWp|gdw|s zadmY5nW<|%Q)#7>)?qT-rokHQuMjEG`5S4Km1fw0=%zh!A|-~K4e%Dsjy?2L`1SYB z0J*k}C*qUysc$3Au~F|7{*0&{>^LVnRhDiQJ@-pyh0Ve`?}hK&U>*=nr%kr=@LOWs zSh=bRTRnIf+*7!N=n^XJ!$kNX&Ge9lo)%XJ>xII;P%$FZFxuD;}zUI|nxw)@~A$#2fWt<6zDNQ%=$*Dys%{EWc zkniL6)UikFsx>V6tXixFx-qBjSOXk@X2SelqJGw}h%M;qYuB2`YGTRXL^MpXc~~^H z6SXxIo&sIS`;ey8(r7nLvhnPya%6y5R=UFn$3D(kgVh6luc^StaTuG13Y%{OQpjT7 zV)KI8O6}^;PR8cXNxK>CLk3P2)fkWSxs9>o5t8@~4p${+<$ub(37$IW&3es^FbMrr z&Ji4cMUzGm9K|`ABb9Q{v?kF*;6cD3k~GAv$E-1gHcptA8jJR&JMK#**cHgiw17*DrW52=nZi{g=H5|~qk>>w`hDi!?ajTVvBFJ3vxUxfGxyV8 zb8O#E^PRJHjoC}rIvuny&kps&@7(ud-$NWYcgE|Hng4Kd0aGn^>i7ww%=L(NOQb6qal+8$vMCw;WEnrhk$H==Cu zbZ)7Wo@(C+YyUW#?5KKsDitD@7l74q(z0sW)FY4sw{<+NY`WdtzcY3|9cWuF_8r)S zecjVH@BEYe@qot zity7?5bxrq0vkL=eUIJM+(&c0z^$Cvbb<0}sap!=S$S>jVmku+-MU)LN|G9*$4o6^ z47uHiT)-bH)x?DhzUgy4>9nK~PLtI^&#bal(aBb}@4tbFe)I4q^H(X-4byq{{2J%H z$`UpVsV^-7u5Wst9_-1poCo6NI4=rsn~ve7|HL)XjKg_5l|3Ei= zH^cABVk3X&KrfX9D9U=DKG0ZAGeom)Aw>tv*-J3Lw6okln|{+&%qusD&E_G(QtA!Iox_!9GaZKp47eNwPGW<`l_R-jW4zGX4$Mq;t+8w zgWHYD2krLH#EEi82L#>+;O39=^2~0zzo4zRVy0&0pqE{oml;fR}@3^!c zAyeNHTIHm62n-#C2U$h&&1cu`rHNi&91R!FHI&sjSuDp8q|41>`sSnex{JaLK2%mS6 zF7jO-1hVpN)YVE$su4D(f_my8YAM3z6F<-|F|14O8}V4>PML^XluPx$eo-O}H_3 z!|2PUfvn9_206Z`xi%j)z-@Y^mz$2vNjW%r%y90hk6!NOoapm;e09`0g^sruu}a#A z^FHr{Bal92eI@)mFQP8B^!7aXc(oooJzv%+9lzuK8^sE0n&%~JH94E4!?)K{jgx?U zDyjBVijLIPP5H6XE`$f@DRaPn<~I8Qda%q}MIVH7Jjy(cKSZbJYhZy~^i-L5XBE8~ z?uVb`rr$l@s;a6iiVx7+;Wlb0gSD_{rqZ~2`U6Zwj-LkFsCzx$ ze-oI(ZCW^OjFrp=%m}04xg%iaXnht+cPj@IrR{E)CMDs z5X`}1?cwi0|s>U>^^y&ej#bY16K)Vu&jf?y5%rp2~zDOLQZB zW-2c^@%AZ6RX!LZl>apmp?cB5M<32~(*7G7KXS>QY?|#BN5z;1`nb1ka8`a5Jun+f z!cV=y4DV5_v|)BLHR5!D9=#zjneLxmPt^kfJUP`n*>T#O(3K7*GH-89ZA2Ic$8T`6 zHZE^|A1|s$R5_^@+4m+inG2%CP81vsH&4{c(nRkS2MbdvI*%6CqR%upK(RJpK2ugd z*-`00=x@(DU>^<_9Yjxxa6*Z_HLJ0_ifCXRFM~Y;_*l6AOgeqh88dxs?Vk++b+lq% zzsUX~)m1c#t#y=G@1pKF?jangVYV-adk^)0ncc__Ox4&;x#@jVEIlNjZaaWqcsMTN z7O~*tG@QU2MT%V%;J+nb&NcV#bQi^1#Xk6|ZV>jf`*tC_Ui4NL&_~;PI)x)0|Baq% zU!0bdh7Id_`&?{Nt#&9Mt*EEg_0+kZ=GN1|daMRjM-a@ewWW#pI7bz&zsAj{zF4^6 zC}1x!nZlcJB0@1KwAi_*AsHr1nn|hbf6yZLHam5!r+hDUO`-f0i4o(is-y*hZE~7m zQXjO7m+0pD+0>(+=G(xvjTT_CyAxfaGtF>rs}iHArxjry>WLj=9!>LZt2(^x%wdqm z0%Ui>t9^$iS!r|%P4X@}LnCcCrI`SKq+bBhU>p(JsH0OBbOFx=@b^XDZkk+6$$8Jm zlP86CtrWI@@3Yfw*|oH;7gp))=1MBUNfJ(#f@_Bl%SMu1HpVn~TxWsj*ok~@W{+$4+7$n+(Hmr5uq%uLnQ_KDN~$tb>wMq1UgQIIfSy?E6jQ}8fwi>h zeGxr}T*A3c^rl!R);o$#p}E!YW3Z1ya0Oaur3LVu=;v0#*|&Im@w9i(CZ)+}=hxrB zzq$)OJR#8Kd{|wY<2BBOa3%y7%0{>PsT2pI>I|q8j)3UP@><%dIqe8G+Tyb?j$fG? zL#suj;esowy*7~RJ>&47q{g8Esz;YMKNuR|Mc^t>bGTV3wRXY>F5s293a8vV8tUq@<8n4{sfEbS>FQp<{bV*I7_lF9( z^|dr1UN*n&>=YEB7PD;;G-`E2&JUuQm8PwQFJdzA^=p5!0++kLv*B@!B~a<3-HK zOP`u-V^BH8N6jX=sa}NWm-7odLO3?Mx58S*iRV$)*ir^^^$6mmFerD^E^|cQ>!Y$}ju7V|PSV9j`StXwso7pCF+i@2DV>0KgE}~i zuwI7uo|2iG>tfs9q#?RIQ*?mxjBPsbI578Vwe)^@wM_3u`jhe|(aX*Q5b3w4*A;KG zr`zcx&AWx3hs^$tgQRCGoM5RI$E-7&kU%^E=Jz!S{Ar8`KM!N?d-B|CF1vmxjo9+z z3U%^QH!SEI z;QcJ{Z`hig@1kY(zB{P3ch6oNl;f1Aj24Rk;4Xv=5o3quZz()lCC1EHG*LGArO8i^ zudZjB?^7e~UsKJ=55sDqC)fy%nXzx;V)!!FOi0sNNlznk%A*6lK&-@>AXW0CFk5=+ zZhB&MwGRhLfiH2(rUSjf=-4t=XJ*lmJRd!`x>*YI_Ar5KRBdYMv$Zy=HmA_WR;-R* z0AhR;<(Y?S#0%?zI`fc@G=;Ov5!y8mjWk=M&HW-dk%)6au7na?4#S}XOrAl@?VQNOkk|29!Ku|=iE<^3P~ zq^T6+B!r3H+X^=lH@HM|*<`Yc4wb2Ke93A`HDw{51H%o^uii&5!EylMcZA@g5l0U+ z>^Zc3ijOjC^%%`%lNZWfjq4VO&lc3td*z53K8(pc$4{>!T~)P(KGOn~=3X7?8JsWD zoRkI{ifPh5z}F>YK;lzPq`0a?Z|T3g>uFzk0QV%kRb`@+*m@e5HUhYQVU?FJ_G&3L zh=2R(cdQOx*uq^ESo0b*+bjh4o5>EMT3|I62aIcg4x=Xg_5GT@H8@vZ4@?~P|f=k508qc6D9&!x{gFRe#` zu*#DhSP1EVz=!+;XHoPK0!%fODLQ~k;icp;NeNkTNSXV`%osy)nC~1^#MZ3Y6sQt? zvV1hvk0bB`UwTdYSxSLxT-Hc6tGx7CE7*utIC5y^XLDs1UHKDN_4vUNTs_i*ai@t0 zEb1gqfID!zzA{K=jq(|GVa|S?Rvn~qgO+Wy|oKMRwg%$y`Ym(_qP)^dl<_MNcT@ z_a00)T#TffG1b!(se_f4=HadeUzn__a&5sC$pCeBQ(@j;Wt21T5OqwUqC7h3X{KQT zx{QElEJ8&3R@6%W^fX`E!e?twc5Uuky!g&(H~~aB!p#w6Y(Q}}q1IJ{m2aa8^00{- z4u|!j4v7CFn1YZ>3a&3uc)fT*4115-G}=AX4&B8DVo`cl5?qLOdDOkxwXw1!3p)ol zUAWms_YLN!(={v8VP8kpgZ;B{1Tf!5y=vi@Td8%eyz5gl49A=)#%&O46A-=hd$5#_ zo3~3gZM-CUo;X31agE|URw9IfV7Jl27bZTP{KGCd@9gn%;h$4H?ybcfEo361 zCx516j^-UbxbdtHtv@gY*B8w6?GP|kQ_;K?_wHN!w^F;Ne2NKRz03LoRm@esbl@JE z!V$%{hcr?*tF9%VV6}qbOS}YMaVo9vZI0(PQu13{(Y*IPNC=0MHeAMr{99^w;YA{P6PtNKnonj3iXYSf|eTsrNZ(@0)aUL_LayUp-g|uk}xv zME@XI?T4_g;_67ddMW%93{Pjj^~&!aNNbY`yIoCvoiwYF`daCgR=9VKeZu{?fbtk_ zRGdgpEvTW*YpUs`uqN0yOovNb>E5;OE#krL^aWwA>|EodO(bkSpwd2^!SNbeX%TqW zL$8j$N;|j_R+q05QA2SXvmz})`XTXjmYoK;eP?T^j!*91X$6IU9G61AYt<-MEelQ< zIn=$O0)R8706mSvsn=RH;^~Gcni2L4oDlJ6MLvD8+BrGvw0SHqI~sjUaDN1@R%X>! z#kuI6HBJQNC1eX>DEkUs>vYpdxx#(+OWG9V7>K@J17$yntK?kCQfoQk1DQM4 zgtmc;Slou4K3nOgk6VH4<&`!J+#b=LHd&m=39F9=d9l1Uwi5N}RKE%xFpI{_nkR5e z-A$EigpJb|$xFLe!P97Jg*ET5tE^DfyH<*n_bDG%{eAPujjYAS+jiww^9ijZ%j0(=UN_Wxi(e_ra_^q%Kr+_tkbD>pd! zzHYc%bUlIYTeo58=v$YSs&Hlh{xCt$+=4GT@Evb_g+$=Ai<50-(p!XhQHiayyrM9)9?v`y9 z8zi$O5G0!|2}owiHe<5|GQL%i5+fXv@!mS?=9B`CA;xcp9s9S8{yS&~`NU`@`A) z4IzE!Uf}Ofj_-ZaJ+OT5Gu?rOtCz3F{0>n_<&3){}1e zJd*x5;0(of9lF?g_~e-S6+DbV{B|D)&?j9wIP_I$IBG2>6pa3`J?ecl4D9X6aYTc! zfc5nnj&EcaW~q3!I;vX5$-=^QFuNGZMElg>=>NsP=)&WNk3ySCsBcn|&>`we$#Hm= zin6ZVizFL_;*rY3?IA>nwln|29h_jNFr8R<{P1D57GcwqVbh?l@1ia^iw9|>-#UC0 zm?x8oR1D5}RH?41Dm8Khn9`98NR@(Dhnz=Rw-^P>I%%-xp*w=BgA3J{64fJ=eR;!? z&8lgE`lMdZ>fsu-XwN})$?(P@H1S`2ifZ^o_5j_7kV$J2Zm?t375PX{&kw0Jl(NB# zKc3@ujV#l27iG)=wH+47t4I|%qZoIKx*TLXwV}f>Z7;NG3HmK{?Q{ zPL@-a!Cj}1J{)}X4tIAl5Ogo4)UH^KdK{+vbJ<81c?`h!vzrGA({jgP&C(iJB@;O9 zcZ9mRjT^-=AooP|RiwP}Oi$;ywKxhfdGG*C3|+t+po3^$&kegL1=S;2JVoRqdwC0X z&3@Q)UjeH;fcCxupTU8vi!tq#myHnN4}&}A2e+vcs?`^>LAoy^R@Vj2+oImsGVU&4 zh78ujbxSy^^#T^}Q|L*ydlCIzO@D|IvO6EzyDSJEoZOIHt(^?V=eW_F{ecI^w!?$4 zau`Ee5p4z7I;>*DdxOEj{kuopPmBS-2M0hW)X%mg$PGkuc3N}x+~bf$ynNZ5BdBt9 z;4+ttCVhI6l6SLPki|(`=cd!hwEt_{RLFhfGcRm|*^k5@lN+Q(>u$99`z_-;-axqv zni0zH--QraD<$llG`V`=9qxp?f5(Ko@UA#MGCxP%y%i~YXd&x5b#vC#ZcXP;XPr&uxhZm&f<( z?MYqFrfrj*L$OxHf3nX!p+H^i=1(Ab5_<4+=+KG9XkE- zi3$W44CM^objUvZ_#T4ubJUH8Gz0$2738P7@sQ#%-2C;5=34i7RDDGB0D@v?>d9(J zAgRAteNnli1$5j6ES2~hU8>baIAfaM^m&AvytReN31YZjp9(stdSdY% z&=iB1vH#2(#dCMyhz7yjmmTJ&IhYn9rgF{hnN6Gu)PrO#P&kGT4uny!2cb}!Ky>oe z7U;FRTWKa9$wFY>U04U-LB9JAa#j%Fz^*!fbep;*%iY%!co1h2Uq?K6fvTJ2J0wg$ zdNobeOW6s)4?~bZqa9lgM-h-e${xr5`P)_d?r4FH3Bt+I6MY4tM3Kz*I|B5UqCe9>Dq9)7|w;u2-c|z#R|8$p;Wej(QPN%)Z3`h7O z%L~!Bx$dcO4downgGd%xi%W&4Cj+mb)Sn@Z=Gi4^^Rt=Y!a@G%2^tL8c2>%q?Ix zN2p8OUG9lXaEJj3Q#dBoTv>a0t@_hdd(@a3$2Ea#Gp>`@xiNQB@axOfO^PJk^;@z_ z=uE-;AV+X)I*l0&F5T;P?fo)oPrutjjQnoon-=2kPg#>YMs6s-0VGJY6jR?s{ZFaH zVx&p_`&H036=KI%CE(~(>!vKz4GPn(2A3RHr|wdK$Dl)1HqV?`M?yD;XSG*9pxNAqv z>T9>Pj8v`YULNR4j*tRL$9&Z7S0R?bI)(b4(h9zg6`aJ%4|0jHVWy!s?NJY1<&Hw) z9X{%wzPlT-+yrUryY`M8jH5E8%Aj^O=Zq}7fz(i?mhN)9-rezVK%G+^P;06yg265| zubHIpS;gDd9~_w<#NjOV$iJ(OnRdJ45YD4;i1w)y_FNmps&1by}-+f>idG*1GvS5B^&a-j9`9y<5Rk#7SoJQC0IW#jIi@*DXb& z=+kqXIqww@-n}-VR_}r44UTY}3L|s~B6>B)9e(w~dt)?1Y~15r0R$u0i!aA&A7Nj$ zdn49=>G-n(mK zC0O*|wT`#IUIU93hsGuD`Zq% zzjfaosCzgtvb?4$h*ZDm0X4RDx>B74VmhJHt>cM0F`*h=G=d{lCRcGB2VF+hCqckPMhL_qKf0Q3;7WQPzdw;x-GubD!zXLPwfaQ%N_xq} zF?+^ZM_N?Rs z@y5B^M*`9Hdd>SKGj_G_0f41ingay@8K`|A5k+$Xl(z3uzwG{8~% z={6jcSH~a}6=%xbPc=Xy$Mxj*xUFf=Ip4Cy;ZhbH>P5e+l&hu6f>1IXKqy z)Lb`O^TJ5Ya=ad9kL!WRpK8F#6KKs4IPa3$ysY|?7941Am{#XN^em<{1+hA?@A76y zKx9;2995ffjP0M}{k1;t=js0{yb$2|*g9{V0X+cfKmxDcm;xnC?tSz-yC2M6dNRpM zc*G0F=O?>=yVLzi!8N29+~jt(ENh8vTe=AAMt|dElOx-+pJbNLG?BY_D#A#hP@J10icX$1KN2R;G*1cxa2&Klj zmm+Z&xl!xEC$T^NzGa_U4kIG_e3*N$Y_GXi#~bOz8Vg=kH*ck6$KEN}Q3!UjEsYbg zNJDV4$>|$cUqrqLI;rxVHO*@O+&!4o z6;-dQ+qX1ts!+FN!>w*=Ie2w*MfQa!R;YUhkson-ZE}crTXoKwJ5Ra)G=hKWo~{0I z)#NL6$)SO&vL@j+&+@-DwH@ zr9Qx}!b#6jRWs?n(K6DCkkmeP3l|+$*Mb*+0Ea)W`ZN-P@&9!c+~1cYD3jfMa8>ux zn&m6hHOK-Q!6VaGHz&K)4-Si}ZzFi%9=ChPb9mK9H!>h_$n71_!mC>naQy|{<>dk9 z3Lvs0qDUYDr57`qsvcy^xy4YtzW`4CkE;h{2b_BB?wUO+1Mz4P(Tm`SwRLv8KH zPhW53vp)~a2X!IE5SSkTw-_u$C5>HjLW?r$Zs}6R-K7} z&wCKLp`Rh^92R5@EQY#rKWcdGTsM)@kxzxIx1%H-Ci~U7=*qs-uKcADD&0|}0Ka-J zI(3wKyAc_QCl;%`aTEjk3yLiLUtC4D;eD!l?9oJ&X8|8Xug z{;4qhUbsIJx-s1!+%m0iN3UvjPrqON17W|7d(`b$R;%C7X{IX-Sb7yzm--WI*lhK+ zY%=U#xSD$VSax&E4mM-IcQyH(znV=x6Uv?X%$1nWU(ea2=0by9I3LE{&MS98UaD5A z<4cDEsULg^``<16BnsScC7qV^O+>m86OrOkVj?D5G5%xUMJ-Ps1|>46zN~gF3&PTl zU3JgG?dqfB?#C-z)byreo!f)>jJxs1HTy9D`VTYS1xH00l=g*y7iO29JaO>g>u|w7 zde!h=a#Z^q?^^r9_E}a>~@oM}bnXbrbuWIlILC-B(t&Qr-gYd8%47^XT51_5O zBZ;H+XB-#oY#w?Mu42HW=aim z=Pq5bGv%?CmoGJsJ({)eM=tXgwRZgA0oWUFUOkPpGQ18e8yohw^W8+v(rrjrqujQ` z=^W0nG#HxCtU&i`H7z%kmwcyC?P?u&V=x@k^JDPVn{Bs`s9T@{_!%;Yz3#)IP&R>{ zr+V0Zzgk_l#Z9E-#}N1$LfzZzBf({@tGilZyB?i=VHWu^L9^?xc@VCQ>+qJQ-Ca;X z4`k2F>w+W8eQGxyo%;+zv=qNXDxNk2q}8eZ5?4X+T+G2%4h6h!JBuu^_;=(zgy(UWK4I2T^*HHw@o z%9MNAK{|`));y?&kVbkK*eRcZ+qrd|-ej^1jNtKh9A|WEZpY@n>8gF|WBY*n6?=qs z^2<|xrO4~E^Qv*+f1&oQ!jvc+<8wFB+_;~kzZBp-RNaP`pQQ4J4|5+4w}Sl1**K}d zHjhH;wmY@x97^RmHu2kAbi29~F^GgZaTM|R=3b;Q!gN`1@8>U4--5BB zp4o!*0DA4xC3WzW9LWCo@#?;ma$7?rxsVw=~0{@}pCx$>lu^ zWfVC9ubhi6e6M34dsgnsn#QXzkoN(nNVd8jGR!@xeC-DJMp_?OQh&W}Rm}+c(v8z+ zNc~OTfHyhmtiuU<@gtPr;%)Tio5P^(eKTvS!QIObPUYOc#^{iP9GaO>?URAcXkG_* z7N}Na|6*sj>m^;`)w4mRPXMKUk3LbJ)MV@mc)uQSH@WBl-UV|*W0YQHas7g7+`QjF zGV1yTbWi|?9pM%o3AVzh9Ch!!3zG&NN4s95ITK_qETi|?Jk~%N0?#Z+0DiV%n0#l? zEzp(|I~Z~vq|TdwXLyp1`yxlH6{UaHFit+gYZpxO@De%nQi|WNa;Ne3M@YNP?$r}( z@J6{i$wxOyF1m;3fU@Y#N7o^DJ9V*%avz^ly|lH^rEI0-7q~(>g}(x4-*(e6%x@!A z`0*=|qD`KwnbC#WmfPA;-^H>PQ?|oa+Ot@q_<}u9u(RhMeJ5Vu(1O~2nN7(bJFhMt z!Od@QHUoF#d^qbj+07$0*YM%2ueJP+4`;dX8jl+XhYp{)$%U%Y&2Jsq&OJvI`xRt4 z(9!m4oGmPL@xr{WyRax5f?#JGa8zcY8@xT34B{KjL{bZKp6BGe`{_=tnnH{e&KkUg zY-HI4vtMMlaKQ=WTd|>Z&$E2bWTanqwV4pFVIoJ6s)J=2J%@Cxw^kASsdFf%^;d>( zIfv%zomJ%Oy!o7JoMb!pe@;yYK}M+U*Q*u~LEH>|CX%Q@H#rD>&r|=TE$?U}^4YodnJi{m~C-Y{40faa5-Rh0t zuAf>@&ZzfJ0Bz)`8`sm@5Z*h1UR!eGdYZNOP9R794eN&i|NVqvz}pZ+Bp6QnBi#Jk z7T(i^m#rfE87BDySqnz)K->{WO|e~f1mqnp8&C?P{nD|@__s?yU6TSb6L<)NM z;^BDhExms61~}pl$D}<5Z^whj;{YDiu?LSI#dV+h*W-&vu6qH!I*%Md&uxGws0EHO zB#u%<(0voNkH(0&p7`V_{4-y?+}(A_pEiA>HF*zo9=w|jg5+2$NS<{ISc*hbr3iwX zz7*jcP<0z64ML7QXyr&Vy|U(`dnl}0cpv;l5H$%LB$!Tqfb-y`Za&y!k(L$5g2k@^ z^Sh8}&9Z#Z?PMpVRwrQZ!6^bR3=h*__0Zj|w;73;kA!TDL?q&UkcjWXMGlmfhzSg& zSxdxcU7RD%5QjkwWVjaMu=+su87vMbTV@V}-@K!T!LpDdDQTiGC9+DQaF41$2p=In z7K96iR{j4LgdkcwEh&x)B?Hd1I>g7Bn zGj@;b;|O=;4U^mScC~nv9nJI%-tAkEMehP~Pk#_D*2(*JEBFMEYIHZkR#LGp^f25q zDD;{$xtreVSdACNzJj9&IC8ZGuLio7{HI;&zq*iI`L`{|kgAchh!5axL0`**J^LCM z9L}(GV|DLAI`eDYI9$Ewq$%~P;Ro0(*##%oz`240)8Xmo%yvVzYq7%H3|@@t5W(|# zARzdBKtZ`A#Ex|rJhK-WpLm_*vDYT?LQ2&C14pytD8F@k+lm4 zAdo5fJl8m7j0T>~Nq9Z0tAZHKa7;T-9?qLq*L4@GznwIWD;>cf+3ZH?-17F* zFiPD2u5H@C#X0f`q&KcWx<0cCdb{r*Q0vCT{xNJ}cUs1Tw>I(g;$;%3VoX=@+D9p` z?app^wOiEpAo(83o{zVKKTPYOcAUr#fPnf-*SNYhFRI?|YR0v=Yrnb;hkySQuhrPW z{oA$~33J)%p3^W+Xw=2vCTQZ9mk}R*DhImpA?ll(ae)n+LlLJ#)U%s8ar2oRnEAVL z|Fr)3v!`W8veZ}C(_6kD+eoU(pFaxYR)>NI#sq(ycE1TPVGTcJw6&8p;&Po1v5$UQK>_JDfl{h*=w6@Uxj~&a-E!c0c8G`eT%}G$wLiiG_hM(!D^+o-X9RL>SL&%A zWQtFl^E~9gtH+rn#5Gfo@QfXbt@i$LQ(eIc^}8Ot681Qp;p}O~6|d~-sVW%B@OxBb%1jy?R^fy6^H2Z#@N);)7a{E&IkELLKNb0&3TJp3^_CaU5Wv}}D zmZ|OP8)r|sU5KwV;0yt>NxI$V)aP5UES6*_$D@nSfPMEYa9;ItGp34X_{2%|@|n{x z&2MheBy{%lPIWJ);VtF43CudkV8*mlH=svR%BMaZhH0NtkDWd3enU+*(@DT{V6{K6 z*d1Tge*?=N^SX9^gK(DH39522_}I_j>z(=ki^jAy1|{iv3vDtlVgh!D#zG4vZ7Q2> z^K5qsA|omn?;&tMsZL#>K8u9q-#RqPyK&}i3TcgBp-k~4y`uBj4@U4(%6CiYEoZkD z^Ly}KDxW-%#LvJyyfixJXmzl368*Yp&Jo|9bM)ppNA%y;a@*k0Z7n-SP~wS0N5PAp z+msl>&0~kMF$cs8n~2IDKXf0?Q68c8ZyFv!J;-g|ad24@tAST7(Z6#}MDq5Y39$Tb zcP_edDcs&Dca}T8`Gb)c(6htT#niE}Vp4Q}Q%<>)Pi{dc55wDU_ilfk`}l)wylK%7 z3E}``^6Ez-BgrHMqHnl_y7AXDDCyt}Yl_uxkXm^IB-=2~RL~hfh=kt*b$iyX>|A`w z$P1Txk*db>k}@wGs&6bQ3zT}{^2Sx=jZUw(v9oQ%U}uy*z2ZdM@cEi`>*=dM^wlAJ z04ARBfX0V)=<6@uP=Bn$iN@*UFYPE0OT_q-JRSJLOafn|@!FI4eoL>{gAdCj6Hb30 ze-y=QU*`cYSoj83asDIGwhz(M& zqJ7lAwpfotUG_TAF9%KaboTW-_`~f}&%#yZH8oB z8VS_bF*aOURnq9ymNZjW={rdH){DpA7{buXH?@1g&dufY4H>7e-@|8UbX~FzB^Bjf zMN=JD7v}n!{QBbfI8S>w=E0*+Cbjj%oy35L&)D$D`5R4%p18N6bF+gL8tNQO$oQj! zn0?)KuCmmtDXFXU!c8G8d&G%f?!^+Fy;$D1L|gwx`ix6gyVrs5D&fOO=yW}QuE(pw zw_Y547G~i5#SZ_3FYI_-?E_MCG7(+k^kJ+W9nKIBjMur4>7=i7qu1Tm*U{7I=ug|k zy>*+-lD5U$V=%fu7Aybe%^ZdFt@!i%C?VC*B>4 zCeZE5KuwrFQsgyu_H?$zx%1K$tY162qUohRtox3|j>R$In##&+Ky!{4@5UE<@UbpU z!$Jhq&_Msj&Oy6JJMfJmjLp*@hSEeAE?HGx<^{^a&R}P}b8x7$qtJ(n(E3Vz52}Q| z2c;>%DXpN5Xl`gKS7LWW8UvsuqW895udNT8)1k?uT~_GOw}rguAdS5}8Xs(TuoB=o zfpBRF_Ec#Z2+mNK`TiCUF49<1TJ8nvs>&M!5gtNE5B=Whw0Rf>Xv<6VC)#?rwv}LC zk(N+-S$TyM>uu{Y(^Fd#s;X}+4?Fy=DyJ7S-`Urd=;oix8=3;EywaMIaF~1U4YYN2 z5__P=`q!=ZK(0hgh9vkiU9rA6zFRi1*@@H#Y1B=aep(Xj9Db6%L*_*Lqfzi8YHl#r z-c293Y6D?tiqYRmi}gkO!9e_N)rfMXy4*^9PKtWKw1Vb+G9cpiDm%eAW9=opE90Ac z*P(C{?6~lJ!;57K2R3_yZCLz4CW?VU?4f?J1AKaGBQYHO*V)Fiik=b$gWp}A1jh!4 z8`OjWJ{-UbghS<}fr>z>gEfrC^wMZ~q1lz5Jk9nEb82sE@9xCl0>o1Fu+4|#`0<+Z zRpm8{ywZ}=DpVh6EjLq>=*Rct_^WY?ig-NOADxMCXQHe#>T|OcHb(uy=j?i@ZeEb` zI%L}pc6NF3wxLcvLi!y;#~Q7}_QJqCEDoj$U%qPZ9dP;wJ225bPQM3c#WUXK5rt|- zk9|TPN~3kc?(@(SL-zcAG+uBN_J(306ipB%jVS9?fTDZ!eic5)J1^Qn-^;^S_GZip zK2S#^0ejO!0n=^oAEb}nrA{^kOldhNH4MR0UdF#v*RS+S>+2$o^)-&yyV(nEZtCNY zuXz>V^`($Hi;5hG2FwJuuaJI!q8s1iGgs~G@CF8By^z^Moimw;cSV2ix>%=! zZ{cCnQDyqudo1%EFySFx6%Bwsx0Z}M=1YM5Nw)-%f%K{j9}1*%3zX;z3}lfC#hBF}Q5th_D)iiC#3GJD4N0hy#Be89`%{ZR+RO@gtX z7yi&4e=?8Q!XR{q zXdAe^7VW%bpfnMhotp-rVsv)!V%61nb;KX_(i8cCi_ok^I}kC9Ns-$V7J`S8aYF@f}m`yHgz%!}(R^do`CgzVw5Z6d zuc!b4rnHW-Sdh40qaI9tf0X4pq%=NY=as})L5IW(hp~rKKj-MQ>0yv&0{sCB2#cMP zaJkb*ztH}S=x<84wO^iuV&`GcZveKov)8LN9Drm6YVGP{LZTXK>LIgMLb$NXqj@$> zGU+|w8I{nl!ul(ET7hWqAl3k}R>&PFt*I}C5MUWhdLKzOl0zjc1FViRftaDuh71$+ zf%VjaYFF}?HFdR?_6k?FM9RHjpsoyRA#~IJWM2m$P(Qx1N1Gr{ON$lmBXt-`u_g*q z`1I751nRw-Kp1K$OEjp&XcF51DoH0kwu#N%-quG|8{N>sfQW!t>7$)ZUt#3sAtJ>Jt?`3$-YFaw^MUM4+=qF=Kxlh z$&A!^?3Gjji4UoQ^V0LAQ2H!kBh)}tNP0-z5Na>fiB2d>{mDUWQlE8c{VKG%E=g?L zBcehVnMv^ODf9}+Zr~55n$LgoN>&7FAc$JRk@8x{!`y8ggh2Q3ol~E%SV^NzFaXnF z5W<2i79;J<4jk<4Z6oVMb8TY)1hhF&6R6XgW>jl1L$P=)!7>?tNX4t=Z;^VXApArp z?HLwVhFQ=SGe(TDo|xO}r6od+wEC*7hrVH=$uxr&q@|CZ7N~uY%IzCiX(pxwK@}NH zc82+rpiHr%7818)g%v}M>*dngv9HlWPmf~~93m6bHLxExu{6)29@5?<#sno6KgphE zDXY04%kr5b-(yV~5(3o@5R2@Mcj@g`~8Mq542w1QS_G zN>qEoh#W&Mx;0iWVoRJ(d?nNYeRYDLYid9<8==@k+2YTHl7?*5eq!~!A9yUJXf2`D zVzq#@l64;HiIeUfC0b!4Buqkvi4F=pZ5C37tl362(Hvkelc<3XvQAGKvm{cD78}(F zifMf*bw<-8G?ZA|I@nGrCYl#duEY0RV*^?=uBs1|(XP_FgSJzOi9zfNnu8I~W_7@q zFbG;kTJ!`=WZM~tEHV*EYV}0%Jz$57J5eKqk-#Q{!V4v9BP>R;bYQb+f=gBG>jyz@ z6+{YNDG?#Y(Bt(FkUrq((Sea@TG0%oqaRX53xS@tD>fS07!ae9Z1G=@7GsL_s)G#`aB$1tnsHH2i#p2l9o55?aBr@mPw*c0efGpM`m6nOgPpc07a0Ou^Nfg+2+Ie%scc9%vaffYX z^siluF)gKvJQ$564Mf_B=L8Eovv69X_wedkcmtI$pI{m*>J3HuB z%M_RrB*;KKm^>`8PBHVQOJuZ)(>JQ8*+>hn{6U3TEw~cBe4AC02#iC)rMe zuL!r)l{zdE2RE~p%sNtM2dm2duplIeK!|WjttoP}Kf_91Zcc2V2+cNqM>@^``8B{C z(IK+|F=;$3a31pMzzXYX?~w0ZlfvOa;l}D}4vCr9&c76m(^oj*OB_hTD@00%NA!wy zfsVyPBdJ~zfoo!AQ-pi~(2`>?Cb+AHar1~%H*laYQ7USxUQ)DXWIr`f*IM3K zPaXnjQ*a@|xd`_r=^VYjazRT<%ynZd(Vb!>fR)qy`bs!SEoffQfJ+UC!F2T{VOwfx zZp2-wagLV381w4L%OaXDD=6>|VCZl+f>&b#J4icAWvW`xXzv8HLXZu_Tvw+yi%=u4 zIdzu+e4w3YRZE9X@}%<25m_5|V`m>Ra8Lx>8c}EfP>wNVrxSdIC>pdalq)JH?^T$l zY~ZH~=EC!>y2F+bR1aZw(8XvAp-U`0X!64?wKetiA=Yz2MASbmbPemGzQ*By!set! z(C)&R-ehF2;1S*gc9A<1B`_61=_JVX2jLx7PkRTLOuRsNT~Axz1}ACwK|VWnsdgEp z&(JnN6Lk7}I+$tEH25CL-T{WK+{Ru7iC`(qHuu%U)|o9rL#%D^>O76THAt7OBN9}2H3S{oSWLjipZmpRlSBAE*Q}svFv7P(c1|h9^&V5EM%qCo3>($|p@wZ`!P2sA>2oDf*q*=14 z@3s8#`Z#7=>}WXaH3^aiMqjokF(2B@o1v7Pa!eNy#4>8RO1do}{#MmkUsvB0hHB5s z5qW$_N9%2aEd%4eC)okgVnL$?6h%YI8@<(#3b>Ho6y~~1LroM{fQOMjk&fAQ^e5!8 z;p3e>)E72V*!`mEsHCqWOii(tNK{n7W@2M`C9E_!FsO@Ki$yCX5qQE#ouq<`EVvl; zlRjxN*eZC?IOs4cy^pj$Ww>8sxmVVtw@2zOgF!yKs|efAr(V6G^>hX*>q=_E4#?J$ zEOa^FE9|kVM3RoS4ag8&0P0D5Cwt{UIeJy0K(=jyE(@2Xvkshzb`7(Wl>Nt^O*q+T z8#*Mc^=gE~LF@A?O^Bo*IbHAtbAW|?T;Q6JPdV{E8Zv5u8VHf* zKytx%)dL?|k!8QaEW|F>x*{s^R%*E@-Z6F&=vm}Fi3u3gjDeI`C^45Owd2Ksnaxv7 zt&5JZHZ_7|acCM*;${PVNoblg*^IC(cp$tu%s#Lo_~L1&q?kQTb;j^Pdu=@=Ca_lc z2kOyYaqT6+BeD`j)(u1CKwN88NllZs;CYOiXTa47Cp(lJs6;&ug}k($qB*azAgKm3 z#i2^ArTMqmf2(8sbCnotw=G=a32089x|NxpsmXSs$f`(K*_aGjJuz)-^T%a8OqM3vY<0Rb$4moB5ttJem8y99mo-QzVqsV&L z|B$ORa%MH442~V6i*WhEDCyLZCv{1a_Per$ z3vrHs-@pLvMt{B_qyucGuv;D@@m7;hsi|+UEf!}hianRK&A{Yf8dG$v93GVl^p>n} zCr&yT{{f-$>KRp+l{DkO)65OTOrh*`u>>zp8iR*U$?6snYyUb{$w*n&#$E>$OygCU zxwTj}8sEP!lXMhUdzZ9&MOK7JtRjdhmh^%+&;E7+NDVF$TBuZhtO?Qz7Hp*G_Ez?Qg&$5t_TGJh!#Sq)|E%RvdYF1`0{`b!<>U1U|2d! zUwHafktcyTEYB(Ni?OC^|vot!)Bt@Q0fs`jbl#t$?ox41ovT8|$Dzd@7eVHXBugpzg|&ux5GK z^}TKJ4MeA=i!g{VQ}C!@zauOlI)%A^Ve^+9WX)_=y4(H5Zr(WRM5kuDbi($57WdIc}<~m zgz`;zQfr{v;~^rbJ%$(&(JlFE2iw4HU@B<^Tn}8YF8F91;d>IrW>2H~vhtde7S06X z<Nrc#t>P&r!};KO&obWLqMI2#W}_a=>s*Y^XQ_ zeTXThFvG${Sca9_*MjBm3BZ@-U?XWN#7;_OVoiO_F*-XSHfH7Cq_qoIExgdy9Eg{~ z^$_byQt#R!)gVNz@}0W*q27bz!vPB&MMMmXFA`IRjX{-cDh+FIyN-rKaAg@y1?5S`Ws#W$n9sr)Q?br8K~fBYtB zpro|0o04`vtl$AMf_!%gD@w-a1YHWPvE&NC3ej7fMNMC47i=QTJ=`43iix(tvbb{C zK%{fP5o#CS5{bAF;2YA~E@j`rU$Ks3+{}E*5uWB@Oq~TTNTbkJFw+p}TqF{(9eDXb zN`=h1AvLw}XT+ZE66r?Z#PEPpz6;eyu0qoR%oAvklo67ACYOzp+@J-K_uPs1AkZmJ zM5Fg&W11)qOdU!FqByBe2=Z9_GyiR$L#k9&%&kT zYf@|iQ{pEqX{guYHqz>&W+Y_5p#Y`^KeK*E4pl8f+abh^>lY(Of3%&cV_cjqsTT)n zu7iUVpGT(<+~erE5FpeUq>PZ0ysW-yWlcGD8!QVb{?sa)w^}AvARp6fY^pN>LNd~v z{(*#X8l!JIkjB)`aYkAT@Q^NpC;*!i@f&wVSI|v(At5TGH>nnC9Q4Dr5kA($* zv8kxbX|l#^Unex*JFz*n~s{q?CX^K)51V5nN6`0S?V> zb8+3-C52ws39;lOQq@u;#%PbRTPsx3SdJ8oI5;1#NNH7|ri_UzdQn*ops0RKYYd|2)vOJ z0Z1zHG9`5E#wra(K1qtZ#~flv&5!{XFe5WM0eJ_Z)1+t!Gy;|m7!Gq28p2FD$TASC zl6wBa2xf2%{KaQMQ`mo8!!XjZYV<6kIB-Y1`hB z7n772VU|!pOT+NmA(b30P+}%en+fbAFAUB;B%+Zkg_O9i!M1^JofazYD6Q|vaf=jZ zJW)OT>$Rbpa->CK4nS}S-Gqrt!H%w=46h**gyalBXi^A55>F-$L*l^fRBaiuBqdid zRIC&;yQI>n6qdGUi}?3P;d+AT*PDcVFi13DPYlwDQYIuqIwqzAldLsCP<1IG%g9L8 zN&u_H$Wqct>iEs%`p|-FFCH0VOl34~l1DlX-B05(vW%2+M-!sfW!s_elSzUO88&GW z!XfB5Y@%5NEj)R`Ikcsdv|uumQ0pdm>_Wiik~4s z^j6o(HKqt!4m=*bg$$b`2ZSCNi3`e(VD8CVfSnG#CLRQVOHKg(fuhtp!$N{2T5}df z(m1la!3Q8>Nn`Wcq98cqc|dRBU)7F4IaUNmCsa7hyj~E0wgT}0=h%X`AjJ%6)>sZO zCgk?Og9{Qy+7YYzS~^e#sGGdd5CPySoD+yRxG>c|uuaUgcEga2L0ShU8Gme|ChK34 zK12!xq`3C7m_>#(gAtCf1gAqGXNFw)%r;ZFtqF!AdxdkmjG0gKtMj>-Wswzlk1pvv6d8d)!dei0v3ek z1cL6UP3|H+UK?zBl`#|I(fCR9+#o4s8)(r|LJj3$B%l{+7BPqBfYunv(nN3>ItK85kX);4+G#>R zR0N>o!^_6#)PN0e?mHA=$$jrb z+yu5UE4O~66W*d3Cl6p5fSL4knwW#$M*-UFdLywmG$84fBw}Oj5GmRn$VYxKH?*HC zIP*Y!MhG8a+9=bChCS0|2fZCCt1;9~-U7KvV0ltjUD5`GKwZ6UgB!38!e2Q|(>v1& zXYINjCuHOlL8|aJa*U`_OA0toc~vS)L&gF`2X#ol7UwlULyqQVrJNdp?Z&OyAWEtn z_q_@rSFeih~0L3BH-$X%$Lfu>%99G4Jso;um8hDQUD zU3SA8eVvIs6sR+~7Q$aSKFbYIf(jjp;=BzI1?w}cchW?rq}0p&lDQ7G0PZ$kPTj!F z&#kquRdYsSXLp6Q|E$1>|4z-D25--!KfJ2m*O11_pRHALT zBiehkrxtOK(CXB<2XZALrw=Fu!$dl9*dtXxZ0weMrne1@z)Sj*bhw1$Uf+QjT= z4oH^+71O~_?Jk8;h>;>e8XP-9h8l-cLH*=IA~hN6d7IHs&>hm_iBOFNM$R@Kh*1UL z0pRJh!jeYVMMDx6T~l9)?UAA%ih{n_CM(QjYDSdv@=}N+#oi=bI8?G4sr33RD3f#; zM~V z2I;tdj9PRfR(~`xA;q6GSjG@7Xx2MRMX90(G9k_xM=8TcXou`=j__at5Na&r(?4)c z)UTxIRRm0(_y+>;oNYy|p=Dlb&CyFrOY56(_zV$BB-d+Qn)MSLo+HMGP40!UaWuzw z{MZ%p^U3!{YJ1q&wn9hLh_#(*dXO^-KYtG&6=dSq$6ob_^(xhRM4mTG{MsOAU=eK^4O+yMjf_&EqkTu9GKlLeqz19UC@8HGmz_N zh?2R4^|q4tfs_wYiF#?Qm=``VEws-xR*tN1Y!w|DAmvLGYu5L)CQ0EJim~<40nHRH zAwB|wLj76;WOF1_&R$O`WPU ztFJS5!d0~xWU>#LMhJ#u3N^aCuF4A(E`gg#woDPZ3h1C36D?BUv`?6yG47RMIW$aK z3PbT+k~6`D=feEb^MN^-naE;IDso7PM-)TRZg;pWwLXX*Ht`uZ_9TJML}SsUgrE7y zv}aynP`|Por^%5g4M#H@*?OWm^H-A(g;MLAP=qL-HSd(=A)bwjIphWc=J`*VrKY+7 ztbEWP9k!wn8W9MlljIPm3KFSXm5Vk4Xn@Rln&}yVcb_C76T6W$t%G6oyk8mExhN41 zogb4^D@35=?D0d+d>EX`mR+&<{7}}m`e<@7w?a6Di$OS)DFU{tPh4?Whi0LNT{rAx zH+|44b>IM6D@@CdbYLryiA>%S_`4|U4etq{!;@N}p@UQ@3ZR_4q{)U@s|{BY(clq` z83GWe!|4}oh+sgh^1^C04i6T{1MD#4h)2efu|o^9K)y)kggBh0ry7Q59ldnJShSk) zbAp3D1U5)qKvo3`J!yb`+;)a)ZPjnRFH0L+LJ{Z`h*(2YqRS$ES*$NePZG*1^h^NC z21UVnhj|; z7j=YqGii^MwGb&`-oT1xeQj-t4s?iN%}ke4kz%?ZETrrKGmtx+)7s;#_pP1}QRvaO z)-Eex2^#&<*hMG~E(i+b_o0}?XkybK0}|lilG>;yN1SAX(iNnQDp+)j(K$<3>#$$FzFDxOW!Ov^b z-KGX$T$Kg%X$A?^p$$5Z#5F|eMFu^5Oqq|KhDbB%N3taL9c@*A`lGGreW{mo*eY`t~pz%hCCd?t;=zww33?mq5G(lpZ@%hD`>#DRf|jjlQtgqx4}nIm4rim-#)v=Q7%J!t zN3ujt6Nf<;@E#IB>H%`&m_F%(@JvDNjl%$>y)XI^#~E}?1YYhLQ5fnJ#gv*O0dn!` zlxg2C)(eM0=&%w-iI+&>ML*gHnW7n!tAt)Kq2EQ2!Z3*ovVQ=<8la;ztGsv21EdQ0 zM^?~hnqR}GaYt(|`vjI4_>u|UO1C)_R!^ZYaCQ6$hZ+r>MV;lDDGJGXAYcd-ymLT{ z5*oWsbHy}*t$6hi>1b+WId3)1zaWy$v!kaZFGjN7kU2r zeJ#`msbdt-HmO=P#6kV~Bab{a93TASIZ1qsw91xK^_8NoX3 zL({Gs=+!B&07Ga1)6RZG?SLVIm>Ep8X(Sy;oWp@>h-V`tX-rTYOBz{mB$Efbq9@r) zsWyHt4K&7HsJ3jU=)P$eAFUCy1UQ+ZTAig^V>fy5#!>a4J-*_tPI%K38xmpT>esA> zlmr$Tq9a(P$SB&VWrj0|^-_Aw`1exw&&>BZ6nUJLL+_>|!qP?{+fnS|!Vv;K>}@85 z-|nRy<3_a7h5nOx8s3$s69cp+!9?oIVJ;|4AqtTwgka`uMmW}-X`~uF{U#{N`T@`A zQIN8&p%D8v2b2#VhHC7?De3!kHq*ynkOD8kcBRZNy+B3ezlAH1-onL_g18wU z^fW4q&(}@3+Z^8KRiL8?lw!*Ex;8K<@}l{JLxPe#9hhLQL}te*yA&VLSy+&KWZiQ@ zt=1j!9u=gK^1BCU=R#P~;cEDxIFjb8jAmDBeNn0((g_%;YXA~yTNeju)2TT`!m?lnvf;C9=ObdsF zClbHUr zS7RFnCN)kA7t$X@v)E|Y^9+xO@IHIGMJGz|o?uT8y}4nrHq5Z_k~vAque7M<5R;G& z1-Rj+u=Xg|Z`@M$>;vyf5B)J(5$TF_0?~FHEVH4hyh%I$Q z==2vY3p}EDoj9d!TkS)`nvn}6tdq*%SmwM5<3oTVLm7#%s>#CT`i;1CN@&b-qiR9+RQor18D~EFiLWK?$N#IvU0QD;Y)7`k1q&fdulMkB`)KhI(f$ebM3xqu3=DXoN5u8Nxa z5(qo^7?Dqc!xwCd=zS>%knFl}8l4dhwDG~s@Zvu6K7h))ru@?U#S4}!D9SG?C|q1n zSX7Wdud%Zuzp5>v@$(DMJ12jBZvt-98 zU|%~Y%%tSYux*Cd^?~QhtFXlsf?(+V&$d^kl;YY|Y3;0+^16O39bm3rY>UgKE7I^T^eUNW5FK%kOj z2)`%@y&!?0l}V0V_^+tZE`&jc!+yNeO$dPf3OESb4ok0(IHY!mkZXuuDcue?BD$aY zo=6JHLQI&2;*4;Q56h4pW71mD0=k89=o#?!E)o+<9DWxt%TxU{#FEZ!)t)#6X45Im z2oH&nYDa-L#4ouLrDq)^4a6@w1t_(VRdZuX(%S?Ey4z9}Sfm@xc<(cfG7wsIK1~4> z_EpyoISvzjK%jen5`KjuFe5is9J zg#l$;-b~d^K z_gGx6z`Yjd8qmK;UF`;gDHKp1n|%rwn+F>G2SZ^4c3PBy{7adELbk|1@zj7RJ!q~p zV1b7$E?3|yEG|#r&s$u+!1q~Pp1==ST&}`Up#r~DQg1eCSNa@GhajbpnBC@oVz8vK69yyIB`Q~S}7(T`7? z_HXt35i*c}dB#A`nk&(yz<;;6T!Eb|jihn{A7*j6<`Mt$jDhxg(Keg4%Q#qzrXwffjfS1kn|Jzf)G*7)}uCrA9hyT7vuIbj9wtE6D zG$=iKxm#`v3K*PGQ0~^)f&xZo6f~XlFVdCy{(}(#7x<_~0i{2BZ^&JzEhu1WqnUd{ z8kK6ZoCX1+IXak&CNZgH8S!Tffuxsqrwpmdu=gF$`KT=k}qJLwOJ22((q)CGMa zH-Jp=O{O%Mt$;EwBpS@GU+_zX1eBIF`OBTm0f~lL`jJWg(vMI1Ei?!yYeAwRqaTsk z`T@~k3d+2bXqcrRnVaO(rqr$GIt#VGWqvy77ikmlZw8g)98~XqWPXO=akBNaD|5|q z+5|k#pg!!;i_Pzq{-c?j#r%{o*TbBo^Ot3RSv;}B6;#svq@1=L83cHZ`SB)mJ;Z6+ zF=vM>x3?Sg(S&Z;G3Rnrf7-;3IfB2#{C+t7KGwly(#dV7Df582nl8>qHG=wr`H8wX zC;j<{&5!?XuGk|2?l-8}>0BOs%#`|wo*Qa7X~rQxNrgvH2joXVN-IavkFY)PkLDn~ zpFcLuyl$?CQ*ltl$52*qe=@%v<&0g13A^mibNFXL|Ji>ughw6zO>l=P-QaPlqrg&g zq4d7wn!?AMt6tVQa{Ez(K8ltNUBo{ck)R9A&pGt-y3CPYY<>@!Yqm4y2;A=DM(3vY zD)YI533;x`JcrFEpl49Z8Q3}@H&XvBoAes9BxB}^A_CrSP-i$vH|OI8x6N_$&v5h4 zI`0g+b#vw>a|N~djJX+Gc&B;#K653BB=DCkE?3~MSX`dK4_aKlz>iwoJb@p#xB`K{ zZgEQl{@5XUc9pa7B}Z<~G)Q!CiNI%BT!FyzEN-5_pRl-mfzP$LJb@QjT&}a&v(#xJ2M37FQtfQj41>aIwYZ3%tVO@&vxv;&KHpvA7HtD69KDGt1yF0?PQZ z98bW7rY6mD?-7*?CiDqY-IT788r;FRZkqoUw>#BDlyOlXnkVE=mLCNLOzmv*hwj$L{9RKp zA+Qj3ma|ss7g7Q$z5DW%^ciZmfQJ||fU+at(LO3H;3+<8l{6<5jtBqy=KdcL;u~g` zY*)k5RoS3WECrOApN0EQXH;~lR3tky%egdt%VSk zE?3|uEY219=N6YM@UJY+75EK{%dqIBAKy1+z&Zr{g+b}(ejmjsl@W@laRn@${MA58D(#pb6nTSUMr zgPP+czr1xq?gBpc;4HpfsZL76U=c9&!AuJyWUB43{SYuQqeZ#9))o}-dov2Ak5pQS z`wvD0lsah^BNK8b)y?8i?l*Nv1+x&zOQy(=&6Nm1;QzF^e1ZRHaTx?4bxoNvXimU4 z?PHF>Qq}B4@iX&;G@RwE7Em69BG8?|tlu)vP1_b-f&XlAxdQ)}#pMb7ABXz8Az$F% zTU?&N|7mf#0>5Q(uE58eslw#u3w(mbK<|QjCoCFw-U`TtMkISgnA6 zG^O->%boNG1qD3CGz5wgPx%r(fXV*ZzUq2Z6$Hd6DngH=bO=;Zmz_a1iswjas}RGajw7<7MCmV zPK$E|zTe_<1%ANd3}go_eLK(mg6S1dx`W*$;GkdAK)%4z8x#{zI-_@(+(~y(P(bO~ z>|1fEX>E(&w~*9zpGDcRXy_92ll1w&>AtNzBWCchsp%1OrF9ed@WXU#z~u^jjK!HJ zY~Q4=z2+Cpvw-qAIx67NrY4jUP%58&s$MkJ{)bDfn8 z#wu`;#pMcofyJ5jZKG0Go+*RT3Mh|bP6RyPmJ(1ZpM6fGuKD&s+qQ--Hb0e^E3L4= z>ntu;;4X{H7>(3bWy)YQ0?OkUjet>GN+Pq)9xRJ|d}pi>*tZ`l3apKQ(NA z`pkzHdD#5)h`I9CHt?esmn-nsEG|#rX^Sfm_@Kq*3H*-5R>suj-ogE`8gyFO!t*4CD&@Ydb5_O=W9OuSxo3NAk~1 z$*8IDHghGS68L?K%N5u;Lbprh1U}W`as|$}I9K4P#bxYM>Bpb_0X7NvH-pkUQ0_ir zD#L~r@S_H$3(DPjwxEC)&nPH&4Yr_wtuqSBU7IZ^pbTwxKA1VU$ZUg)OvvDl_FISu zD8r!^A`^1Az!nrxhNBD0U7al`pbSSBl)Fw_P{7o|Wh(tInB{rXU%3VWWsuoUB3F7` zoZ1Z?(95fk!NEp1^C5)Dy){d%3yP zAkpwVfjx`M7r4#h@&sL`~H%7a->qkuAN@J|caVJ3^VV&jC| z$*^Z}WM@|2EY-_G!H^eFDx~V0XQ@6zDrHvRBGn6Rz}+oiYV|F%RG;A&f5}Ynul2qBvi%_51eEzE_26sfiSO7a1$6!CS|dHJ z@KGTFD}B_OW&=v+(PVnx*O_L9Y;ywc^igXBe8@+I1hk#HR61pw%LuNHnF>B&}psPv~~V(hpwidKW zbEP2){5Ols7uY#Qw@c*&KHlQ;1wO&zGKMH^{=w9bAqx0+gVIBkJE;r>(?^|e+BrR? zJ%Q(1T&}?9SX`dK>y534G35)~YjJr3_gP%7zylWN3cStY@&&%m;_?K((c*Fi9h0dJg9Q0`>1X4&yF3#a+L3kfJwfv3_tj7^i?HIz#4 z#4KCuJ~RLC`RmZ|bJOzg{T?)AnNck82iTCl#tTj9GXJTNfVSVO>P!VPW6C+~gA7q9 zRoUkk~%rX~etVntpg?dcJf^BlA8T5VTO59iA zFIil!zzBl1cO;$)| z418EXd2DvEo%vuy9+XKy5}bhlV!A+eMJD7Om0HI&|c(!ZtuLI5zLq;^?`S?sDOO<#mWpbX1XvQV?=$1j_wrtC-r6q*EU zl8S^ffJz^TOvx-y$@ph^DrBan-Ji840oNPU?8`0>Ug|#>5is?^%%vMJ4T(Mnw-rVNNyz#II>l8(T(sS6C{Bw(&C-Cy)^jMf#%FPOc zM8oq0zR2S81un6;Jb_CsE?3|xi*p73yuoq9a&xyWI8WevEG}Q*35&}U_+E?475K{* z=L-C~!EwXs3n^3oikT`5FuvnawlI6{1KgYOyG(=xY`w;IjrbTR7*Bro+?bilajL6LKR%09gol zp{WacS^k7{qc0UH9gzv+lIdgmhyR_oY@SH~qF? zp1=bZmn-lli*p73Y-)w+DO5fOi-a z);zrjPL}yiXaVFZ?e+ULg{3{2s#%D7rz!n_ZOj$;J&P+4*f~M>g(zF#vn;Ma;Il0* zLtm0MAM|_LB%nMtJ2l9Id;A9@0)ER!H3^tnS0;fJm<|@EbX4FRY5$Y@7n{1U4+NCQW*?+HxYB2o9fJ>8T6kq9VN zLdpmzHEOz%JE?ybakR)(dx2klNI)3{SVCq+8EZITDi}0Z+Wi7=w76V>ud=v2fv>f= ze1UJaxOoDPT3ms^w^`g0fzLll&n6VqmmIlSYLMvQ5`mXlT!FyLEpDE`7g=1sz$F%! zCvd67EY)Xls?6TENcI2a&%{~*rJq!NONLo3rLxR= zLuD7R$VaV}F5YfY>0_3Of7kCpNWgjiQ>z4&x|K7u)gSVDTTVb}kjtev`G9HaIoqUw zQa_lD^!-l1_6%ktlW?kEq)DEtv#9juk1{`{v{i3V((T#QA5-K3b0x+m@Jkk#FYqfC z=L-A>i^~`IJ&SV%c8muDZR87_YjLi?MHZJY@FI(I1-{7Q^3!Kyr)mGk<_h*A;L8R@ z6xcK&cW>E(0=_+?pxhm5T1AZlx(20dl)E!+K>?-bx}e-GwFL!~q3MF@gL}brOh$wk zyS!;o(sz2-i>X$62~>JTPi0gT${c1$`nkgIXGX{*v!aH~iW)L2YDn+VEJI5#l3wv_ zQ59L$-dtmXPfzdn#b)|S%$2s9z?WKF zuE3tfWhmE|ncvz{$_Tv0;&KJvYH=BLU1NURmQqIGQH#qJc+BE5>e^|3yEmnbz~8dC zT!Hsl+=tfn1ycqaPC$8V_U$2^kkYW31x$S~(^~kZY3X~m#q>pd$^7&~bEQQT_{SEP zEAT58mnZP67MCyZ&n<4Az!fL!*3m|Rz?Bv^Pv9zx%NMxX;_?KpvAF-u-kU(nQB{4s zm4Q$oLNN#xWGF(w21PrJVGc6_k-oXzmjE{dh=K?h0)#;_fXrh8D5yY3W&|}LCYo@ z)3iD~-n1ILziAnKplK;Q!L$UPY+4K-Yg)Zq-JjMv$zlK*o;(GDV>ME-K4_7T7=jZA z7}7dQRWSsoIH?7aZpG7Qtk$bIuLelr<z@;ThF=%N4A5 zdClhidX*0tXSQjq>r(9nH#ECJZ5m_Dj{I2<@^}#@+e_Y*tLiuFC{E1NVfg@Rv+W;7d(Q;jfyO!EdV8`4Iw*w@QZa+oq*(w5Hqr z2^^ai!z-xP>4e5gW|+Z=X(_ylX$hQ~7Q>@e>vZB5o${ToqmaD`;#Yl8<9M-iY=YN2 zsRfo}Rh-@G@S1ZBeh2c0fk~e~ln2!0Wf!FZTHxS;eT-ITKfOu;zyqDs1p8I0t_iW4 z<_Ho%4h66rE365z_I9y)KmrVk_6N(c!uP0?HO3Sds|B9wqz3o}m8!=`tQpR+2@*g` z2$o}oV;gn02w1#junn^w#Jz2Vzt0;IjI58Q>l84#Jb5jHbDZ&7{PL^aE!#d z!o}(V2_Rzx%dx^Sa`zUEm7jI+-%Ly3f0`CNp%Lp2msbnKU0xHw=gkTvcy$SXp$>mE zM}NOQ`0gf))Z_)d<^zU@f6&fYc!X)efQj{vWd!0b0|wXANHWhL!K(*6R2>p?^aotm zTch-vj|Setv;^MHv=qKkH95=|Ml`-&GK6n3ErI8m7Q?HoRixPo*e&BvsH0Q^B&K|F z3*M|&MS*D1LB&VB6l8A~z6ml6nG%qIdH80VmW2cx8l!D`nBRSCi!JJ zRBtUlkne@{Y!|qXq)9_+@;`c)G%CtO01DByCVmEA)Y#X$41yYEI{hEktIRMsN~NLE zvGNzQv^I5W<#%rB-MuXwIBv0yllAT)dd>F+{CU$7_*Bz^oldO7)JDbx;#R$fXRE_S zrQqHNq-0V$z;xDHamV(rjk%whS(jsFq?3VD2F5xD~8j`~SB*o&u zq{XC*AxMgaAuVP}3_(&X3~5=y!SOfm+NI9WN?c+LuB7sdOH9)qMSdr>HXVn)b6}+?gsV4J) zB?Z3Yr2a6ee!62L$;TaZcc06k0lwy>{?N7(# zy2#A7*Z%g@tGrDD$E%ckPF6nD%)sMHW`3%}wIk+8c2=0fMBi(cMm*I;mQNOx&o(WA z&oM29&owQBFEp(Nud!~?d*?kmjZ{T>iKxNDP0Qd9nwG+Ao0hpT1 zh+(%pE_Qh|LA>%#!*_i@Qiq3}V`C%je0#mh5(jrxNq$!`_~rV`HNx$BT|OEz>zU#^ z(%Wb&yO4d1ejk&-9+l(=pySluj09>GEM6)zbX139qprQIKI;!Q}=o+Bas+T-RniaUAlUmFhlO!*PV8dBej3#(3WKEP( zuZZn0!I#3(Em_`vps)b_OE3kqbcmU zmK(vOIf|F*HUHTGOwtv5{xXefk@^|+IWBnrNjh3GtqAlr4aA_9lV1!h{{4nF5`DZc zIzHlGa%j^V`4711_dDQb}Scf!-Q1Pcy{QkroH;>21@bdcayT}4d;MBAj-r2My z^8O?KWo|qzkdSiVfvadFIcULERVofkT69@)SpH0V`i=F7*E$y7OEdbNT0dc4o2vB= z-M#*_R9;W1*GtyddfLZFyZ80nQh7BrV2@t&hXQz-X$gG1X~Bne#2T+QGD{%tG9Mt3 ziiz{))Ff>AY={@AYTBrEjw2pXdw%XWHiot78mrYFYwsZdwX& zX<7zvWm*j$ZCV}P&9u?*;TskMk!Q{YgK2zLMVaW)@DZlf;iF8e!Bb4j;Hjpi@Uf;P z@NuTa@QWLl67-8sMR(AVNzp;_mX!k%vRGoY=%8YW5q_Kt-voO`7P&}|Ac6AN#2MW( zJ=lfn0r8jLSp!R<<_4h-(5@$HwIuN+7|R*j@$KrJKW@PzH()Rg@Mx8CGx!T;243o< zN#K=EngH&unM!4Dm_e>*l|>rQxD`-u!*989Ho$d0M8cE6<7$N@eaxOg<2n`dQNVYo zCQmb9bEA?kjZ;<3ec?+~6JPK(C-s4c>XOYp;q%=xmh@=+tYr9zGE<*B7g^c=e_!YB zq0$`M-GaWM_iodxqzW>(6;F{we93u@^8=rz^U6HSUmbwVvpfrf?>^;z{MlaoVbM%^ z>ouYsb~4HDWQBarhix%ZR@bl*ZGV9cyz6&6QM*0QmMus|%SR`7IvBC}$Tk`&R87-Z z4OOavEJOOV7+KY7Aq&gBFU&o7Plp%zmUFk9 zda4p2nIE`34{T}0Kkd%O1H&8+^s7En1DIDU^a`GWu2V0%&ohT#(R=buPBYsy2D_x1 z;8?dp#Eu4okk?T^)9r&y$A_7Y_r1vK0hiU$Bil5dQ1Sip15Loxi0GHNoo|w$f!~m5`U%15?k6XnBij|8CkLKi)O2`C zsdx%FR!uOK*K_b@y;W7{BZJ8O{(x^+lY8~rSt~UDqT>6a6QilcMhain78~KostAbx z@NOnmubM0B^0$sw=c;lp|K;lgb&SNV(s9%5Po4>c`?-)C9|ukn#0 zZvH+kqLHd7@6$4PxM?Z;LDLdAGcATsR;|;CKYT{El4d9Gd_ek^cOu|g8cM9dwN)zK ze$k@Oinm{@X;150k4I>XX%^nkbNEtueMr5ww7&Yak56~+>my6$wT*i1ZGHKJ*zw&> z_ED3w^}0fI%!25WLGkF3@#qbM-H$c%Gc-Ep(Wp&}DUyFDQ&d_^k^GDC@?BKp+q5Z6 z5yMaYdd=rMdX*Khk5;g+dnIpPDzAIg>u1*2*4oGJ-TV6CQhEJKy&ki^Hqt(}?B3VI zOXc+!^?KI&qWBwj@9S?%<@J(!4ecKIwRbm}rQWCLHUDfEzTC6~UTc$L-E@u`8f&YV zf4~T5rp55cvNMejnPCFgO^e|@%g!`DZiWfGmua!T$QkYhRy6QcC-s6vs{Uw}SaY0X z6TII^Es&UbtY({5thvg|7Dxf*V6Ew0MpkjwlEh`M#~zTL<+&Ox4=DV5gXOflbu1|| z*uf-_Sn_gu$4tM@gnDm-X=pD!dd(Lje28fYe3)q|{FZ96Ko>?d-Yyx!@0gar(MOAc zE7sn!WdW270T@CK$OaNV>R-m@H##>dSth4(Tof%i5oSlpCvKOLEz;2;B(hewd{ z>EhP7Brb;FhI*?oq(wqv2$Ea%b|Je1Ty{;c?W7i1jurj@hgiot#~zRXvg*NdtZ>yo zqA{L!u^J#tMfM%TW^O9B;y*M1g_S*x*A7}jkwB7??Q=u0eF*j55@={IY|~QsT+$tjAf=Nt10;!xPeiWM3?6f%Y3!%n9p*A!mjAPFc_(6DQ*VS9YWB1=$huBFP-?>a6-e>Rs`gva;s)QJ1G%4Cd8f^IYO$H^9rB z)C1n+q+XC&k~~4CM3MrT3b6vm+Ju3&NQ2)&{Dn@JRlRR9Rpe&Eo-X}8emej-p)nS@Bg6y+WiLIW&XkOM)ykVmO z*#@OEnB`Wn%#PFLWi{w~T&2=1*sDZAVVQcV2^&EA0<9*&I4JJDZk12)`{I@zQ^D$@ zcC5{cadJSh$fe8`i`(z}Nu8%*w%9=eRh~|h)&8@3&7a5MlTAzDvrLQO^Gr+N^Gyrh z1JLK^)J9&vLENfeTBoSPEa%ubMG;3i>-^HpR+Bk;&4&nIYgz)|Xj%%tYFZusmuV^d znrR6fZCYfM_X`g-tqw11S_;ReC2(R|4DV=~E(EIra}7o{7J3<{vUev(HBX|rm_MRL>lY5bQ+*}1si&dTJNOS ze3IckOiSQb5?f4j8eze*7nbPO3F4Go>TlIwEINmun!LnmGd*ik$a`>cP zWtV{uI4P*j$=c1QHY>bkf*0sehnd$O6kjmOAMjZk=w`hRjy@iI2u){qxv`A{uh&lH zuZ(V(`9p1xNk^pdu-=qkAO!ZtdgU%g1aItg===(QrGv)zBb`CtO~^ zXnNJUG#YvnXPy`$2|X82TeG zR0eNz-49Za!q6{Cq54%RRKGA&G~?&=DyJKGfTk_qZFa*TqP^37xqedZ8C(7%ZGU9B z#<-Zlsvmv(vAQ2$ezeN{=ZBLO;%6ojp{TA%erYR~R$GVth@0gGNF^kvxmAbn+?jN_ zrj-@URO&c0@zks%`g1u|GdS5Y0T14yFqYp2qf0_oe9Q544REOi0w-&r!O^rm{Ybgy z=Y-9=Zh$=?1FUl6-eQt`Nt0VsGm@RSFly7H^vg!m?wC1j{mH>fbT{aN(z+Y|Q0S1* zvZ3Y;3gQ+jL0L+L>aV6k?beUYS@3Hgekz?s@2}{NNFt1`BX;X?h@0Gc8(!6|oC$j? zl32cR;Uo0vA)ib?k*W!PU1yJO^3U2dJU!;W`Lo%`ljT=c>G7UebS#5|K_9yxV3vsniR&KNhMnuHzh=;D?;l0?V<& z_b^k`;aGE=t@vfV%JbWT=|%Ewv>WYSgL`Oq+CAB)o&VZsKeu~}PS$&9zq5Puxrg?& z-J8cfv^VYEZ0@10uyxUijG@6jw6*MBoqK2>v3nW!(6+OC@@wkF_|W#Tdy77=_t5(7 z-a_u79bxwta1ZTdyEpsW8uJ|0F4U{69q@89pHC>Xo9*6Q?xEdn_o9om8?;~8y;=C7 z{lV@{;U3zvc5gEGiqQ7|d*~K9*liVg?NI)_Uge!9I9;V7(bSo38W))z_(hefo*@&x zM>n09E7kCq$6au7p{AUdd1iX@IDZH|237nc1!^2I>;5AK4;k8Ul z;I&N)evZLd@6$2JOA|=iva7&VHB#}ULyLUG5TwiMMhy^PM^CB$Ny-ph=2i^V$Yy5xMvOxMPU(h`R^G%bNQ zHZ6rGnU=wyHZ6q@GcAFqm=?oFo0h>-O-tcpO-tb8ObfOuV;!Y7vQGC#5aK{}VM z3et12RcSF7;tQ7Z2)F8X+W#1rN3d1*)my#YO}ItA?w5AX zXX#ik*K7Wg3EyB^0{_UgV4V}|t7;?b9Q>L}#ag9BFfr_w*IXB?3F2KWOj;Hzc-Ff_ zV-P?V7l?Ne%TEGFM$vUZzT-UY@ix86KiTA)MBKZ3F*XbI-owu3_!xe}vIQoE z{iVAHT^u8mL;3c>7rSDRI(=bYwd5*nhT_k4jApa5Uh|~{?`m2C?`~QO?_pX7?`c{M z-p8~$JWDls&pbb(aZ1S$KGn1ue41$)e1>T$e3oemJlnJwetpNHES+R%yrrU4rVhVt zS`CiI6wYFoIW{dFtUT1T1YX9p7~Vj&PBM}A-+r3?A$pZ(Zjge>Yr@%j_Y$)LZ*@|y z7dmR|t*f0$17uwC+69uXWB`(RZsq;=O^s>YH^9MT3R`&}8U~u+#fc{C3|y#J=^nhr zNxcLb?qUa{-BYdicU}$90!<79P4qLGtpVB=2(MLK_YIJYs=o7SW=~f;Ez1||MA9Y?0@M$LnWn|ruhV0w0 zufVIWmEK&h`MC`rVp;+pW?BrNZ(0J+HZ6v~VOkP-|B=UJwUL)a@KY)kj|#M=n<03? z07F_|GeeL>svkbWRGL+(G~1+dlIx)f(s}WKNb5>71k0&3+mZJlsqE(*dq6tRd+2eg z9ASnaofn3*t~EojoJ#mc2uErt69kqWTfrD`WW@3q4VE3l!Q)7N^5H#Lb_`RUr(?TK zulbsWSK2A+{3luhC#J>l;id&^mH2c1welO5G-Y9dlp5ka^cs@>80+cI{{Fhm%?Mqsa;(Sh>34 zX7MX2vHb4-s)cw*uN5ZL%uIqe%FhH*g7?2ublBJEHQz??eA5#6UekiN8N|9>ZKNO| zZq@4)$6K9a6D&K1>-02rINLckE>*nTB)_=aBDp2b6GxJhQx05wo(nXYC-jZ*h#}}Pr(_zUmtnxy2aNR^p*dvavn`jApOf;WnsSfZI z(-Qb-(}H>t>r-kYvkl@_T`wFDc8*Q3>=@Q-PjwjU9E1JMEizf+q;Mn?S%To=lbWT; zoT}G+3Bq46ErHK4ErriFErY*fS{?qLX&HQ%X(@bw zg@0pO0xvWzhMzF44nJvH2LH{p6n@II1YTrX3@^W{jRRiAvs%hbk2th8E=)U+}j&`ofSFH55beSv8bYz~=_|(xNuv z3$Ct1Ejpn^0mRTh_!<9=Ze&f6B`NRJK!%rxZ?HtXj72_~2?O=}fkx^VeATKGPET1H18hFfD;IryU=|-*eiu#NT)H`MArp2V70vr6Mc)Y=S6=yPG3q|@`R{oG|^9|(7h5Z3xxScvULxhG4dLTI7 zN&6q9_<6mqr2Wi@);gi{O_kg@R}J1jz@UAp$~L-j-&E-qy~^L*3~JM0JR%Mb#5BdFjMq-uG+{5RhIl<<)Nk}@G#R-czM$@ctz7{aB5l| z-dQ#I@%Dm2GMQgLgMAgZDHoh4(Tofg7g9@Me1!#ponMV=EQqFsQ?$O{>A% zn3loYnU=ykn3lj}OpD?DRO=)|W4syG;r&gk!3Ua_!4phN;Yp??@MP0s_zl%M$@mMH zHMG8#RF)a|Q783+d#hCJG+MLG5ZqDwEDUKeYI)QFe>=dC)*n?BLy%EaZ*qpQu1lo} zvf$+H3P|F4tY(|mwa&K>B=N$K784~A!OxV2(QMN?)eWN$WQ0XTS`1Pmg5~jsudj@k zxso5yfovvuqYaj0g+H?!spGD>@i!>RM3W{d9%qujmOi7m*g=v3B|FenqMv2S*u}~p zbH!%_#AarsQXqZ&Z%vY)UC~ds!LtKo>4N11TWwnGfUcXNs^9RDl}=Ju;a)0ys7b6y zD|)c8BoBW~RCu%t)JJRr$~^c>yJ8WGwa!j=P zYMaysMXRsceqQx|ce(G^v|`W?tLtlel`Mwp_?LHeXuMx>U6aDnG$_saW;I*!3X|q4 ze#4}Biuaf_U-8E#J*a52+IU_iwtPhmqmLJJF;uVllQLX0ErB;OE%s-TSh3p3%Lj;C zzFop)TUUosrQq-urX}#!rls)Nre*Lsrls(?rX}!f(_;9Cre*#>$#-+Lk%5A^Eq5cmump(psM<(n zK-{V;6YZtzP_LbJs64{71g@DD!@HW6zn%Lmk99p~8CO>r-i{6$T7j6y~Z;$1x;97#^zrGsV1 zFi#w@l0QG6+!)-+EBKhMp@}#3ny(M|IMWh%mT573xoHVJ*R&YE#x0$>W(byh2=#Ejy$U(fT z2ZSTZ$@&1xj$xiSVkPV2kZ$W^o+f^qUi0+GM;-kHbg*sHPofi(}k)|bZ-Lx3q$Fu|$gf&jpq2?Tei6=HG%P_&+)vG#t9LYo` z9xOYCN#Tf$gta5#L!D#r0VT0XS%wLgV}}puIFgA>C|Gt3lbWl^T&351 zlHhAhOW+$!OW_+$%iwvY)!>IstHY0)R)c?MS_c2#v=siMX$id0v>5)_KE(+nW2^fw znvDN$^^=N&bR(Z{fPYe}VhPboG`<*ut2wC!l10VGC1DaxlK7>|s~4n?VmZ>X@WBTI zVfY@xFL2@eKt`2^?`hMb8~JPiWMJ}X7Dy6>uU~5hKu_{+m+()xJQ^U~RJy8 zUZ8mef5F5pl3n7wL&qhV)VeN#&29C?@cYNQ6`8<^X)!$Bv;>}PS`2^1wBUi5JhrtZ z3F1~PXMehI+|oHV!Lnm`rr=07QfRR37=E_7v-Y%)>#+e+C0PyNiaKanMj$m3tNryZ zJytBEJ++&bt6shByXC)a;1>ozax1m%nG(PMuc)B1Ec~(?#t_HkHubo#9w8D5(ET9om=lDlZzK&F#c6 zP;e@qt^v#|7(KVFj8#edHCtB8$_6U!CDwrKIOc&3Bvv5HqT&HFjNPIeV#_}oU2hZp z%WiGAK%#f-{M^@2`wg6510=ruUgQ;emrxZy?O32D59&34L4h~XxezUZH#IGWcQ7sS z6D9udU7{_Jkg~zRQ5s1OVUSLW6PFfUR=h+$tUb|XS8GM{+!G{CH`mEYWi9y_| zlbEFrrq*Osm5$nO1{e zF)f4tWm*cqZdw9Ix(4#ufm78w3DQ{03`fIjn^uR{HLV7(XIciYZ(0g(U|Is#O^e|% zs&x|d*Bw(nS4S&r1;lUhYvmf}*aXXt;k%)W)PZi6xW})kBa3vA=3Qcjm~P87dMcFE3Yi1&XN)VBD@)@~L8TgWXO&VLTWvR~LO^+~1KC{ibVVSRvq&JxiX+Huh!tqF9%R7G zKCO4et0ItPTo3_w(wWb9KD?W03H))>QuyR?MJ(~n;OVBN@C?%uc$R4~ytY1;=kdDb zyR-Vq?g9xZ>lmD=R>c;l)vHg7;tL+(q(1N*C$+$THu>b>H}-~>9%AK z?&PFCaBnBIz(btW2Oj057I>zU`oK9(YJp#OQXhDmlUm>dPU-_6aZ(Fh37VHK1M@vdy&lu690+)Q%`N)I-xL$Kj2dewZebF0vyK}| zaBR%dZm#{m>29`mbLIa{cNFmn?QWUqnCR$e1kI;ZUbc`&t@SK|ReD*)-Sw&=sPcYV zZIwAaE*L0tT--HK=6rZ+pv-~r0o`R9n-gH?fiheEa|31e_;mwiHuc{J%B+x&=t|Kp z*|z%*l-Z|K2g+>BFAkL1iFXW?*?PYpD6`jM-A|f{ZIFV7>U1zYvQ5DMf2O2FTDJce z%+&wp>Gca;1%KA7{OG}7D4DLK5qiy^aNv=qCGZBOrSL|kW$-4Z)!++FtHZNRtHE_8-^*L=z+LZ0`j+JRF24C@^d0kERbE!8#N-MhpBz1Z2@F$jA zhiIUD<-!-4mcW;p7Q+vjmcYL@Er$PWTGB0#^VLQs5xiKXViIZn*bG7XDGX^nW`-b% zR4)rkLjN+AAf4xq%{Hy?yB?Y#ofn3*{$z$=IhAl#O;ZQ@mq!LVz0t+$3Bv~u7Ga=9 z7^o2j3f2pOW@-1`zgHWJ)73JGrpR}5m%qK6J7=rKu#Sa%J+`(PV)s5sm@0O+^w*o; zN7c7{`!*HZ$2VC)hG5_F{qCJk@l7H>qI|F6P~T{w7U&7R=9?D&p#B?7`O6KQnHIz2 zO$#<7@z+or*^J;?DivFY)=p*!?lr)W7QI%y#DtwTt2%AA>2wFzX%nQIV%yQOPW64H z)$=8-AU(;yf=2k=T=;QeAbo_lKy|fd_%c8c@1kVpQqW{|JXo*!T*5O=OW;|irSK`H zW$@{y)!=paFZz_9J}io8WGYI>HF!PKGI)K{Qg{Q?61Z+!3{O?9(=m-{W>|xdH!Xut zG%bZcZ(0J+GA)KLQLWQ4jZ4k2247}c27kr06u#WF1fFYJ4Bw|(r{ivO{wbX!Su7xa zi(f3CbB;~$YA3b8a;)&Rg@rfWIre}AkXJsi94q|gxL<0F59+ApQRfQ9>rL{@5PD4r zy@Fqr488h8ui)Lz?=-`g+-MtM>N4yN0|hUDf7SrzrO)X$y8SfZ;Vy9NWW_T~GW&uK zSt_pu>h+*r^Wy`4$g~9hooOk2{sBb>;#-F=FfD~IG%bN=n-;^Dm{x}`GcAR`Y+3@( zH7$l$JJ9ljKVVu4uWnibuVGpYuWwr2p9SjqN3D}=O>mN?CJ)viBQAC;EygE?;1$ld z1zxFA;Y;gR&af9G-RdKOR6gSz8{pYaak-<=5vVjcKtPe^Y6Z zUOQj;M`L-54$^V{b%B2PSG4RbFF8o43^OVc5iHMO4-$y-be%N9Q*AK>313}!9KUW= z_D2&ItCzZzCc^isYsrpxrE7tws#Ih|>oGI*V@=Upr#O?II~DIT=|07unDnTk#SY$6 zkmn@l)dD~3q#lwy&q*!ti%#kRzv`smBZ#Z@mgOCoEL4-f=runK;U`T?;HOPX;eGU_ zBR>q`v8JW)CrnG=hG{W8%e3IIA>Su74>@c=+^W|ej?X#ACRlb1U-U!Ao+`)i75)|N zX{ZiIP79EV$j;eU?>5Z}B(I7ygg48(pbX`Q#ds(fiu%$_<(Xif1gr<(_GK)>&r+?^35|2jFoVxCErl;IErDm77Q;VQt<#CW;#dfu z(K^e~2{JA6paA|-t%^NFE7lIg5PY9Xg&{4~L@@*}9AHR`v58@~kzM9S z)&wtiQVS%-JmF@W*4l1lO>i?OwLr2id}*EJ44dF|C$&HZQ26>|xJDEGmP@z+-r=NP z=HX!{HNd|*sTcg4O2g#$AEwCHrqX89RGc{#ef}4s{n+K!M>LjC*OlZKXpzQv&yK@& zDwtMziw-iavK2t)w3sD-@m0?qJ+RWdE_y#)#ajNdX8R4dfEwU;ozw(>pwi0Gv~<{% z;{QHUd>fNrzf08gIv1q}yvs=~kia_zfsc;r^1qEco%o%W?{!I|t$i^lnGKLW2TPxR z_6yYQA-(3WV(??8CGhV}OW`&3PdoD04funmrSRIOC2(e148Lw#2LIc%6n@jR1db*b zBh1GE?_*j9k2NiY_cbknCz}?->m3wz{>#T(ko`aP{EOB}b^u6exev^w_iiotxxZ+?U;T5$9SvTNtC$&IQEcPp{U7cYQJi|#XkgN+| zTH`cfDHJ%hG=^rI)*Leg?-*c6>tQnlhw6+KUDNu2s?s$`p$fyu`_C^-=i`M5I#LGI z5h*;$cf__PMxq_jPq8C<{YHMrk}=&WMz<5MK-M0u1nX? zMhyK_MDp_x$uG$TTJ}raLTi8zI;lVGuAlC%(bMU?+zW=Cq0tY$GI zIQdt+;{ImIg8M_pjT2oa11#kfypTPnyM@RypJNhusY*km zsW;4Qhdqv?$Kmc+9T$23ZKW}G)~iesxVK7ibWA$zxOCWBZ4^td@hdg5dN=5mBAY)7 z`MfWWEN@NL&x1$ae;?Dx)>-qXL1#@mTg45r3DV0l(bRm)d*P$HdTgrK{P_gl%CrRD z+O!nj#!!u< zG}SuEbgR_qIttl9;CG!g5q#W9Es&n&PnkeE&UbCAO{=A8h#`2mlUg9jidDB%PjyK& zLGqJx5hOo(!UCUnj(ylnwOOfC3#&&k$$7 zl9TUNk!I*M4lj0)WDe4Qb>{bJ#U9eDJcfWan5hZzC%e7X0O@CNG&S)HI!nz@)ocDz z51(dQ0-s@83ZHLU2G23A27l4CI=uWRi;U#ebx}lPMHTaxdUz$%YVgXYW$>z|rSJz# zOW@437`|P#PBJv^G{ZXlJ=1FN-KJ&m_f1RT`KBfC&rFNq6%Q#@hQ=x?=9Ph0HLV7J zz_bir!?YA0Zdw9orp53ks&y*UZ4I5L^D7TQAhROxi@?=&todqhwP{f?F$C`&U`UJ6 zh#|P9CRaqHMap8>E#WI%!cFjpPHKVsmGWq|X`Q303>JK1fFZ4y%n&5CJmK)iiEPO) zyHt8W7QQ^FffO*0CI51rcE+Le!jKj@i=ki6|ItK$>k@8&!`$F| zNo}N)8sMf*>IJt@iJw}~ru^~_G0ZG@CJNK&qXP@n7X}K37zX-Z&$K_xv_H%=SleT? za5larFbT$6*DbYa=`4V^GA)6(H!X#CG%bU7H?0QmVOkyjglVJURX^np#03$JHB^)X zaWtHoR)^O#tp=}US_ZFUS_)^TCGdKt1%FsW@pjWe$Poe3wH!(yy$p?J$VU~lh@Wr5 z@T+0zVVvus3C?s|&vI>DI) zzpLvYyPJZ)8&VrwBK_22_2pGiaMP#RsNvDjGMj* zh5nXHqye%f<-7u^Va11jbxmVbX?4NdnwG%(n3lr#t0phi^CKF+C>g>Jn3li`OpD=X z%K>Tp(+pF1k!cD1nrSgS<(LshbY0Zu1YNszhVJ&bDZHEo8Wa$YJufg;i4yr)16}vNC5e85iG|Fe~WUy#@O9e zqTco^QT6T}zZG;!lK=bNZ>sx6`jyxU={n6>^`8K z%2CI9`Ikvx=4O1(+!^$Ft4pH=-ch#mCwQpF-A%7~(a7{cb*w5Rew1!tA&Dkq^n+Cl zn^>h``)N`J#+;|bkm;c+P5hX+B28LE>pExM(qIZ?fnIXt<3PW07F+-5y6o$0EX@+2VaN*Wiq%-zGbU%HPpN>(K7iYknZZ z(PxVycV63-6VqaNxM{((5dR@p-4;mr{P9&I#Cnx+gUhK@jGGo+Ry_I={!!}@uhlKQ zzkIMJllPL8AL|+I`CpcSZ<1*yBlVh>9iC-c0-t4C41dYA1fFYJ3?F`kO(Q(Tv>3kG zv|t)Djk}WC$OM6_sZ>l5t*@FPICp>{t?SJYB$4W+-lM5}RJXZ4C_NPK zCX@UQ3G_QF6G#s79v}^aH^Sh-fk^NlY4Gk}x`YMeUnw8=m2TJ<$9@9cLy;HDqr0VF z3%`%5Z+h}=WLf!P_R(tZtJh`nv0NO}WPZ9$t>1(EhPU5CRADpJH+o8ozN(x223;R$ z63F6QM&9tr@5i!5zF?N%>26pZOPc4JC3yZoOPUv%CCKj4-rs#FJq(4sWdo2i!79Er zHP)_6HSzljO@fU~M-07cBXf^ISJ`lngsW^;(~Oz%d^7qfhc;t^w`#u45Q#I)4>V6Z zyG^g1w_VE19a&iCukvtWS`2S#S^|$TErxG1ErIVaEr$PWTJUm1zHe%d@^S;NsBXoJ z1FcL|F$A|AU`T5pGX&=hFr;;(8G>Y7{klZX%Q(j-NS3){vrTIoGX%-9Fr@VvGX%-9 zFr;;z8G^T~R2b6wwHbot!G({BRR8_Xv9+lpxl8HqRq3~81^z*$;yuh5e}Vq@Yr;^; zNuG%PPAf)0$xqgFJAV~M<8&L=d5TnC2Jc5-OHHgkO^{v&PRe33-A!Xz2EkzPWL2L07zEFF7T(9|w0WUHwfnPK&g zS3EHq9PJpqwh@(it@sJt9@%B2~HS1~PthntqdN0^quN1B$xN12wuQ%sBD-hIjH0xyQ}o<~DzWz2r{Dkgh-&16THQ3E{DN&N)6)+F#| zCpAFIQt?BpiE4d>^BM;prP7dS%KV7NDQ0)4;{9bi)&N&>|ElwIMId1*0--F?VB7X- z01MQM7YS6HW79(~GUFPW1i$!vY7nJ?H`hgK@}gezJqo{US^~deS_;2uS_bp!mc*;U zf6`C9(=zyR(^B{e(-Qb8(_*-PYBAhS$22CXn0E|MHZ6k>HZ6q@ zF)e{VWm*hhqFSe88kd@34Zh5@4E~B~DSWwU34DcV!Sf%}`){2hIRrq8D4Pp>($#KC z4Q9w<1~R(hn4?9CVhEC1^?68cTWYUztbsc_sRfcx9;?}=^|CW;f^Rvg1(x#&kJtUx z;SlH8055VZ8X85w!U^v=_&?%xCT7d0)uBdX&lE8*VF!+ zVvwg0%!*7eu|Djo(!iQ4314nA4svA541mOz z8P5pL0ar0mS8LGkSa9$OCrtoL!Bc|o=`z=ED!ML~15 zgRAtKzmCB_FfD=So0h`&nwG&oHmwHleN543=TxV$kBa%r2|U)c4BpqY6z(xCfybK` z!X^n>D&`%-qfN`;ZA?qy?MzGHF{Z`vX{vQb+^zK2YN_Nk2E?!W1%NsGmUC=^ zk2|RamScs7II-?=jy)g&lCym=)k#42C6I7zI^5@=u z-m}$Yj$ZRE3SVYg0xx@95uvl_Xv8Xta{?!(#qf->GmTTtFoDl9Er$1;R_eLiFutKF z%W?-vNKRRBISpUz09te|hTs>}P{M(vQE_OGQtNG8_QwQ27&=Ms5w7A<0(S}|f7%b? zCBLpZcV?TGr4)Qs0kIg+QjhI(n)fMsmAseN30Y0AB7tkERQ2PthTa?JY>toNUegkI zKhsk90@E`1BGXd%64Mg+GSg!CYo=xJwWg);^`<58Jkw(McGEKWPSaBOF4GctzG*T1 zv*U{eFB>fLmp=78Q~l&b1;40L@pw*at{H+i3^1hi7c&GiO{9oOYZFzaYj8Iw^?`d0 z@TGN_8G@G$Fr;;jGi-u44lty3mow}Gsb7({U%>-(oRm#A2}sR`{ETt6&>hmX)K(AUQRtm@W9s)h3ftHVsjy4;) z#fI@aYqrstt`(wV#$PgsyQn0dtXq>BJe#*h;nU=yAn3lk^ zO^e}YRqJ#@<3%&f;FnBG;a5yc;ON96>%0o^3aWKFp^=zj2Cr;d3a@Hf0j!RmXJHsY;t&>_{Igjui!RG3)qjPM4 z%%nWGep~O}tJm_!I%rS02>q`rQo)J`ZN`73n&vwMp5Y=jKvtg|R3KH5ryTJ4QZSe$ zC7$52I-%kTvL?g|q;6v6Pu~98&!;U>kS!q}8c~=Zn-yra>Z4YyKymcDds`P56H{?o z|3v#(V10pqbyDzNBhx~RD6MdKq-hDfp=l|+v1u8+scAKMd(-OhJk?~Y&W~u^QZj^Z zHLV8UW?BY+$Fvl_!?XmRZ(0nG`g~FMPBJt$RZ$L@I=q=_HFyitGI%S~Qh00A5_pVh zF?@$=on-v=z_jhCqmV-fq!6;>z&q8dIEQGFq!@zRXrF~4Ei$Rt!+sueD$KfOL?_!e z2{D7RX6c$biWGLz>ksz4lM00j%HL1nwT~t&(picZn&bzXrGY5B{F*`-Xkr*B_{z-t zw4keKz`@ZLZBiMp{pZ>t%2P_(JY}ky+xdz9K8U|%MXW8`VXQ5KST6>#wyp5nHt@Sf z$M&FJX*GCx)9Ubw zrj3So(?33zGi6~!V^0;OFun^uFznwG))nwG*nrX}!r(_;8k)jA2%ILi!2 z!)KdThtD;w2A^+Q2484e3ePbufiE*HhM!lhlOToZ1v@SG5@S*{RwB|a)7RX?v z6Og=%PG~WTieDsS3_H3pG{H5d7Xy|TDv)II@Xa{9CiH*(?oz;UIj^|WcRnB{B*$vV%Yr(z5}jNu9E1SIRimzIqoIEN{3&5dCk$blgT zg*!Y*JO8?inKanAxgpFTI)*gZK)E4IjvYf9B%B-i|B>;>UB=@<`jJ>S%%nlJ21VmR z!guW6J^ua`@$aaJzkfyi@Qc>&*SsImYv=Qym$kt<&fgsEuFLx(x6CJ8srZ0N<8%=m zLX{TflKTJb88umqzeLDGbyg5ZC^7wWBqgb6i#vZ`A3!!%f>nvoFZ^%D;facdPnR4&QJ2=*4TlTKtkmB<5Yb5N+339*VmkIK>cC( zrGL%&{r|-bP>27<43IFpCSRU@jdG1XIh(7Nu^&s8>dh=;KW6!!AG>_dU*bdbX#KD| zVw+&UN<*WQyFC#InU^kthfBcAsEj~Ri_Y{;U}ZGj}hX} z^LY85-~UEh{C6E8!QS%->EYvUn)`^wd(?^#pEp$N?VMNe)2>9HXI9axJg3L-YNjRd z>ZYaenxzY=FHg=qB>)d`Qt-L`Y`t}nUh_i%zRa`){)%ZSe6?vAe2r-}_y*JJ@Xe-; zhMzno>ij2rb3sJoZz@WHqv5}sR)?Q9tp-11S_VI7S_=Quv;(xn2LMQpvVcLl85+%$$5UE#R2(U^=(b}0KdhZGI(fewdQGq-3;MfyJ+Ie_U4zLh z&LmhuAJYo$p;vkP4vtr;*dVkfnc*iD57le_mG39ZSH9E!tkb7G@dFM!i!9c;r+f) z45H&qW4wyea{^B`EruT}J6kadVi@OZuTo2pgk;Xar`4(`FD*J3LvVlXQ^J9yAy$48 zE35Tzm;EuRZ_}&y2q*jWODbKa*NUx6L~16#4+|2g_ZFZcTB6pFPv5kO;*$FK{Q@eQIe^{FPT<@UokC%|7BVV zziwIrN2eDZ=L3dURIQT?jg`%?4zFTb4PMQ(3|`%|6i!V`;LNlb{)1|rWc>MO+Md*s z%Gw6;t3Gyce91XB!S`#GBomq`vM&FvcZceDWM_cOJE?cL;&vwO zqev1Jn{`i({hZ6d1=`pGfyC}STNC|Av%6?%I_wKG?+au1g|YkmIlWB>@vIw6@X=9U zFy8*K`~I-|{@a70_50n=31UxJ!omg5G5)m3cXDKHKhcipr`i$yT6IJ}-B~&!jJqs% zwR&8yo#RdU3DXkzZ>FX2Q>JC`v!>PH=S-`^FPkvHo;2mBL?CVw>+WEr>uBnk8)*YP(@A}diNz@I%>1M(-mDRuGX1}-WTeM^i_!T&Zbf!{DKhKHY3WG?w--NtaG`pN4h_)91C zf<&r*9;6;$bB;~$b|B>mca8&i{VwyF6OlIafpl?>L}9-;#WPF z8><67%P#+>N;p<*{Ew;$V~`Ui^a{$l!++%U-ZDHy`#M3da^l>r_;Ztft@w;d{>J%? z-dcPh-wW%DTwqsL(vY(LkKQGXib@lpRB6AjOEt>%uCJi-nXa7?dd*KTczx3nc%*45 z{9)5F_5Pi~Rq~L)k@>+Se-OucQe}l{a4RtwvwazAkm? zH2$dgv`H^1zE9Uc#V5jNsmbC4`9sC}7T1@XSkjQW{)gTr4Uzmn1Srk5Z}J_D@>ADW zF!y70d^_ni-=Of$rX}#lO-td!O{>F4nU=zzGcAEnFfE3UKDQW%wx#Smm%)i2oeyNv6h0n)j|x=rsAOC-NUH8t7I0)Ye?9L*X3 zYcEpe?^Jw2>w=>kcnpvk6e&z9*ark+l#(|{Y@HEJi=r)Y{mAPKH|(yJp~s5iEmZHv z^_uTj_^+lV@Drw`@Ve)@{guI)X(>Fyv;?l17Q;`TZ}I%eCf{c?57`gkIvPqw39heF zQEFOSXnZjQcT}k`q&3$JL2|2J)3<1U-*u@pz}KDBf0%~7$b}CM;|JCHdFRytEl}SX zUZBb)y_tr1)P?F}e3n44e(|#2dPA>Z!C~?VH?qKlky+qi@E=xhCa3E>kw23ohT!7o zi5|#T{^<7daf3T+txZrOl<)bg5nFm);skKG(G{uz(yzqwyIZ8zFX}bltnf>wCGg9p zrSQitD58pQ2G>nX;Z03T;L)bV@GBQuyl(lvp?Sz=1wX2xWR&1$DivFc)@~YK48eU> zDhz4OGeeNvsyFMs+TTxIDh+Ts7pwmS#j8y6hxr!`@U{g4El}T=yg-$kbr%islnd3z z_$+~7v*KmF^@d)-YQkiq8(Cn&$SiQMS+`YhCa3E>kw23ohT!7oi5|#THsrV1tOO-O z`JO*b*wX6~CxFA9u22n-ekGRQT{OE;26L6o3J)vp%T(J>pVn zfWuv^{<9QsHOZfr7c{_%&ZGfapuX$8K$V-dS3|w#a_VDzmO!vs@v`1}L$6>pVRDp9 zJ1}8n7C6|fd#g8-({-N6pUDwJaPjj*59BKw@<(h|f)b&8&z~l2>2-+{z~SevPz{iN zC6?b^q8npn+aNK#ifIWv+_V&az_dF2OVd*LSEeQK0@GsnVbkjHqo$?s?@UYJg{H-D z^WtLE`P*Q)Wm*dNnU=u&nHIyJG_BsPo@;9!a+rW^C-s7ixY+u%7@tfR_($j40{^5^ z;Y({J%}snk(ycyUNaaS?Lj(M|lUyuHCE=;YMAu^jq{oW&_C1Yhu^Ss|fVy5gM-Gj> zEILTX`FmTx{99;vmY2L|r83N@NJOwagTsnIlt+dFGEM(s;mPYCR%L%QVX=CtOKBo} zuPIuxsd~*Hmf>SfOW@;7OW_ku%i!sz)!>!CSoEH6EqFE4YVZe4%iuLkOX187Rd*`{Ui`KHz2buKM(&bL0io@q6BglQQ( z(zF!b(6j`un-;@onHFq)#y>~%m8}obwM-iLA&pdQeOkn?nB5P3sTlGoy~@@Hk91Nm z_&F!FCTLFEgA6>nkuBt0SURk`7p^njiQA^?E_C6*J_U$aa3b+t$C*3-?}ZE4sc}!` zsTX|SNiBbvf6!Z)N^!u&c+J*oU!>Q3>%*6rmcU;$Erq{qS_WTXS`Gf_my4Y9tq+ef ztp;yuS_W@!S_*GzS^|$TEru^ME!g^u|7)7BY<-ZfWzxW{G*YqkX%W9-cDK5$81hbf zm8}m>cTz7n(@Cu(wI_=mZ2dm9KHhmX!1JBdf1Vepa_irzqbFTiI}GmA>R++-@v`3f zLa)AXBz^wU#p@HUufSx2j)+o8I$)`4e&8#qL-)YGiEQWRx^4Y$dg0!SZN=iaTf_aF zuu%hi(@DMH+fE9${I+-0)?vJ~W$V_+Wz^OtD&Hq#RLPSaBOF4Hpj zZqsV;J*L&+ADK29-ssAri1MqSvj@@GSVc*2H2h)H>hLC})!>hrmcgS;OX1B-OW@I_ z#qiu~O9}cDPDLNqk;(ZC(vN(96}Y*EFOFoq^c;JsCoznlTzP-#dseP)|nchM1a#51+=&o&hjOB#db7NSHP@wEbP z(`(21Pui$mRdS}Wi;Ch5URt)Jag~bsP~e-KR&PJ9JpAfXCk5L7Q{*3L@$x@)*+2*X zX;+ut!xgDZZswOI*Qm;$wJNy=uQ9jiR?c6FvYpl;H-jmZm{F!JbR;5yTRW)%ZsVk0 zkopadW@Iqs%lo8Ul&IpRfnsc|6_77Rm_4&i>q%FlK9CZ{(Mj^J+sNPX1cj3Gi#oM+ z6`3*0*Y(bFoiHe!RaVqP z!S1ZD%8tRErYh`n^C=dC{r>`QiOCoIQl))$HHmba;&)B55Cz?)mHWG1^NEJ}>Ogr! z+D0Q-@JS$ru2`uRE2O1~vq$p&Nbe!-r0Su`Uyv0?;J&(~&v#3EoIlzgz18nbdL{*4 zJ-*k}cQ-jPn2(A6j+cy?A}iTMe{)xii`dt>?b85nRH^el$~1mqc3}<;e{e*fpo{;j-9^_JK}pugkI%4kr>jpx?qPyQ)jkm@S-Dj)cOZ%Cz9Wz ze+UhZwy!vow{QD%l-s>qtfii9KdC{{0Stv5Cz4-Lk^GEa&@|jWevB4dyAba1o zVin%0b>vXU*NNYyZ?l*%oH25?fUmh3J!w#z#!A|WOdq(hN}ZXfL0Us1arX0~aJ+|= zPA^iUue=UsVMcC>VCCes{m-b(r3UL`TmIx?>TosdKcr#pK&o zq{coyM#Clfqv<6>{~zk!JV36hTKlea28y{rj71DkkN}N>Q~)mxC`1MYL8wX%1gP!? zR76D$U;wX}jx*vEhO0rr3WI=iL=Y5#Fv%n`s2EfrDjA0P**JMF?Tul&Z-XatBlb?_ZyXE}Q z6umxT*5;K``~Ls;^)t?g$)77aKoj|8y(S!K!))H4H41e}0zy?ng_?5GbV=mYyegWG zFsJ5KJ&Y7x9rRmKIfk-1ZjcieNf9|bNX@Fn6Ze`GXCd0EL-Q+&CX~&IhUq~fMcwSN z_Qp^)M_oMYhX1O`VY0|Cv505gFm=v>U!=luMA5T8*5yzpv@du1Cyj(1Wd}tEPW9wM zw|ZpgSdR?NQvcl0NERz&EeN4(P8LyvZBe)0Sn5LA9CaVoo#S-9%4!Mh8r58+@O-0c ze^=FqYq-i2$9n6l5pQ495m zsjz#Fb>{Rrx})~Kj%$r zt^#g4R|dD8D}fJnt_a@rl8l34p)lm6Tb}U(30hWoATg)Ucxho=1c3*uAEFL;h*D`^ zS~!=pjohlq{;ef_p!-=>a*D;dV|UkYr$N0s6>-FG{IB^eWWj3jgU;D&zmpIX}gx>NPpWUZnU7HUQNw zV@~!GIWXxHi=>OhBx2xfl4f*ik%B}LoJq&8G&7IcAXmFbXlkgTq^n1iqMLO|8K<$x zIeVhQ$xZ>cP^$NW!JD=5CaakarHITJ7Y!tB+(bz2D2fO3gVWLBkDz#oi>nqNGcY*ktL@cC#Owve&SNh z<_DZ2Umy1g#r*aZwn^djE=BEZZdq+J*F4c}5`Dc(F$aI+6w`4h8;&*$%1KU9kxQMr zN8y7`QKUYOZN_m;8?-j#_%^5J>ID6tu_r3kNVeq^aN}6_0ikTpBKtla1}a+AeVzkH zSXH5Hjyh(+idWE3F}>J5Udcv65#>0wu2#%+tDGiqFQxhlBh`4RZ-$P(M#bqS*&6c! zWhk5D*k4o~8-=L*W^;_gVUb3~K76uTDMDG_MLV3!HLs@>r$}(DU5TSA< zl*`5nC6vtxWtL9NwoT9)keNMRex2QAz zGGgG1TnzZjj2QR<7c=<%)Q`mIIK^eX%9}R8Rz?hbl#2mR%7}r_aWUY188PsyCzM8`Zs&1yhT4 z*TNKFiv-FU_rS5vxS?#$8TU8p@}JE0dT0?5&)jev-Ei0|6cIm{k9CU}%I5gVo$*$7 zgWKTVV6M3y)yqG18>g2z@&2)r70Tu~!A&w2b0=wz(4vtrJF!r)KRQdsLh>84SEfns zl*SS{SMTwYMG1V7-S-ax*VcUItzAc|I5IiU?>`fXM3sM=QN+x0u^0rJUns~br+5`eL~qB zbvz6z>&=F!J7}yYETL?UI@Iju>gJE-T_~HQ4mBLm#k&uV8ToPoILErpEr3y#eqk||GNk1M z0>nRgmlT-Q#VcK|v8vWlAm5e(vmN7K=Kc}wxX>bsHmxt}N0;hV26)+6lOvRszZ>UH zrf7+(xmvHu0E4f0t^{8F$7w&2tAN*Vt^_VQR|N0uTm`&~b0zRh=ZfIJI9CBb>|6=F z+_@rnn@ip2vEqMTW0e{L_NgivJ>Z&3r6ojb3lnSsUvE?c_@+^PX}!$^TfiGf3DWwl z3j&`VB}l8F(Mlx1S1FacO>2q^0?AbV6bU2Ad2f)g@H%-f=@E4k2lL)lI#6XkWl`3E zR~pp-USm`X<&PUx13qa~beO4X=-cTvse16+oGXF%ajp!0yK@!rzRvZ7>&{idZ@Db3 z!`_leV=pDenJW0L&h>-$cCG?`yK`mme$JJ^HRp=p_D?d-g!6+;y-}l(sshq4zgXzF zhjnZM-)mG0nAH`prytc0Z&vT+sPqnnbj&$D(d#_zEx-I~Cinq!VemNBw9u3f{z>5* zH8VMPYbbY@+ObRRFq`YB;^}6q26RPHwSGsPz1Ezr0lilT^TZ>kS3)8lp;p(B*0#`U zKu=|K?0sG>ySc#+YY1+xc8^kSE_wv|!$^^hq$?VV{T_O?`s+?cH<;)qH?lkd-S1UQ zQ*18E3Fb1TM6VUp%_|a#LXEXV?j5QLdzTG#3;1rO@+WTGv6;8NrA@iGlJkhI9CEMbFK(};%BxhE(xb`0go@!j)drqpR10{CQmJdSo^V0n zGe)(6YhP{w0LwD1^HgG?qTELc3ZQvnBwSbox)dpT+R15f&QElM!Mzw%z z>X6G@6Ts<4wSWg3)ds%Ps21=@quRh@jcNhs8r24V(Wn;i>qfPK=Ni=lUT9Psc!g0d z;0;E#fxj}U1zc)W8~7)qTEM>;)doIlR15foQPFnDH2R^MP6*Jt|Ds*c!G>)ESM57D$~iw{VKdLHWzg)(!e8l_yka z4|6Pu5(tnbQ6@1SFuz3#NK7JyQ_OFX0=l28IEitcc_g}k9!-?sz2oGC0V6_``2mN$ z!UW`vTo`^L6UN_HI4)FOVBn6`(MtM(8O*$XU)NySYh(mM-LXhCk1vR{MAPjTD)LXg zN*T3u1v%MPk~;8fN{ufZyQILlH@!|->Iqx4u@+ zn-eMEIp%yDKXFbv0@;V8BhX!6#chOWSnov_&;yJ{?{9J5!vRKw!1Hqu_6kEwDlUvI zx8igZ*(j5KV8$-5Ul@MUFN{C0-;Qc;rd3Z=o9tgV+gR3s%-Nis=@OOZR3m8vdar0a z=!Hn$t2W3iQ44Yc53^tRoqqN=lUcAS*mbYGpLiYWMzyPn-v(l&SYq>jLLV6pJ4u3c z5a^b(+!U@z{psT>w;$jM&XvHEoGXJ@bFKnj)46`|`p#9sPbw$3F1L@P@l-|-{IqlZ z;AfnxfS+@&41V6Z61Z@s1}*`E_fW3q42?ZqunOMGxqk55oU4HMajp#B*SQk7=3EiH z^Hr&XJ!itAVb}&VG8t^(`;BS?zi3noND8GSfG?<2dOJjGvbrV~fJ7{Pf%~ac+LzWl zy)SUYs5bCZMzw%zXzXGE_!^^HKr)n5)>mjOf49gxo2wbdCg%&zd!t@8di|F-eR|c=^ zTnSupt_YsvTort@b7k-`&XvF?I9CK;bw>wt^-|t)%{D5<1@Pp2k zz{{O0g5P{~q4zJzUyA&H#(S>jT~n(st$C?W`ioa2^ID_ zT6^J1raBhsN0NlGdSOe}p2}DqYb&lmOXVBtZOT znGz~?GG{G{=I=~3zq?+OGXQu`=StwcoGXLh>Rbg}bFLqJuX4R_?`YhY5d<%Dt^)p( zb7k=T&XvFqIadU4b4{W5uVDsW-~xYVR0H^cQt6bYh2t{*z#Y_&RFKv<^+W`LRi#ovTDUBN?rMr~_$c$P37lh8 z3%EGrN3%=or^?EUcR(yAel)wG(Zf_TmZT#POOiMs*-CYhC5)#mk=8TuH@in`Yt_8L zj${cV-0b*=)Q;anNKy>lh-fOAFgQ_A%mr17i^4uGF?t_ptM zxqk4A&Q-vL>(eYqz-7bEmHHGHohyQmz9EyraP?rw_gAB`$^#EH>LB1}jcNhEWKO1s-Ko3;3i_jny<@4?O1wR0#aj>s5wyj>2P{ny>H^PAyP)s#A*; zp5xSFh2%JA)$5N$ngmWE$vzSK&2)Cfv*KQ}!d~+=M<3T~a@YcY!nqRobIz5)<8Ms0 zO5X~2HRsCUqH`s1$+;qUz_|)|C+EuGot-OzXF68|x16ht75_IhF4^&cj~mqhuCAJr zMZVRgg+Ee)!2L!E(rPFxf9h2GWaOxD&RTJ^@E>O zuJeD2LD*E2j;2HvmAq+o%|jcNn`rBqs8 zwEm_>r7D2isLfQ67M_UUSbluLj5dJ_jA{WdP>YHBW|!7a&5tG!i>Y8}^y8`-OR@|C zu_XBbF3$wt>=Hc2Qwv18esQ|;Uh*pdGMmW@GKo3 zh6U&H%K~*2v*Z()RoCi<>T(kQm%xvl)5z5-a=Tt-B?V$m9;slfrL`ndK%&W6IYYm5 zJd8!67bjwo=<&^q>U^KO2lODK3RtYtKh$foY=JLwt_1$Eb7k1$#?U!T)lu1TOr-Vk?68aIOm8)44Ku zFXu|&nsY_)A=% zO5i2V6~TXZt{QF#)Z+#^7P9&Sw^S-wGFn|)hq)l|)KP-8&U8WGjiUr`PHf_j{q zrnRlI;v;Z}QG&E~b3x$SM+wq8&;@~qj}oNyeisBDH%gG!CtVPD(kMY%XSyKp$D;&k zUFU+pn??!J`n3xJ?;a&c>klpn{NpG=S`WD(kXq7_3Cigh9mlfr+b@^|We@+uzKgN=No8zOnH-64az-fMR>ykq=|-P!8Pm3oy-GBqyn zv;kQKa|)`c(%XA4<|nxk-AphtDpZ)ISW!JzRF4%!L((666xxbKA}yiqyn)3TR)stn zK4U@1lUc4FKc?5@paNd=*3^07O5pvK>)mtFI3Obkt~pl(pPubZ0+_%TsC%7GoYp;0X$iW2qlxBR%Jm$iahMAZfDd=B3VxS!{oo^*|a;^d%cSo893AhX%?_3F7bgl@Vs$9=O8XLLb0C;2Ps^E%q{ou`hR z{1Pfm)_2vZEA*OtX$9WKylTXbHgI$R?+OhZeZ(oe`l@*qJ>fVxa6$gU86J=q`QCTI zNNBJ}V*STva#rX?PcHPMN8*&HY!)e-rl}KWfCE;o^Oh87yxU0ekcQ`bR+#S(X|VJ3 zDrZO_tF`N$lkIkmmcGP0R-2eed&jo5S697G;cQJISiN5b6wJ>s$r=?q8+3kyFL(1sX>vDMl*b_c&Juzt_1Ec#d;L@Mgcx7@;vu$;1eF zx^rdl7S5HxRp*M}vy|&aLgO1QSOIsPD}&E=t^~f&xgvP$yE2i4RmB*6Q}Zlm93cJj z&p34afpu&Gml@RpW_8799CTe_9qT|8$QcKi)fJy{_Sdm|pN(n!&I&RelbKrvAF7-f z40H7f{pjZ=(gFV7G*!Fc7fh^vjtPhD)@NY~mG)_{dm} zEfgGS!_f+ZI8{IDnn(?Z&74*Ka+O|z2n*E?Hdrm-E=nc8kTdj$ZYP;cwaef#vU#pg88lph$7kZFB?Hs*~+Z8p+fx3Ibnq1Np4Z(y&7Rs4pU!n zAjj>h+Mc1;WXA*#I9CE6?OYXnjB_RM3CK*2F@OM&pTU2k`~k?gsoN+FqhpRWnwQd#RYL_&_YC4>M_v zxF8TysUR&3i$);XNCiVzZdc8})@w5E;I)67N+)LyaLKtMxZzx7EdBqm2wK1=l}ZPX zR#BD7zysG&Dix$vaY5j;QG&E~bV1$**?{BY64gSKvhe~fM0pBd@6sA)R_j1Q zOx&w?X>I6&KtfCfX;obiNQkK*t$kb&m<=vIztNHO$Q%NaomI~i%IGQO49t4biVi7< zs@sR_HJOm$cR5!AAK_dX{C?*u;14<14?fnpD)@Nk2EdmuO)Fn+78Z}Aaix;t-~jk4 z=c?eVo$Ci*>s$qVy>n&o4bGLow>wt^5B(|QU^q+3=zSWQ3sI@M}g50?#$71^lZ~gTPIGhx!(9 zN23OT`x?~(UTM@I@LHob{>U338{c98=9*6O|q zq}W9Y_)aVGCXiwmDd2Rg=q8Y27b)OdTngxQ-}Z`65q00S^}Y^#%%~2K`cDrJwDz`I ztpk|?^0)-Z6p&*O@KWp80cK}I-DbldOt21|WkuZqQtzpEv?zJ83#8=5J0K-5Qb5X7 zq=4I7mDPb1phy8JK+y%H07VK&0g4oGqOHLl;6_TNG10o)1%VWADoBfB6}v!+RqO&O zR*?d3Z*^M-9&c0!_)(+kKuTJ40XtURb)Z*dC#^&OpJkVtlPA^&tqf+3Q`l$JaJ&Kz z->&-{c@te>zH%OjU!toQt69#Yh0V44uqj_&utM%(Yu^y?0;6WJs(ryKX$Z*bCf_7p zuAfp-LLGTunxYf+DwO9eMKv`uWagT{`ASWaU#ojUVbd;cJX^hR%`F7 zNCokOi7J9Xsx1`^y-V3J`2C~pdpK0LYQ-BXYR8IJC1ofg{4p~Ts{i-G9tzdT)CyCW z^Ht%ET5@+;?H~3=T_oRTi{)X!LzGHxQNw?q)fMGjR+z$x<*{Vg+wxvk{d%M)elInY zkrORuQJr&Er57T3*6-ImtZVB`ZQQanjIH!4%i1hGD-7D1p%#W3D>@8CYnh_MVnv6I zrHH*$0z(m-j!-D_4Pr1<6!z*X><~Q|Kqlkj%GBf}nictnn#4(kr`FrypSyQyU!r_p z;ll+m%V$wa>*-=59U4X}k}EKbNbU%0eZ8nx8O}>}ySrSkLIJNdszLD&+q|d&nP~Db z_`zkV-)!PJ&xcP`1(&-bdaYqweyybN^-j%DxUW-TlFF^Syo)&tJT$1kQRZ6An?CN3DWW`4u_F0QeS_j*S^9)R5GDV&R`%yu%kmq zdCqBv`YGuSG@)?Z(n6QkR6Axjf!utif?+tQLrS)dP~-=y^Agit1Kwj)gI#pGR~L|# zUD9y1-m7uG5Q-Dh*X~OV=OpVVYR1jgQFOcA{MCU=l^S0-Zb_l4T6Z(;b>QAg_2l-| z#=$NJJUlChx1V=8;OSYpFo|&p|Djx@g+n@S(b!X#78#NK3b?a6n+nn*B_arHjS{3q zPDBvMkfs{R(`QC?r$wryJMe3x1jF>94yn9Z7s})m5+eAK`brB|R@tk2C_eRF?$P=b zQg=dyvCs>V)QM2)=~(wzBG}AV#HVYkXYvj0vU#DZihkI?A|XD+@mx*Q^(4dnRnFbm z3T~;{5@i{>NnPP=Ak+%(W7#1@YJo24m+4igdlf$K)ObBZt!HPcPFW$3W~5`7r-#+4 z$MxEmbK1OaS=#Fsy-EpOpmx7+_UlhYE=7exxVNh!8QJ1DhH>pZ)B1@r9~%^3qLE6!DaOjTT`*PKO&n;3ef zg&c;LvSEZN8wQ!OVVo&TsC>1Nvb5gj^9x8$QbA8hibCh5-hcH8onK)H+0Vj2vY&*@c%1!gEWde1DU}ao9Ha=s2!sk97b^5usL)NJLhpnMojO#rf4E+I-%2Y! z!nqRoea@A^A9St){-bkM@cqtJzz;ZA2LHvm5_q|DMevM2r_qSd)v@9_SNqAa2Ka5G zI>5V(Y5_4UIRieVQprQ3R+rY3-WP~tE6DfPtydF>Gl}|Um)7rG5QybekQT<}X(bRp zQo*rObb(o@12HboFoC~vDd0UuwShR3SghxysE%tz9XqiA%z7KY#6h9rqC8Uu;$mWS zR!-t(fOZKloS9RlvV-t_=RIb0zRH=ZfG@ zKa_DWOgb4I)W~F=1s-;PDl9_; z=P&A@oMMAh1Co33;o^DdM^}#w13Fced_}MFXIo0(^V~q#ZIOPowO0e?7(>Zv&cNji zQO;n5=DwrmE_087ON|=D0}?7nWb!%DDq=9yeU&P>%@oyu&luG~(epY$q8m8gbaybb zj#F_CqVL!p4e|7N&Yr zwe|9PRkar@Me+rMRu9!A6xGAn2^B7+LNR z^(vJP%y?M=Qx%fZCG$eRdSvKXj|_e5k)d}zGE5o%ag<2X3jU1y48%X#TSD)I3VjnQ z^h~JGFQLZr>L&Fd@#;3k?!q80yiO-jA_m^Wmt>&Nuff>U!PwKm*wbj0zE8bc?zsws zc}hRp?t%0ZDFNV{bTgBoSvoItphx1uPPXLNj#S93@5zNm->F6!xFj`TvMTRTkil15 zwuVAYZPi4Hiu=GfXhh<{Wmc_+sHz@``}o`=LkrX(Bb*)W$+q1O0ZE$t{j&anzMe8$ zSumcc2=gi7;tr|Hd5h%x8tzZ^D&P13uQV#!c1i8|CQ`dfp=Y}mXS){W;yc>QZAC9h zE!3=E?)3z`Iy)etYCgQh`pte`$7*$}uGwL)OH|}KtB@9h`9bRy<>RNXsMk%}YpL6s zt2RD5wyj^jqF(oCuczHs82W=N7oiq?QEF3yzS`uii=nNzXr1q8_1^xnn)fq6v`!-J z<_BZ*w%DOC=WUa^n(dhRRq2Jan;(wNM@Nz))CRp|O}Ka-w+xTzhdnY((gH1lQ}voW zX8@n>TnYRY=gQ!(I#&UI!?}L&YyX;BPo9E;r#jaU-q^VcxZ+$HyqR+)aKCd!@arFT zyWp*z>j%HVxeB=ITp7Hbb0zSAb4BpE&Q-zZIoA(9-?<9-Lg&ihA2?S6FLtg7e%&J; zFZlJ&^@F!@t^(fHxia{_oGXE6I#&e$dAZw7k^fJfouzdlPhWsjbjak;GEL!~P60R5 zK+|U!+iU9-y-HsoSx5zGJ>r7E9W{hhkk)(tmO3pOfu|~!3evjF1%WS(5~M|1at>u= z6{K~w3j%L9!DGb^tzWw!kPJ>JB!XU4DI$rBEs1p?$&_jXlF7uoy5;pJR&XsK znM?&~QDveLNG4N3T8~=6wSeR-6{Pi5Ekn@=JWDD0O{~LR8kZaS;X}JLuFceNy-VvM zR|$N=1m|8h(xo-qYPbcYyi+G>ecc6t-^~WTlggBCX@BbXveGMhViQphRO>P5VSE%OC@NwhielAWO6C{|r2X?m6Zj|F1?cmho=6VPCtWxr)kIU2|-ib0C z#5icO)QB#7^FN{pd{zv zsDDJ~{{^-V)JXvKE?iRa(;lMqdKu6MaTT3K!nOE_Rz_9M~Y^l=v7ub zb>N0Z%>usGs5;O+m=${vz3Q|A4^Sv+s;U{+U4I3-*DB1doIY;*>2KU3`HOG_iq6rW zhU!Ou8s>5B$iIWe5+SOjNOy?3)xvIP>j*t-Wz+_~pp?AEI-yI0JzS0k%XEPz(9HSc z1T`#O`?@rIs#IJt3`EoQ#$I_*0ZKIn3NT^j##azd9zNmmF-@uV(|&7CZEY3%Ie8eJL(IJs7r z2FsY}T&K&i>T@b7V-Ea^Qfn0E6lP36uCUp(zAoHZ{@Dnhouk}&t_t`=7dKUKm-%O= zYOMM26PpiqyrT5eQvub_aYYtHAQNIjAvw9Ql~Vp`cV++snX-%|iAz~B$6}tcV|k97 zvaaJJ4ha={BNVPYsgqVHZUpd7sL(Z`LcfFxo%)`pk$WOpYh$PCm|Mq|gF5EwR@2ea z&JcOP%{aOy(LG|(H8JPWH8DrxFd(i$mM{WyWIFLjqP0yxQok8=+fB7 z<$!gUo7kl>>~g^OxZI>Jjkzud{FuwF)}`@zmjj;Wa>XuT^<;3F=#R+q-JE@#lz?Kx|A$7$nLHbGiI>RN8b#zmV$uST`c zJ=V7deAuWK@NuQa7o@CcyySAg)pU6kxxOxq4Qz>S0jIj$_%4mDTn;$Hb>M17 zwSXHcwT|p}+fDy)VYAaG%zV@IsnJ#;t0fDCFV1xqh5K~6uPHxuI7f7hOHQ4TEECC3 zZ6`c!PE`QyVtf>`@Lj4$;g$ISSImwB_ z38_MuO#_AF(~qH9p-@PhQ=llEl=gtxF;J-XpjpaLNShO+C@iK5VcroaoS1$L&6J^3Sq&;B194OR` zK(pMUkTxe~QCLb9!hADOxO)0AH0v@7X>-~Zh3lt1U@i|7YKoy*z)?t>le#F}AXNx+ zN1$-c^kZmNdKA*;lrIV=r#)c)5-8L$gJw%WA#LsuL}58q2=hXqaP9PCX!Z^i(&p|$ z6i!Kdz_7I>Yt3BN8g4S~*1aHE&SvzMv%WQ6k~N3>4K|W>q-*wb_(#3}xa{ZLny|ry z{o%*!S}*qdvi-S>VdDw=!grzc!rIGxGodFqD@ zDv&hD)(iZON+pBZ>e9O0`vM7B`T~D5sxPfay)TgPq%ZJw8dYkS)(*;w&%m9HY6F`_ zwSZqRstr8bs1}g4 zXw}Byesj1Eq_XAfO<>mHx;aeAiXadd6F=%*TGXNl0&y`Fq~#7rU!y*wjv|^n#;x_V zvNzMKNQDJn)PZ$HO?qu&y_!H2C5M<}3L8gnTI{E8z030m{D4x)-=!siOb0n$ksJaO z3P_dr6^^sHjl0Qttu?JobGDUf{UU`wa|*bH29_w?UNN~&xG+b@s_Q3PR5c)rfqX|^ zVy=8sEhgMpsy=F}>Ofa@Vj)&_Vga=TCf|2gq5%k9O-`Wr`c<`=oHS1?Oq$w-=;{Z> zgs#Z*u`UcgS(h-LSL|rqF-{hdQjjvk!{HJtbctSTS^2hrC`v{q))dVRG(Bo1)GDY_ zG)bAh3`O)>ONP$BxegVqQ8-$jp{CzzhrumVSI{)B5WPH%2wo>8Fd=fg7HXcUBD?D~ zIXQs$cdi7kIadbHa;^eyIM)wuI#&hHc5VRt%#*2?z2E6h<5?xe!2$4d&Q-zBJJ%0> z(YXq^@KkCfIRY7WuGFWv=v)yzS-GBrG&Xd>0q_*(s^F>4^@BHdt^%$&R|aq9TnXIo zToL@qr!yHGYsmM~)XVk&q+hZj#lQcbTG`J!Hi4%Y)dFU9#ec2=UB9sLuXe$AnX(%2 zaUDUqR~)bLk|&|2DYd($qS^(|QBK5w8)|lvDFWV7IS~Wyn-K#a>|#LTOtg)a>U%O# zf}ipzfga@$Q8My!=dq$FkFY3*fJBxbiu?GLsKT*BGr0znVEO6>h!=8P1d_`{ z8~6arYYm8FIR{OOr)cxK+67OyN@)NO$cTaOaxwCX!MuU|oJLCwQYP$*t}rZAXz*)l=z6_QDx5NZWYV+}A#Q7fHm3xB zvvSB{aW9PzKD70s+VD)aLy>R*WZPb-QGd^(Z-l*mt{=JLMwpFch)4tZ&l|QJRiQPk z_;3t`)^hIpb9#k}QOM+x`e5#4maeeZBO3h6>lMy<@tA5MJvl)zM=5UckVTE;<`ngL zS}%84vDSbjPR1DpC-}q$x<}E_qktOB8|R$$V1XJrMX$*r27J16CGg|M9ajQBW8CpY z@bYKV;gP$868IV8L{9PQp=1=s~M2wCc5ffT4kFtLqH}; zDoE=PEAb&9vm_OywV@5(5RkG?1!*y~;v&s#YR0UOWzDA&8R zKA@~<1fDobkk&&k2z*VZ9O_+KZ?w7@0`8*J_`=9Ymqx?Lc_UpKEhA4H>C%{)siu0D z7PTgx18*56Nb5vSn zJ)jf|q@2}u(E6cFgjz?JFP1au__z)=<1A7`I#x&8nALy`vPfN}E5V(%BGgXMRDIe~ zRs%ALW%XM)vYKXWEt{y(V*=*T<~FTrz%=x{d3*Dq24r^2ujwF@%n_kT8?!+uoLWmuR)zxTehyQ^?{%r;6@J#K3ly@@ zih5SpKf2V5Kp&lP3Yip=1_sJAGfdf&AyH3~wzd%*0<29QqHQ<3tC1OmQMJ@)sC?m#Hy3WObOszy4)2nFJRRgZCR3gTd zo8w}@|IUc9E*I=nQ3I}_RHBX9T5&Pp+>98D_wQ`+t^prbD$y2B_=KZW57Zf-aMZ+} zS|bS;{tHKMd|~yMY)5=ahqg!3SY(6RVE|e4dU6ccpr)xu(m34G*#WZQ_2kGWGq6Vz z8*{KnG7*`DJ(7mczYdTY){~?0BPLX#!^~s$^yFwPvI*B=-MP{!CK|J>*OjTpr0S8( zET&bDq;bE^#17Mq-KQrP4jpS*W;KoD&s!%$MQ_p(&5Z1Km0HIpQzs{9mj+m=%shuX7k9bxSpjFBB`?upWA3nARQ{=A%c3Rna43Z^TeI2tCO# zdp$Dr`}aY0tX7y)Ijz_^tw@b9>n0V3dpvDwXJW#iRt!T`It*6n&|js;at>R4h3%r8 zCR}JG;X)G$w=(_m%cIAALw}KV7*O`J&|dbl&~Em#vFwv;Ij#T+S!O}#N&eIf?TS=r z?tUHX)oj|=fSBvmHU`(${kunoG3U+#ieodk0K|fv_0hkc-w^=cU{nW#M;lcG`eNE4 z?45nX3d8<;5Vrj2Nu?VGzFKl8F-hM1#5sbu5AX-$_CaW`ticnxyjch&38ON4oCP=w zh>hGNZ>joGmNU{DtIBO$HINMFs^-HztzT3`SY@Hh*>N~^aWXE+E8hcK>@Z!P2u_;T zKWVdRMLs!CLrGo=&wdWinR-1rElwJ(BFsAHYR=TFeCHV|+UmuW;buuDC6HBGa<^cF zdm>J@J#sBAL&~y8h8DIBEaW}x6RHaa1OhSbr z2^B^pR5;c`g;@_hkO_9uNa#b4487=)p&vam^rT0IzVyh@n~&=)Argsv z`IN?Zw#C{4W@2415?bd86VpJJm2jkTR+^pk8OEFa@dl8`8?qq-dCDPqT{bU#mLYOf zH8-<8xf?VPim6B9B@Z~HGmvw9PmWtW&hb5xJ35Z+J(3mAZ@hEim(GHZas9pHnh373YuSRMh-vA;Iu8dv00ng15G0G=RGp)eP0=9X_a| z(=&AhzR2om7BCb2GkJCNOkN#5v#NFUjMWiEBQG=L%#mmEO6HlUWQgNzi=z&_Kq>jP zEhAkT1Sv0=h7};k=x`ilSQm~k5PMkG>%dH^7FwZD8@0$G;dv6npb2?qar&}NB$_QfEqAU0Vi1nkZLh|(g?ZD z4EIUV;9voDl6BS{lnE885-MEQLPfnIL>0x@BSU39GE~R1`)~UdD*6xm)q8SCm}IO+ z#$n3S$d!dD-Yv)*%>{X*8J`QoVC60$^i8PHvz&Vg6rE^=*8yH>)DX}IX&7@;Y}px# z%?*WVSg1NzsAxD=G#n~AH&WEWqxH-)&os97Ed8~Cu z>2lH|X&j@ZywU{BtTFLv?MoUM&WN&y%)$|_42Yec9B&e2EX2nn-ax>DO#iT7&WezG zC=CbfI9=LV)_v~k3 zEG2zea6Nlz@c1HledkKx$?af_#UGg$122$oC>L`$jj^XR_)a> zThRl710u!k*qwG5*I`kwRS9B&_BvIs$y>4DuQ*o%FLbU9KEt^R_$=r8!RIVdpA+iYGW%22XOX1THyO1Ye_E&lwumx?mN2opb%*pF39p z-{@Q!e6w>U@a@hO!D~-Q1MWE!4mQK~oMuYq8*nw%mCiR>+bS!9z*|NM(z?e5fdk`H zPh<%M9;#GogcdI6JmrWTZsIVbnY^>D#_>8)-|W(Qx4G5?l6>h4B#^W(tv`BSpnDt5 zCA_`b(pv{!XH)}-e~HDqdHWi(SO;!uR0D{AXSX`=?eukdQ4YQU$B8Vo}z z>PK6fNK_!3=tu5kRIRvis%fbKaZ7GDaKm#HxpR#w_?0XAlfr*E1w^5oX@52nMi%?j z!Y3RUUpTQpI&|Oy%5(0MO1j>!uh(QJ25;tE2|V4oGI$H;D&Q@h>j(EcR|UVxxdHI= z6KxNgKaR!=N{WL6;1`{%f(w%}J2seW;rL3Q;t9@`!IPXTfmd^`2;N#b*(B$Wqp__E z4uGr9Rl(ai*AL#oxeEBdoGXI|oGXE6I#&eGR<7qDje}fp0DQ1>RdC0-e(;cU74V_X zmBEKQR{|gDToHVday_<5#eeE#AIyQlIqgueMuAIZa zb{MdZbs!4lMgo}C72gk>tEGFXUdI&<0$!!m_`*lVb!q(4<-&CRQ{CB8MUtn7AJzQg zMBWoc|dQKYINjvUi10-Z<@ffvuvL&JhWE#rR2#EgP*X@&vv!`}pHdiAej9rRQ zDBwF)%KO6*od}06UZt+xB3Cw&1yjefsZSd3euWbOwEcQ@Mfbrz~3sB_N9f( zIkgl!+{EEWEQU4^uM_pnF0G2i&;(v&R2xVjX_ zz@v?7d`;o^jH&_MsRm9xVp7q)*);tq<3SkhPAYPMX^CzE>5cO_4_R@3o@uE82}XM1 zX+amr97W$(1y{Ht;=JD}APRGD0%M-58koM@OltZ=e6 z0GUkb+JIVgrffJ?4XsRc{G00Dt?Ev;DITqNC#<^2f5<7+T;5gMpW%aqpZ*5uqHqBNdXG8Ls& z(O7$0X>6-xDoX3ntSF5yj}oOtggvcerI5hnaVU_mq~DYCXb@H6P2G}6SUpi1M3sut zBCMV$4Wdd#X%SXWlm=0yqO>wGJ{i3|!Z_|?Q6-^h3b&jjDxS z<|x`jrPuV~SvYd0Hkcza6bqv<>ycQX?tA2yH5B~sk>Qkns~RqQX=C=C`nR0eKoB|RIMsl2-!D28g2EW#cfFKhF9^WwuC*;vBsu zXFTwE&XvIDJ68r@=v)Q-E$8~d-*&DF{=Rbq;QBfouZ~|{pwUt?`IZOVcCHGZ?OZ?j zVCO2}j&o)3kaH#QuyaN5XOxo%Zp#ZaKI?)5;FFxIf=_m?AN&R9D&Q|UR|YR|t^{7_ zToL@(`k4%dmCKO-R8udH(SY9Xl*Q4refs^v`Za->ev4M2Up=Q^{N3jF)=q=CMz69$ z0B`y z^wUdR3ixZI8YFE`3$Ob0Wlu0#!&lyz%dS)7AW_L?g4frmj8dod4)hXZuM%93x z<>)5;MxAQR7bzGZz2u3|h0&Dzwf4K;rfLnij}DluqlK_Q67CfJ{L7k$grn@RnQ-C1 z=hf7UZW2iS^;|_ix^n$T*}H58w?kj$*$ApAJfWDAyIOU%DYSV`t*iAi)#|2Aq5aG$ zs)~{l^$h<(Hi~TqmUu*JtknGPr9LVo66!-CZ|svlT+jVgA@pQ0<(va_W%3g}u`(gY z%EW0luAO*XJE-!7q{F!W$_BB+Ao{fKFs%tF=X6ClyO{?K;66qT0}nB(5&PM|Pu4aquCwro6!pg{CsbU2(XdWc|J={v*w117WG|Bq3qSWUr-t$KUZ?Q$ zD4P_+_{r`jx`1qSCHXOOxs^Cz^J5E}$#upST|Qy|lTJXk!nhNkutQ2GAe&{}iBH%= zr4x{89CzZAwk`d`>;}H{4>R|@xQ4^>-ZC1FL2`e-?UT_h+qO}!8od@GiNkr>~Bok zoLwgr$$J`z42LrD59pd#YFxJP_|(tJa-c0IHK41GLcd0(f9t(~EJit@&QobblJg12 zG0tLnXBPT>!>l#V)SaDfGKIq7p%=c2L!q%8AF=T*vsDA)w%9_^QFg$n0gp8*@`#U) zH<22Ucyi+4BSOt9kXR-@`Gqn$!Lx09q|sE3MWQh8)znR}?WhKH#ZgJ!sJ*Bosd1q9 zik6_KwATtmI6bl@O5E%uyV%MRDdr;<8R^Alvz`rK8#vXdXafjuYx0IKl*t*ISR~4O zD3Uwh**uT5&}%>sH5wd_+c)}<0y+MO&m6az9WsOz?e(4@ASd#iU<S`?TF0!dJ+krwI7xn2Q%3C|HGifVYKtY zXmtsSnI=;NNCK01TU}brwEz618`RVTZCGmz>r+lm(iy*o&HU(q za0F&lcVA&g%Le71aN*kUv8dmGC5J_~uQ1RJ7oUU+b)6pR+R5go>)I*m_noNUK$noc zUu^H1sNc?!?%$})-}IX2_ZgZqN@dKd!5NZ~)>62tq->ZRj45Rh z)k*!~gHT~FcFF^76^U-b-l88Nk~d&%H^}6a6(4=TEHzG4_&K9$K#wB2^Eg?h&-7kD zQh1e9OB7!3R2cg%`q6$a0(A3(aT244bvdD(tvc~6Cn0$D8#5n;%10S@!XU5;kjQ!g}Lt)v+42Tyjc0xmmO22XLW1g^ z>&}(Hvz;q~|5eUJ91b(7Urjs8tq$suz+2L5%F zAgvcnumvQxoOO%H9@Zj|A4LI{Oi=?!cuBC$F0I{N5J-5bAgzzPAdv7uBCq^wT^!viu5(=%kh-JLXUG z!tN2LGw9Gg>+8eB7&3)H+ahl-ROK!iINPOwM;g`nvchwWssWc86&*v$ z`VlsAZpyb+k-bby^wT^8k(OxF#nZW_r3S=vv5lvm#>nGyRl&us=vsw$I0ZzZJV=dS zdy0K(;S&zX%YN~%bif6a=Om5U&B7s*W|h}HRsklS^bJ=Lbg@hH{umF9GkirlPa(A@ zTUDrPYZb|Ox(W^qYA?4H`B>OcpFVO;o&YOe+qn{W9p}p6b)Bn#r#jaUzF9drD9j&6 zj|&2?P(M;ZTBX;fo=BMjw^S+>q_w>Z z0ymzT_Duz8ZLX|n1a31*kk;8Q2)t>OAgz~N5J&=3(_>|@Y*}am_cf{o%<77NWd)>Jo?_!@?_(T@vE~wv@3~Ihd(!kZ^@7=Vf z#pf;jMWaNCzc`n31bbX3PQ&VF@V%P@pg{-rsY zV9BikJ>Q);O;N>uP@UmKB+JFSRJVIjyHzRoAR5a}R8giV)>7x(qcMAt2uU08W#=R| zw<-z1Z-!aMG9H2kLy%LJo|8uG!KzehNe`Us={0%a2;RWC5_qO@$Cbc)8+UvWT&Sc+ zz`nw9C2-NWsbnfj>#nRQjWskCsVJ?<%Jv+fLDo{yAZ>+1 zGz~+Rjt1~>r6wimkiRNNo6Jb;7mnm4M1Dd-Vvc&>6XMey%pr^cyw>+4mdwp6&kQ@DGBQ(^A-=mix?TmY}HqbBPFaI#V| zZ9+|jJ2aX_=H?Kdzu***{H|U&Zsw%pE=zt(78Jp)QIH=hnx+XFd&4M~^u5 zoIg7x3(lEMzXlWV-UaZvk!pNar8VtC+iHi?za5${locDE?s}IlVRT2#J zJ9yw(=)_rwcA`yG!RDr@2K49}=tQAZ8So|V2=p8@$iWny%+fI| z7eYA96#?CY4j%l&rGR)M8#LxvCWH#jeO?!WpZgjC{DO{xtObikXq<0D(*S1Hj78DX znjZRQcNsKlxu=vyW-VDTLW4<)2HLEsvhXa3mRE#H6;&XK1~MFo(k59wy)?)i!eRQh z(sYoX-nyBSn16dQ&G9l`H$!h^yzzypB~+*?rz%24@&ir%T~v|V9!XY7RF7O)mgF!n z6Kzya!i7bWa5*)yIB&mMoVT^aKYJTSCPz&?S>4u?!8k?Hp%F#%d_n*z23g_I&F+;m z;cGz&WqRFhx`%-{nf&n0$Mk1|)qNEy7XrL_)xQ$~z2zs$veS7pRl;eBI|?y+%VOYPQsYQCK|Fe$&n8+fFtKW=Zl zKz*+-CkIv}Ss5;~(&K>8Bg5REt=l6)IX7aVV}0_QBf@{7jHtnRrcH0b!Rw5pekQ{Q zaWq~r_Rt)(^(q#CpD^kmAVy_g?u|{7)XM{nz3jwL0}dN?5G(m2r^3i*{b&6O)gPtm z2`uM#PRvyiVwRa3hMY5*KOglvh+dm|v_R68TSFMmoP1bp+5K}?ZVEYbI0}PjL>LBn z$AWPQes{|l%%5Pr@u2aS$s2eF=StvD8+Tj@yudj5J%5V#*<$R6BiQ_~%F4qL;AfOdOO@7lToCxx zX{mlmA8@fzE#Oa-O4ZT2!3BX&7}YU29Sf~-3Wqj_>HyzuR13IFsnjT~9W^21FpwPO z&&xPVO|nG9NylcF7D3B=1L9>WNb7y(a}$_#CH}tf1Db#A%f0w?P1u(#agDV!OOq{e zHQ@F}HJ(%WR&%294ux%}fU}KiJ*My}qiVqCjf(C~-xIq|RgpJ|hRPsALdD}29Xvac z?!j31V61yE)*YSIQ8b|WO&;ceGdT~HCt{)YgbNq7^VIb_^(u@0%r4590l7QDqv{Ys zInP8;N{z^3MFE`Zg@BukYtGRGMUSbMQrYyn--f&y#zrq6-(k#CeBv~U-28B;=mj;4 zqQ1gz-B44)h5bUAoD?0edHB5LV-^q}SCc!*(TdqxKi7Fe~YLvaV4ED=d9|6c7ef+DuNF0L$Nc_q)>rrV^# zS~Cl!LN{EE;Y07j{&GNBR8Rj@RHP&O*~;|v6?TaFC)~>Wy)mcX8>4=6HC^Y}2-bk4 zLNXX;A?Nn5rb(Vj(eC zxeE9(=gQzGoGXE!cdiJ2O@AhXVa+k*XKU)^qz0sa?;f4T+NwICY!*F$@q6uV3IiG-T`=orbqsy%+E%8OD_z@l5xzl%2SDdbo^2_k3f43*1sTU3+MoR^H~<%&B%LYC7hikR&}jpgB^mhlE~ zhK*APxQkK4zj&@RTot^Va|7UyD%bm| zBN``W1i>G3t_mJ;t{?ny=PKY&I#&jN+PM;VfpbOh?5%7QSyrHNkdnzZ3_jSoD!AiZ zKX}Nw3iwdx%HYGDD}j%6t_VI)xn2foT;PHO;0v9rg1_xtKlr=ORlwhOt_)u6TnYR` z=ZfIZY@NwqIF+f%<2CiNy#ha@RI=f;y0jL%AaH**Dk}x>%SN?;xGhpZJWMUn`i1ue z{_FK=2+|k0u|_2h1GhG62)M0LEg}FWUx?j3nMSbMn)S^V23jCs~Y5 zASEFdfMg`KK+8LS7+VI zl^}VTCA|ZDzfvn#g5+FR0%Sl|t|T0+BQ>m}EW8@3nnD3FH zg}b#J9@T4d@&-?}k!b*@DJ3rjk92A5;BvoH_`FjasPEJCnpglIZgCw1oa1pV9-%?7 z$)EjRgh)_5&$10!(WC(JOwRk|% zvjgCXt>JxMjwO(};cqv6s zE>S?Z^4RW~-Sm-OXf%|~x!;LJqRkmUaZW4_%pAjFD4Sz37Ktnpz7N(=JgJ8$9Us5w zeiB7%`IJD>5xx|JXTshON0!bzHxFSGP6?Vc11_#xxA>w=#)Zu>5{sFNmnm$d`s+xvn%NvuCR$*7$z(Ij^@XVF8BcDa&A$#){j`c{#iMi?;kHODj`^c#3)H()^_n~|0DslF68H?~%HXd%R{@{nTtE0+=c?cfoErdl zx3Rm)+Y2-nDVf}lgU@!Z3O?7le(*P)tAHZ}izSX%3_%`Rt;5(cvftNa01aI+%Oa{YQ!jM0wsh8VZAVJG!3jDUJPi|CN zU0N6yLExRE1Zn+4Sup~{Iq5r=YiFBlO(0__Qv!%HiEB-Bjhu=g5NA?BTJA^mUI{5$ zW`5Lxq)HY$APUoaIa+_S$m_tDjA{aLBJCUIVmB@Q%<;a! zuVm#yo0nKeJNFOe<%B^uS2K2cRofxVb>kPdnrvUH{&XvFqRMY)M-qa|8mm7C{@&B;*=3#PG)%t%CAT$VA zfJ%W3#iWhkrI~|FK^Y>TR;Q}l2;E5-L{OA42T8i4AOsN!$RsKq6$B9#6cH6Q7a4+r zL=laE7?}(R8YT@+{MM=Se)c-q`xNP@_xIfI^IZO5z56|DuW65Us=EVTV|&*FzbbI2 zc7eYVxKpa&>jQUc7r18!w---Da`;3Tw?5!Q3eE1Yz$Zjy`)=O|t(D}{6oG`eTIGTT zLt`gwGy?Gj*9BfDDmO}tpi6Gh#C%eSxdnVU#5@2b%FKK##JqBdV*p5qxgxE}t_b{a zpjyBy12q67k=z_DPb)b-N$Zl3RxfZ-NNW&SOshAfwQ7iC5J)0f9KB&2$i+4u;8~$> zFYrr&8U&I^ZjP3xmHbp2X?;4RH4*qLrDeYzuy}|@F|mmuv4a(f9fS*qXb^c8%ft~{ zmxrJy0tv6(J6-~>R}}k(A~)`liQfiO4dCBJty&qXkKLjc8`~o?mR&S3e1$sz-XJPd z1K%NT<;n>|BQ$>O zDh(~!ZwQV3-p+m?`~81(>t}tM(KNc`hj@vOYOPW^Wy#P8txtuKZUGr_O9RLuYqN9V z5Dmhx$u)l{4x~-SYkInzVb;pw@ga$*K|B7ZUY;0`L=6S&o z4Uf?*5aWMqrM5L`_|9gUodW-|qO{MBgt2@>eYlW~Iz(=&>+4Yi4{_0d*KGTY$E4h~*BR4PlSS}7D@kTHD z!Xb*zR%;`%aEOhQ{M%%lQtZRlJi+3@sMx+yv2~-CZ@Zb=Zl<=IsqJJHGIMV8p#VM` zs42L6b(mBQU^P%vaJRV*DBHM!)UIUe-6J;zcduY*i(or>OY#oQlMjaZ(hEFY)asRK z!#i$yLiW)(F7n5f2RDk6W0E9x3J371UEnW@YyT_?jVlX^u|JIM6%y(L(k;97^d)Pa zj)#VhE#PpV`hZ1S>F0Ck2zNbFLtgAyvB}v_&Bu+t~%ERKG3-;_#o%H zz(+Y(jf+OSHz^J~3V?)YhtK1BN;F2jN=9*PRP4{F*xd%|^)^Yn7tw2~Q%4FCxSa~~ zV@s83QaVX8t2Fo`=c?ej&UJxrajpvfzH`a%CgSr<=~%UZpB9x*F(Q9n+xZ$?UC? z*@?_3T1R_ChV3C?wa zFBI3_(P(_i6}!O~Iadc?;#>`UnR8X}T<5yL-`=^9alDWy{pRXugAII}sC=+#easbs zpI%0h)>mB-_|HJ~16NjX<`>u{D)&o^EbQge@^fgB1A}Rs5s*akg+%L;Kex0Q`ugRNu{GSx}M))J6J{&(e+2Ha0=KM~UGr;67)1-wDjn92o{ zs3C)2GU%~!yG1|I*Wvrl65Wn}V6#NG<6j>y(e3yLHm_ECq-Gy|$FL+F#8o-f2CHLp~Nh*oTZ>92Lh&%bYl6du$+!u&+ zj}S`(NaS|CCsHqC63+W&;B+_ialy-+0%FiUn52JwJdLT3mW$XPoN+ z|H-*-@UzawGd!(GAN_lCGC^}(l0+{I(57+bZh~S-6eNu zwtz)j>Fs9IUGolambAAaz`K-?&9o&m#_pc$eS0r5GV&K{;G(S=NBg`&Dwun^%-qvu z=ANDroBNy0J*DKSrYO5nMAzH-XV?oGw)I3%JBvAMm27e%>4XSc*Z^j z#WU6Tevw>$)ICYm_A-N*_fxfv0!|dw{@FtsyYG<)VtT+adxqE+&ZM!cNYexE9;gOz zFAb+@9U^#vQ#?>?`tz}QBc5O1wZ(Zg0 zI$xte(zNplSXgKC$`--AFla<+PUp>}!F)H1z{2vLH!}_{U5{RT>TM2|hT>nML9m?$ zSQw9`W#h3ljK>DPZkNuW!64aB$TCEQrMz@ToLV+NN|y4{ve8(YY(QHngl@^Pm6PnR zXl*z``&#jKDJBX6FzOaf6Kb2q@>6ktkTf+W3G>4!_Ltvj!5H;d!7X&m7zNy3l%0a{ zh*kE`Rx(9$!^#QvGbHv~6J7N;Osi~uLS^-(o8+wxlNVC)S~HhSyuv6h3ZwY6b|{+y zi)PSZTe2wtWOr%n(O|1FJz(MdSrlf)dcO7+g#}5`+ZJh1b_*L=nB9w#!G5LLUC4J< zSZHj+=5E`-mJl3Fb;+Y=Wj%VdTwWjBQDX9IY%DD$vnCii0Q zIabr#Q~_>gM#b}Ne~rL);pAvyV6Ra0Ch%3-aaOUPjN5dC{bf^C-;OmPvn^NrfD{-e zQv|XCb48ZmkqSI#X|Z)#_jm;w#ai1t?BPuyJAQ61o}tz^uF7Vr%3zqE6Pa%dLb4Nq z!t z@t|XLz(d(xRb*vk#{-!4VVA6PR5z+p@|#K9Yh7*`^66)%U9muo+e z?T01p6enMEE4d5w(O8)R+Y{;C>o}{;ZSY&w@pDjP27Tu2y z-djKdTE%`%Zf5eWdmNK}n}w~zf~|=_Y-P7aFcDYdNtfIS@pV_&jQfBOi)!!w1b~M& zx%?vZ((k|!crUPEYVJ^Mihc#9CCM?566wCuj6s(2)AcifVwDz3BkA@APncn`J?5Es`?3m*c!v0!v z^39UXe+1k87~*4sZ5yefWH-i8A;`2>a`0ZQw@i0P+86-~pS_nPW7Mnb+;NgN)55PL z{aRNu+!vqmDUS~-#b@#SDf7WrROW+cWj=VeJRdgKF#STfVNS&2M&YyRL?E9{ZQ?9Q z7Hyn?RTt}p&&OEjMj zqY`IeFZ@&MeOSLQSnmU3y=<9a{1RU#Kt`oK#qc;B%=ZErp|&1j;Injo;uH@yVX%)e zqcF83xNHEiUOuhph*oI~D2-+gmFRYy3+OVmHt@hgJn1OYk3q9h2GXx={OCqytZqQM zl^1EecAkCw?O_-ADCer+Y0h4i{QBec$TMPMFAc%E}L@U6~O!FM{>1^$zBJ@L8D{JvlF(N+|2KTQ?;@d@Bf zqVh#X>&~Fq2YfhC1Hh-2=}YS+R|M{&ArsVOeMqAe==LMZYekQ!#@TO+h6qis__%4k2#1SI3UFRklBT7y6` z&J}6h8x&hWk~SwmGS2(b^8AyZqgtdSj|wB(V6evqj}3#ed@k?VFt&L*_lQ${wOC! zbvTM|>OcZ0s>g{hRLR|21B?F*DK&trhNAYbA&9e*_mnTGm{iiH2$`_&8^w%cOEwDV z!`g?N{X+zUjPyLG*uEG7vlSZkS}*XF zKsAW;h!AP=^LA@V`-sqMfcZW#jKctiJ{AlOq?0?@UP#&V8-+?zxN{ZR`60pv&~VM^u%g({g7xZ62Yx)*mIWG}Wa3dQebzPasW zU_UPHk1(r(*B)`lM9W%Z9tFXUndhH-u@D4Ehv>L3$;hg;JGdl^>Z{ zNrsd2f#p|np-EK|N2yA(cce#5VkK2ctZb}|c968wANZC)O^kZr04<9(jfqx~=en(~2N;DoUD1skyt_S?EbKT%Y&eg$> zI9CHd=3EuL*tst7p$Ftaw*%}{(aqJ-J~jY}(e4ny$EB6sA^S#XttJPi2&@IF5BRn~ z^#fah>H`vN$;E}iCqBDV196+*ZE4}z6oGio6>0T`I9fpB$Q9$N;rG5mJzAk2e_V!r zUM-@^Ep8!~gfKckRuzhl6Qg1eM#bh!%DJ23A_v=y+TOMc1sa|-4L4+?mPD0}-ldzcvhRwUyY@C`krr)5aL zN{FffWbE7aV^e8m{&Rzj?VpC6|8s*JmtdLVk-2>_8|Pax?4ujw*w9oJ`Y_4tGytFM zTortpb2aeV6T;@WphDx-BF$h8Ty?Grt~u8QKB{Pt#`|2c20q%kDtMZ6UEmpSFGSd> z1V<`0+rEMH%XXIZH@K9HHFaAJR=OqZDTk?*;VS`pJ#@S&=9q^((2{EV=!tWVY(TXF68}pW|E&{Bh^% z;B%ep248bvJ|WFV5BST@b%Vd+Tpj#X=W5^^oU4LwcCHKjC+B*=OPuQlKj&N>{DN~e z@KWch;L1TEw=VEX&h-TBT=y8^Rh+AX$2wO7zsk8PxawRN_}$L+fG0WE4L-!VI(Wdj z8hEO6Rq)Zyb%7sst|wj$%(DwLFKlZCE(lZ;IA50X-If;iOI9uBFAla^KxT`*69Ilh z1DIbEX)(N}2z+T7MOuu9DFP{dZjlxRG)3THh0Izbv^=xq)8AZWbiJf~N>6s0Z|m95 zL-q~elY#2rUdc?8wB3M=n2AOa`)&%fWY741cg*~9%rx| z>mI1>YXa}rZAWTq&MIcDLm&CYl6+v-U^+eWx@!RyeMK|HVcOO zaaUN1xZ^M?EJgNfqf&Rt&pYCVfwf*U<(cVMvZhy;ir1v^Gf}?{aW`&Iwl{~(A-Swj z!Na{5(A^I(;IDB*K#FXYWSq&mq_|6D;5o_c{sMl%xhnY2&egz6ovVZY?p!zcAI|lF zS35YI`{Tg<@5s6K-&vt?h)4@?9QaV@dccFub%UokR|g;FTn&7Lb5-!s&UJx*-&+VU zUL90)Wo2e3HE^FmHGyZmGdGo=)U+0gwapy($h(S)w4M`dia>(PEq03TRUwoX@E~Ps zvjljgsQg%_b-ybDUtC6!)-5580bpMtjn)XQpNBLCfMl4vruDKb0*m>kp9VKno)bgN zlhZUN6EJSsAw02;x)e|c)L?^DpTd|M9J)y0%m?#E>x3HjG~&%W}_HrLNV$J zxh52&;t*I$xXpgm2J9gWrXdUx&BZEA))RbvDAr&a=^#N9an=*;(GLR2B2xoePK8tfNK8v$0K8uqsJ|j&Ar1&h(mbl4wWBX;Z zSGd}tMw+JnN;knc^W|8Ni?JN_xIW8Kk4v^3^|*@5QSVgPpK9>!wK&zNglRM-&e*ib zip|X^_O~O#J~t&!#20s?#qhTi`gKemqRfdxW6iF^vR8r(vS6CKzBcd(r*;%-2gHaR$OYqE?QD=wqMRg z`>q0be~2JC3h3o3$tQgd!CQir2GDyY#plrzp;zLYWVplF1qsN2=eHF0P_7X<%T0na zAZO!g$UW~#uP+cMHVN?XD<4iEPE8AsjYfWFH0q~<4+g3Md?Zj!;L<=ffd2?ob5-4c zb`JNTCRd|rP7Mn_;#8b7RlLJ<2CfkjOm2i$eiB?c1T{c{n+12t4=_C}H!EzLgkQn- zKV-WwRs>lXg_1JGH7V&8tE{7}_X^o3-)g;n^eTn$Vn=V4mA3~+$>u@tDXs!MJ5bGA z1sSB0?d&M2oDh07fb_N-BJd8^0=n&F0Us;v6^jUMe3o2LQMo>Zlk6{_&?C2!)Nrv> zm}Vs((|J@_a-&#Z@6=jg+Le@jeX01zoCeT)_2cV|u(%pPcD0h~Y%J{+3;L_-b-nun z{xVR>+CE#4&J8LJphuXT{Uxc!Yamrge3Rd9?i=VeOeV$>X+I~~e)A&yf^${ypPj3L z|K?mB{CDTN!Ig>mL6CiO1YXU#ao|PGT(AA+g~snhW^Z1=k2u!@e$2UU@Dt9}!Hb=% zfuC}&3SQz|7kHIcAwU{yh|B^6zsk8D@LJAwgJ11j9lVZnHSl`QRlzmqy1@JQ6#|Us z5<~tfmEK+rbyC?ZsI-7D1*!?WS0&1?6to@^Ys($@hh-FL{nHhJ$0?`WBCVf^HH*MU zmQkcd`XxIJ$&-$K!42FX#4!jYmn@Fn5n2xh#aX2Kc^&3|NQioiTmRBXYw7yP*N-0*PD*vx#Hu{;IX4YiPD1KJq)(9IY+!y`0$!-|_6JGD2W6vHQY@@3%GvbtSx*Z`gwr~$%R zE4Uk=_Admg0c0-NMTwy5VJ#-dGj8xn6-fOPlwN6pUKRWdqZSR{%mR!}QDXTAp z>>9YcEEsCw?k=Zrw`Q>2z};R>#RE!q?yeVirv}@-!1G0|Tp6BMA%?464@g*TJp%iK z>j8VpP0PN?uan zkNKGS18?jT66pTIgk))EJ;5HsKpI2xv49wMlE2Incu$W3=rIhEGk(is7>r}c)Z(!r z2yPsi4tT5w0rVi6aS-;Nhj_dW$#tUS;y?&n7U}?gvxflm5c=Z~%InZSnmU{&M{a#e znoY9ppON$$*j0zA5NDs<=2d8XtDp$J$+>Ru z&Cb=q-*v7AzQwsJc)oL8;K#(ZgQ4+zSL^{VcCH)zlyi0P)6Uhve{`-2UgBIAcy53A zL^dzp-6{;*40W_mWI&2zFE)VxEv@YC**8M#UhfMe7wZfB(=vT&5nRdJ6GHn~Fy8_) zMt1uE5=?$ArbRsVJ10O&YJGtOllP_7uezBc@Yq1LfSy3IA*BiQk^u2#9(zj)*-Nx| z&J}6l+&(M;iNpTwkqPlAU#JSs3zckar%c9&jFRK`C~32B>|`SBhl8Oeh7JyfnnZb_ zQ&S=Aub6SxWxt*{~4S#fLJaGn_jMx?9Qo5 zGF4KQvz)xg&{R|j9` zTsQc7=X${3c5WPa)k$GnyM84aT_UqLVc^xB>jA&Yxo+@U&eg%McCH3q$GIwaUFW*M z6U5meaQ#X&-tLOyzy~_l13uWfZty#utAiWP)xZ;-tAd-(b%9quq)p<)_t4 zT7M3e8~~C?e*DndNR!DZ6_Z$Nsxof-dCnUPEHLauQ1<9HGHC`y^_!V^!gsX zE4=~Ako{HaMMGn;wN;o0y+Ec&t{6{+x65)Ejml`Up%?YF*Tf5lhyjOfGWK_m{4EI? zB}u0$$-O#O$v%lM-&68N5Ht5FnC!3Z*uTp%LfeB(u5;U}(7T3$H-M)HY9jEwKqaZ{ zuScksyhuz{l5kR$R$LEM20RwvDWb+yhLYcFI#AEvAvv~ka=S*fJ?`Xt$nR*1{v^!# z2JmfR3!4P|m?*n7RoF=19M0uQz>7s?YF`)rc2H{oe-x2h^)Nc`;uOZdcEx{BYUv7%>5y;7BA>c=W& zt2oxNYQ|}xGDShLifMb0$+F?tB!j zJ68kW?OYYSz_~8)FP!TE|H`=<_(A8Y;D?+`{){rUJ3%`3p&58epn8F1YzqK*j9b%URGt_S=V z=f;809^|#msY@y}W{b1{$AQmrt_OUsbKT(coU4P+cdiD$z_}{;GUvL$mmgLLuv0~! zQ)ad#fM>{-jSlcaQTc48Rhh!OgnrGj!kt*pFy)R08&z$tUyYdMcPVAnX}hwuKlDi=UO9wQHz{&U2@&MFzs3+`>A!* zGVFzFQJ368r+kRirffRm{c((@6$fZk9Gy{dXqovaE~Db0HdT?g3WL)CzCTb+;=IEt z;4cEz05afq95BGlW24dpn`t)9G@E9cP4a>8%L?XuA*lX0Yl?XUqbUp8EH+!lKo*-# zejqC?8~5H3S}eBZt~)AXip)%g+^DksuXluLNu5lQIZ2(2ibtEY*vksr8bRc9H;yA` z%R*@-q2#)8G&$QTAdZb}hU(;?j9JINlA`ugU$(DYkrw%w#W)$G$};IoGBL$CjV!?E zzjYMwYbCQ6uHX~JSvSHxLfcJ=r7JX7iM_oo#?iOQIQ}*n&xtk}C(tIN3@T^H@oY)^ z3=I5apqjv^M6FzzIj=&4;WGPkhiTN6Yg>~BBh=QUac)tQMxhRKhpEGZMNJy4m$uE4 z;>;Z`DbCzsiZfdqWxG2K)=@k7xMD2*HNpTlfFy70k1;39lI2{oN|`)8!S>`m1m6{? z2GFP2Y;c#_+Zz|b;^ zMx}enT=kN0YlpAhDM1IV`7q;Chxq?lD7An_@pSGffLg~n~3e1!FKYJ4+C5# zOLqBKrTk=!wX#zsF4|nh@p;MY(=hmZ&Q-y$IXrw2oL8aoT9MYd3Vxk)UEqC-ooO84 zidAsKxi0XuV&_h2d@Yo<4@f|^uz|#rANRCyZi>JO@|i2rB9fA=f^vQ<#L)uY9jHDa zhRTQU59&}+5VoTd>V{6mmH3%@k?V5P-aFW8jv~QLq`g(>)d21lsN}mD5CV-`!_IYs&v32>e71Arz;}vk|0F7npA;0qcRSYu{;6}_;04ar!9RDd z2L6R}Rq!I`y1?rkQCMm;))$$*6av?r>j7`*TsL?l=jz~1oU4KB&Q-zP&UJww6xXg` zJP#T2bCsEW&IbN4P=ml-ot+nL9PD$WqqH;xAN4p|$-ZF}`2)X2aJ^`N}qH6(( z(vA-xA?8b$7EziakPvf4TBnA92Y`f_E7J0SlcO^YxR-#Lrgn4y7lyQYfkd5o>>Z)S z46?pJqRtg*d1%S!nM>sCy5O_{WL4R|gh%GFQP|!&)TasDH&6}WL4j%ln}KQoDW#bQ z-sxIE&nCJ5eM4DL$`z?<8bneo%oi$?_DX^}TPd9DsQ}5cjuB%To1T%WWEz-n;!T+aoOgx5{+LK6u}Ff>j6LD zTsQb3=jz~xovVQtIadY$&bcn|w~qGhJ4b~rl8U}d9c_06(l1+V>7PTV<5Mb=y?y~s z3APRa7Hy^9yz4Oz2}OJB|=L-7;=@{p@6?+hd^$gCw(BhuSv`ldKzrDg|MHRMR0(qiO|7u`d)e_x5^^acn^Y0kF?&|OEpi5nS7$;w?x#+_< zIUUBy3?tK~2ZC^GKE-!QUT}XaGsZF11AJl}*A~P07?kQVsGv&nX}V?fqH$ zdj@GteZ)i+SFW7cJ%W9rYLoGdCN6qfHuNJ1qvBpKY0Yq0{O67icBI@QBg6E{Sz;y7 zob43jMq!6<0NLrSyt9UByx@Akbu@QOZ^;l1&V+Vn8id`}BS9 zAsQSi?ank#^v=L@ik)e2{IomM_)Jlg29<4VQdo|vHc4ZGPgCH4DAQXqM1xUjca8^z zP3udc*n_}p1JwdjRXe<>De)Rbv^XsJ@cNi+GIn;=h)2w*y;K;goc)6banVezq+|<+ zs7^Cfrv;=SnK=&q)1+4RZz_CJ!TvB5VgSe-wPW>znv>*VufM1bQ>0 zGeSS|Zj&TVq1$9!>NXjV?V9r8!A@Q*>Mdato;+TVNbD3Mj{U;yp8SqzNK7jZ%&0i5 zk`s-cilx7DW%ZXwXdDqLom~FfdfWuP*5O7-_-#E3KQ62=b3)^-A*%+Eg4=Kcz1-H7 zNyV&bJE3txm}$vrwYTy)Fyz$$GP&#r?x`AHN`3}^9~q!m_LIVKx3Zrej{6l>se4N< zk8!VMrX2lBr`#mPIp7Hc3EdV$9C^w5NL7+g`z32JUIFtoG`EITergx^Hs`9~JDjV5 z=Q~#i-{o94_{YxmfPd!PIPlzK@((BWLSRva#^*(5Zw|m;aIOb@rE}fjFF98SU*lX2 ze64d;@b%7hfj57DAwU{$5SaxCexq|e;H{nO25;kB9sFkJYT)ghtAcx+>jEDwu3bSI zA8^HS;A5TZ0e{H3Ztyhc>fjTctAS5)t_q&+To?FdaqR#*&B;eKH|&)Pkde1-2>2BZ zQ2v&MRz(g>5lC@zMOswC6oDtJZ>~s-kTZ+Xe=MRUA>bB}>1NvskPtKTtr1$=gn$Qu zgqSPR+Q$`v%|Nw)M4k7g z?V(o#$lhtkG`88Ti~>@~uIwe=*sl6UC8eE0AoqtrraU7^nkAP3mi)@0R|Ck_Y|9u( zASFNOvW1cx7n1A+P84PPeO%+pk$QHyWP2ni1!ZoN_+~iUWSn%HjMHwDvFF&aEwI?F zQL$5_VwXn64vp&M?%$qFaokx^%m4;(nvAa@=!t#iG|MtSMBO z?W0WvlQ;W(2V%uf!}FK8vVy;J1o6YdV^?gns2 zY3-Vj+8)5oL&04GNY2(VuKI7}`7a@Y7PhYlhFZWch#FHlz8m}%abw$O?-t1yZD~UN zB*gr&HI7rVC|UMzlq0W9QqNrzm4Tx~6^a+vpss1TxumVBF7TV3tAe+4t_JRLt`2^S zbKT&*oa+JqQJk&4IV;ilQ$Z2D#JO(pbI#SlFF02N|Jk`Jxbh+GSe7t&uDEtEG(PW& zJ>V}m*A2eXxjOhu&eg!zI9CN=vB1fHMNs2PB@%y#0=l6mXuiv`z@oHGovw;`p+j&T}mw zQJWT!1ac3BGPWT(92f%b1roTu0|pjtrQiCK;Zw3z_7kQjD&|W(b|7il9cuRQf9p9} zl-#S&k{jHPsq7xgN}w4RryTdQ&5_Yy>Ka8fSSr~2+n4-z$AXTcX?X z8`=`xj^EIh=yv>ub~O#zo?&Pw-!JGzOs@YmscaH@HGn$?Y7j#YI0gJ&pc=qu12tIF zMzW2h%_HFCKqW6Swv&NE1o14w$3KIw1`wb2z6Kv&fW+6f3S-X@PUAqqcRK~dV0)1) zKc+rnB7l`Er*tPPf)FrX@|6VH{qWyNklNxQA>;;dTA-R~tj#pmd&aNjFuO8Fwq${n+14jTW*aaH&&;xtRgCS=%C?nvVHmH) zMRNI3bqt&+?fcMrGVj_XLqiqXq2Wo3#PMOm?5 zG94)E!C}an!2Uo@27Vw=P2914luU;=OWS)*rWcXf`$)#zgPa_fpyYk-xWx7#wtpOg zOm0ErlU@yaJsNr?e@E-%dPK3?E1L{n3hSr^B%`)oJaQNPCyo75#t5eE5%(0dO~xfH zjct+4y)0R(#Ij{0v4M|08ihYLl9K7chDY$G!oJ1oD(Q8(>g~Py=`}xWR>?cvJJstI z?f?sxuX3OqkX&hfc<7lY(eQ}COSZd3a`lL0cFhIHRQ5{-U@Vot2U$ryNY*wsAff2D6KGn}PNVNnqfhpM^<>p^PAauU zqB7VoiWExj^p%sf79_LXVShN>w)WmJGBeE*-Y0f zEY%#!|IU&&ZGpJ9*9VJ-Xng+k+?H*&3x{ajB+@zq@!8hv-v;}-nlsUa@n8ub$ zK3~SP-hOHbW%e+QpNq^@Y5lFJN@Ek1Dp#d-$A=46Y5Y=Tu1bsaEyvlzG`<;X(E={^ zn#~@jvF422Pi~S{p=`5Bo`V>C4KOwi^N0R8?&qP|}~DmZxeIkiupTz?9Y0fO{)}ObtwOrWV)IC<=Ln%A57PR(OG= zsR3UssDc0KYCx)%S&M7-8P#k|sKw-U1gVJ~7r@&G$@wo0V!5nj|P=9y|{4Wqbg;^rA!;D zO!l2TaLZ7+;gv>cP)^gMm@j!(>b6&yfKv_xUs|QtuxHYD!w|W?XHv6&Ln6&B)UvEqLIM0yPoHTDKi{&M=F8 zn=qLt0*?>%x8Ee8*i2R%^I5}`o7%QX8qbC?mi^Im!ALf1&SV&^=5QF0*(JaYpagrC; zAtqk7-YD<_O|pywGuLby1DST28rTn>CKHhfmZ>qn{#rOvz%Pfn)BvugMVNI3GtVp# zAOo1Gb((QugiI&ku)e0mV`U4PYA`&Rbuc@msR7vpZ3-?bJ5v^gGi9T2rc9wmOxe7% z=Iv6+%rUqUrb7creJvKs%T{L;urO&B4N*8YJJSQQ*|j5~!FFeQK#rES9t{S<^g4~h zy;?M5Dks(h);QSGUs$$k<|nHr>&;jcYBxVD8+Nx$5nL$2{IbPAKUpN>wGdbY_Ti3d z-xCHRtT!gIX~h$`7VGKeFh7#zduU?& zPz>D@Z1)1)_MzDRaj<=8yf7cug!zZ0-GwOAK_QhsAlccU>#H#j_X#2Nu_DOai~%V^ z))V{*?+KhEDpMmz63RF>q|?J0-v?w@&eY<>GcMgDlCP@&tc=$Rfi-~4Vf(jts$k~x zs@aY(extawskL6L(bGezthlMAWIbSsk+&0Xj*Mc-{-(G?t_W{WTl}()Y-URlypnJAPe{Eut3Z1m~lM&=}6;6 znjIGD8>k*_3s;2gVIaMLB}e(jy0GvG+DaXJKT0a6O0I6Ra>p&FS2o|GcA=in zQk$V94?Wr;yvRPa3w(fcRq)%LtAP)4t`0ufxo+^goa+HMof`*!&k*m4?dP~@42sNt z$_zZ&xgPLT=eog%J68uE>0Awblyg<^H0Qd&2k6VW_Rn^As_4$j%+6gP{jxX2>F;0k zsKeVr#}@E|f$9SmZKc0|Fyjh%r-0rk4hzL+aWdHXS_q&4#I!Asxx?5z zQ?_lr0>2>2^yUoH*ld^~w$3zma&pcvjl-RsJ51wPk>&YTLdZ*Vw3!Di!Kt_n%svrm2zSbDsIqA(GrUB-sLzS7vToJ>Ew$hY>=|K$(X?R{Y>Pa(%&DVDY#4JvMD z7DcDx`Ck%IXtN~SB#pB|3JsvAFa_vS%KlslQ;Ip$wnu}4mmHwv^GL|60c2`fFI?fJ z#L%y0fL__3CW*V1{kf93pDoC^Tge)Yd$p%h+^=+gEm52=c)~zJw@DtGDw+4GO7en_ z5%*d8FRrnMc7TatCpfhWJm_2%JjJ;h_%P?{;KQBk1|Q*E515~)$*vFJl|RBEbn4ud zXsjkOQv`Q8*8^U|xo+^9&eg$dJ68i&ovVV^ajpye(3yn*<86kD9;0lt&-a4=2vie@ z$^7a;Yd<-)`3Zd0M{}RKBCR2@rU?ArGK#eBbVcCZ%P7*?pSp=RhDtArmN>>Da za~VZiZ&$U*gfo^M*IUc3lu=#(p)hFTq{A~S+vB z!XTFHRNsll{*`|3u|&7y?>(02cKp4^65Wo!_sEF*1RMO7P7t49gXshtWP*7ulD8eH z?f%8G{l{={HGuA}A9oLhDc%4+9jN~GHMQRqrg#JB3!$GlzZbNUpO<_&NjOn?t=w)C z+$V4TI9EN7NO;r2U3Jq>z?ankvq^(H?<2C4QO&a_8OaM-Fy*a})xSq8;)40St1HW4A zOoJ<1yEBa+7By*5<+di}Jw`LCP12a=(+qf~>&+Ra!PvAr$AiMAvoH+G0Pr_~Y5}RL zoo>{Wc#R@j92yn7d#whLv9lXiJYq&oQDLZZ_61s8G*c@n+0r4Zb9$&w3rImSbKHYJ zFSU$|gZ-fj@N6hVKae?U$Ilm(5_#CW8*0N8D_L;6$tD$TfAFOrdACUtr_gOOE_LbW z=Dp;@gB{#J!5%AV?@~?>Bod>D<9%Uv4;~i{iD|`w85M_RR9w_}7ihorU>~?FRJuvf zeEMqZ(ePR~frQ`IqwwzuE6m=v&^R(=)c{g(8&05?+qyETm^E!DG%gP_EjevYQa-~W zuLh9GW$$IE8eU3X)tn*&^vYh##NEnX)x`Y@tJJ+Et2FMl%#@>F>6AN9abDmF0}0(0 zLmYX@`bbrhS2ZPTF`jITG&GNdRc^m)CH$CkRq*4^)xb|WR|hX~t{Z&a#|rN*Xna+q zyfvk7x=`p3XW-A91b@e$2TV_zCB#;3dv=f!{Z$;JDM6AEr{-2XEjtfocN3DJuU=MT?5r zegOQi3Xm((B12OI{$2s+inM-nULLY30@wItPUVWU$jua&pIM8{P79g!1IZ;b-x{H{ zsnW3H6ZpYE^#e&S?@R0Mpx6R#e>Q3L13xV)?@McmD+1Rk6sk2sYg4gVfP&)!)eoE+ zs21=zQMq4QC%Gc;M4n9jF%Y#6a}}&o8W<)(EW|T@kn-P%Ypy%k-u7=b+dRd^u1p;I8Kv zhl18|Vl55exq)f{FAr2d@Tx$yfVTvyA9#D9TELeA)ejt_P0`tZ#B#vB>NLc@-2qd^%F%HiZ_eD!uK$xo<_ z`b3D67*MG=DM}`1s**%_SYjoKkbQT8FCQSAZ^_hHUxzKHbm@UTxTcoH>%(!=n4trN zGsZrH{ZI$Ut3w2Xc=iQ6_%%KKp=+_RekJULgXw-b*wkjk-j{tg6vY;1)Z?Q57`CqD zvmv>14Oye|-1g1HoG>cwYq4T{g=VicdnRVhA;%Ts(7 zPu;jqR^7Nf{|}9NMf1&PXR?Ii0k(g-YSwT#_L-eI8xKy-#>0}c@qpxPJQO(_4?-N1 z4cM2MtR<5tJd5Ki_KTw|K8s^5K8qtRK3iVgHdEqojf$f*Dh|%5I3}awP>hNr*jT#> zS3Zk2Ec5uXRD8BPJLW3xUgEu_jg?KtRN_6tsCa8AG4u)_6MQ>P4vfFZJ@*a!oLoVj zt3}3bqiy_D$u%lhbWs2}7X3<aT1RMFiT3{K+&6_J((d;(KxVTGpZEl;z ze(`lP^K+;!ncOThF8=Q}m4XkGcEkaxj+H$wj!`w$#Pc5{e^#YwjVNt~(q7EQ6)~;2 zAV$4gb>PE>QEV}MtT2kpKg+_XYjw1-ER1?U6wAV>xRgf46*MX?piy!C;$qoadAX(I zGOk+jSzNy2v$&4MXL0q4&*Cx`pT+eoK8p)md=^)@_$)4U@mXB+;d^l#l(;>e26;`oZs z;wX#H;#iB%;)sjSmKV2;NF1(Fag;{I!5J0DWK$EX=f@WOM!V$olUD`-v4V; zZhd`>^%JF;x@)Gko9T2;KEcMe+h2*q*4t!kzfHy-O21Lzwd&6PaUAF=^~X-_17+;e zsMul2$Ikc4%^Y`!p-sbkqXveKaw;Bq3=w2@0l*S(qDFgBz?KKq2gJPn(tXbe_C3-* zATHZ_gnxJlzYj=8_V==CVD2#OzHy%T#KD-#PRUECR42U*p+ms-wFMBdBbOoXx;2S=WvWgk5@AVn8~V zCPqJ$##F{9h5dnEX#HF=`}bivtey|=8Im)GZd`&h({$s4TjuWW#NC|DaP78Etze4~ zvVwu#emV!Rk1g8=F-5nMJ@!wEY9(D;GjCulm0iE%el{@i*rDQP(lOwrCtq{e1O)yy zyp`(bZ4_T~m==()IczrqGWPk4R9+15ord)VZWrEF_46r*x22}VdrodlMscU-BX913 zYdv2Pm?Dr5!nxw8zZ&3O7#~Q@;^mrAK>$u-rV1N=w+JgkG;E z_4490)8aHK4wW$TaT%V|Wc4x(FhlRw=S_PTzd+C{Gq9QF;2XnSYyiDj18Ers;wfh4 z>=bvFuI-CWQ9UPaP?mokT$P z>9!tqq-drGWGiXwQAdhqdO%9o)}ukuOb^ID)Ygl0r5{RV{~TegV=K9n8GMe`{i}80 z`$?Cq?Raa>Ki9JFQpcQS>!oTr8}Gh3%Wli2l(X@Mo3lIUcD<`)&eHOoI9X|N@b(dR zuS4}-D^8*KEKa2OEKaBREKaKUEKaTXj08!g_$(glI43)u<5Y}_GcYO++^9HSqv9}) zB04SsMga-9{63JL;iJ5|aLD4>JjP}CyrwQUvN4sDk{`RBrulM$q}^S+z^6D@1>4_D zXuC1J8hE;Mb?`aPb%V!VkoUDeY_Oz4V|9^cup7LFb9L~V&egzcJ68o)o$CUBL|of3 zjgPuwH~0+a>fnz#R|B8zTopXWxi0YT7Zx&(hlkP+sZ_Qj0msOe-JF207L`q-z7bk) zaz)^=%P7)1(G`IgFQZ8753UH@P+8=zX^~sW?T*Yo7BXuAFAY>55JTk)Hh(PrL zi?-6=;GU%pACb%w0)N!GD)=1dYT#$Z*%7#)LgTrDBKUdds^F#0b%B?BDjaPKDm0!I zncWV+&pB5GFLka9yw)WJgOm|T34W|dY#e~U4#8b80sKthj<0}U2;2n|z&k1qGY8xy zgm%FM@cUd1cv?XX{B>6Y-W=3Uu7H0KxC&ll9dYh9Gr$l?XsU$JW!X-wsU z3Ey0}r|y@Y;eJ_y?{AyfvtuTmjz`xCdrmaVVg=2caXEX?HJsM$(Ra!vCpsh#sktHSP5fT+j z(6&Q^B9#0+$$K@hu9CcNSzohl$1v*}tlyz9#TqP;HNz6=XozjT9b;^&O=9d7s}lDt zTY>v3=IJ5!UY5s(Va4<^`><$rBC~TthRL-N+Z;!EBK>o>HJ7BbNR5(ctAEV+su+TBXncq>#zrs5%OMn!?fL= zd4$|jW76;u=SV)=Dd44|+ApJ@SA&z&W(G6jN}m}VK%6io>x>vif_2-kV(aZGfPD_X zHW_;;oh8=W`FpxvXXRFM1XS%1)(vl*BGM$^v@gCfw@YF8wy3SR>uXC;j{**ZT^fRwQiBu409Vk5@;lH1HBp`G-bY54a-mH_Ir}TI*83{|l}!nOmea=!(F@mrk=9wR z2>ih^inMNbMc^-%QKa>ZD*`vv9LbZRwWU}~2DtSyinMleMc^*WDAMY4Mc@(3DAGFC z6@kYuqe$yxt_VDT8AVzbxgzk>%P7+NqALQgSw@l8*If~K<1&izYTHu_<@~UQnk*|u z+ji_>4bKH(n3@bR=1cbV_siz#Zaa2=N}`gSDL<47OWQU+X3gUvoE8Q6W+*`NeNK-S z%wb{Sv`FHoZU~!ya*8R%jIjt9K?bPg>!beEU7Y=iQel%Qd3~O$Bp>RgCsvXg;^2p# zI*Y#7^Cachcnw*0l)&<2IWXIeq6!Q`Ni}Yi=RyQ=HU6SVD#3k{2lMY!A?OB>p)8q) z%wAN=t`6v&Bgi6;O0Ev5xS90oK*5=NWq(6uo@#fiq@~dX zzRkHR_%7#a;Ga5I2jA;lH+X?_J>XwCHx7LM=fYvXWF;DNL|TC3z!x~z1OAkA-QbIz ztAj6ft_J?Jb5-zM=eofAe7+E1JS(Z_B4uWS2c%zqLM^{zEAD6)wri4qm?(AFOTYU* z!~JCtc)9Y)V(1;Awciy%5qP;MDXR6jD*~TdMv>MIBf%o@08zO`S|__AaPBgSw7%_% zz~3yRNb9b-!8LFbjacrQ7UNO!bEj!hCsNd@mt%f1@Ltu~#%Jyj4QiYDoS0O)ty)%V zQ&mB)l5DHepuV|PT9ml0N`ngLsg!D-!fx~EizLBvq5HR+9SU!nW=&A7iX^of$W#o z6Uc6v^#rq5ni`OuGE)PyPnsH#T{2Sxvqzd5kR38p1G6Aa4ag{EYVl6_xN7$2aKRvEH?hiztM^R+c{l)<_)W5Xk!+ZFC4cgisjzjJ5)Gi&Ga1IJv{A8To&Gzu zC}FSUe4ctm{Hm#-eXX|hd zHJG4Z^O0ccjSp+AqoHksp|F14&}dd>?B4!Vb6n=iPI7WYaMsI8n;fF<#V;GCeF=G> zj<@%O6R-E%$%&VIuZ_DSgS)U@9U0sWr0xb%cLS-rWY{L9*~Jw=r4Ui9LP7czVObsH zkjr%99LjW#Rm9&31?mOpwgA_CvG2Z+Gk4W#bMj+waPXDiinCCe(cTUvqG3@U{XW0kla@Imw zlXcCp&M989>!m8mW>rzzZY6QV(6T_v-p$53CBa;*o8(P?!w23{yky2D<>4Kn-z4^p zyTTfu6!&_E@|qkbbn=z<#O13TDV38uTRCR=DyK{3qRv*%T)qmI+QLUzPBV5C`&65L z-b+5!zE$_YgToau^g25fH0gzQ;d5{5egFfU6(#eaS8fM_`_c45oA=-L!6tQ|eAYQi zKDZOwk)FPfYv}BpD4Bh)06x^YDtN%T8hFsTI`}Z>y1_sAV*c^A{j=6Iekjr$cZ26S zR|ntfTn&7ib5-zs=eoczh-*8h@fTO@1}}B44*siiHSph^tAZ<6=GkQx1Rr-zA>(+J z-lP)!SkgX=0!iB5AN@nFR*`wr0%E=7Ez?o5dA8gB)EDwtZjdxXcL+Y_)ar7#g`{bX z6MUyraVl3UxOrd7eON>f3XZ=zP=^Y>LfnU{*D1kJ^J9Xa4O9c@?wYuJBxp5(U2^A_pZ`=vkP{lc?2@z2TKcY@mnkl?aqHyrnSN(DRjDylPpJFiZ1 z1w;Fjp;rSqF$6F`naQJM8+u;u{}LuuUyr8h?vgg}?-wMZvJd7pg|blysjsDOQ`}OV z{!;m+w>jHb2HqSDHU3Mm;S|yB-`V!T(tb~<$Y5HLoEI`p&hj;34cZs!trJCDSpd6O2(qmt$h=n*vI z2uv$Bgf^;UDmx_3-m(1IMUe}e2$IzE7y0hzhIR-fmK({Krc918no}(ej zxsqR&L=U;^8abLEIaPAHBznlr*UZrllG7z;OQMI|b_MmZ`&RWkS`t6lMed>Jqt%}; z{Rbs`*3K>MEs0&^Dr@EFRg!BY)E1k zIY<2OC6`Ket&?j^l^l|sEqRe7c91u!{~aCdEwBI0vb$8WzHV-Loa7#odr9IK`MCPM z(4jwi$aU7s(Uy|eNY0l;4>?Wzbjc4(UfMzb&#%jS{!Q|ql54G>^AjZBC5ay-dK*Q0 z(>myXUHsjW3nUjyJ}voo$%?+_u1fAGxwj;7Ab+5K*k9Vg-pZr2x4i!NMSfm(za{xS z$y+7SL)JFP(MFP+OTIy}Tk@@vQzbtni5=u_;>Sn&@9&_0llbpT-YU7YgZ@6R&ppkN zyk2tMjfh}b`93{AMRK0xk0qDYu2j&Qspr^_`z`Fye}j#4i65|B>wdT(U=c*o*a_m)=W~_@`g2zlQ9sBS}1`cZg?` zdTwDC$?==z?WvM^%m0sFL;Bs)qn~T$Xm{z2R)4PauaW$&Bz`_De;?@(-)-XOOWrGa zzho`{5MAk(tVI8z_n7p@N$;&4^dFYqX!X&1Uj2vzKT$Z9XQVe;{W}%s&m_CH$Stlb z8QVwiLFq4z`o;P?ZBs#CN7;W{_1{TyPsvG=u|N0|^!#MW z4|mWfpO^IfpOVBE+eiN{>D?pw2gz7}HRbt6$?YU}liXc$FUkLH{U1|YPfI>8x%Sp^ zqeDxbI`}m3Dxm9|j)kp6E_3M#+ z{KWQuA-&P+qxZD>QBVBD_Med6X!Tcrb8ev~*(15HWNiN_@h_qOU%AGCyXNv)$ymQBy^lzqEBV@;a?P6LL`m$dF)p^0 zw?Cl%Gb4LXsQpZ2eCKd!E%_PA1Jj z7r)w``I9cmwI$b)tVzcGS5&_#JCh}+NWNF{Xvt}kvA-47zesjIBl%g$YdYAUvsdo% z#l3U6>iAr4C7HMU{})UDvyxXzens+YlK*LYZ&G|4D6UTN-7Np3)xSmhw@Kb9`CCcP zJV)5wQ}Ns&xkNJ7pCf)mlKPTItbgP9ocW>Tt&)#QR`;p2|Eo!kliW+PA$gQ!uI>MS zbiA;h*CnyznmIZ}&u2@{k^GEgtUv#)Idjk3a#`0GQ2R;7`kxSgq2yf2Ydh$luzzmh zT**a}Pf5o1KemGUJqP3#c9%Rxa@z?xzoX9 z@?gnW|FtWqe~9#tmz*nkrDSaX=oQreuJrGb{F&q;$=LoH2jxs%a!bh`$yk49>OKa$>V@60_nBrESyTXK%%HIhG( zjN{!_{dbXE9NCNYkJ0mKk|#-iPx430@rT~+(w{DU;*I^0*UHjcO>#TQ9VPdb#147K z_MVa6bCQ3R+_;fz?jX6BWZeHk@lQ%VBl#!Em3#9ZuaT@tzFx9Na=c`0|Ix@k`g?TH zKTQ1bl2=K7tAqZ8{@mj+k|#(f*IAUv*M$xh}cCWJ7Y2WbFS|@pno7RI>J- zTyw7E)sk`lrug?u&XSzdLI21V)PG9)=NzJVB&&z!?e!(Mkc{J_|Fg35qU75mdsnI* z_y4eX{6C@glafm$i6`#gqqsgGIa~5G9pe3+_{Sull-zzGx7?6CMDl3KS(35;UyA>Y z!zOIA>S1I5uVd5GkIgNDfLam7F>?e?DDuuH-z)Ur4TUSf%v8J7nh`$@?SwNhjGmNb+5hD;mdU9pc$X z`~=B^B^#10$!jI&Nj@vtcX%H0DUx~1|NlR&f1~`4JtFs6mz+xb$ee$(q(_#cUq=0R zSi%0sNdE@O`I3tzV}I{c93PTAUh*2ruSi}m8TUWzy*YENWc{eTy@zD1KTrIQ@5`So zl6+3`Wy$r9&Yyoy@;j2>m%Lpvw!ez{V}E)2E9yV?H%|VpjN)!6z7r%rDY;N`kz{P| z0`q&w zn-tl(u7ka=s^9#7vHxQAt3`gNsvYMQ=TrS)&g>vLUh)%?H%tDvWZZuv@mr5lzw1M} zg_`6hl3Pp0_O};*gXFg)Z|sdj4>>jOt zACjEb!T!nO=SmXCuRG|^6hC{E`X60E{YRw#q~x=bpP80dX0GHjl5xF0B>rT{nUeI6 z^()8c%$bslCF>{T{Cg$mNXGr?_dwKdlJo~8CwJ(-#)-MbbtGRWd4Oc>@4ezrkeqZ< zu5q+vtbdL4o|LRfuSaq}N$gBl`%KB$-euxfJ~@9eY{?0y#69!&_!ZP2lAZG; z=SkL2&F#&V{IX>1^%pCs-^uR$4)z}uf9Ukw^Bl>=l5sq1&&Zi|CA%fJk?fJ2D0$gX zu0K~Yws*YrJ}&uX>3y|>{)N)J82ggnmAqN~e$=7=gVK9JlDP02$M>@I_MDkN*+=p~ z$#+WjNxob1a>*+sKQB2+aScg+RPyW&@ouYrqxFB8^gH>F^E*NM^dr8bJH+#K>E9zs zo$u_RkKPjLqxX{z`sl5s=VK+;mZaak9r|w~ely9fCHIkhO!6toxE|w%b7l|8gCw7p zjP?7)4@ypz{A>sP3uomPE|L7Yk6EN@pO>yqOo8TNslB)i^cyz@^xqB z{05SnNS-eFzpZ~=aZQmtQu34z@sh_=dj6KP^NbpjEy;e#INv$y_pkQ9S^e*j{6%Ch z_P4s?s7r1s`9{g@CCTG3wLc;m+uLh)&Ri{dz2v&*#F}~gZF+v;DD{t#-gL=%l0TM= zy`VR&=fo5DTiBuhHj2APa-8H~hkW4g)bjsK=QoT}f41~4m0TqGlw|A$ zy({#bc;bFbJM@3M;yz09{gNM)JdXCcx##JUUy{65@&?J9C4VCs$2(p28hZYpvNtTd zXGs1=68kec#PfUcul__HX}9FY=jHA3k{3$G`Ji9X^VdnPX#efxcSp(dB=Ns*2me2l z-u;pbC5b1FcN^KkE_prP!T!$wrvBaP-^u=8^nBA#=8=w*eDnEvyCL}n$v7YMt9t$h z$rbItxBR|M@^g~-Z*}nhJLx?xxmc2T;&^wL9qf|ViyiFm_iySyr2d`kuQn%-a68Ef zl6zi|^HU|iAsOd`eqGOZkzCRK?~>o9|mF?R=qIR z%-encrvB6F-^u<4@_U!$FC>2@`D@9>r}B8-EqR1w9QB)|kG)0zV*l;cZ)eFfB(e9H z+OhxdipT#O6zA5GJ(A=T_n)cfhhLOGSuFW?$@;}PKV35J|H-KTX!S2vzfVg(FG>F` zJNVmMalKV?KS|<`<2z4wrd^UhSt_~4rFpwYa<*jL|B9&pX!WmBzb{L!EWh;Mse`|F zNUtH;lqCK*zR$_dtjqEzU7yb7hW}rC=N%tcb@csfOfg-wUo| zjbg$|mR6QPWuujhO^Ya@gc3m-p^6fEQGgJKs?Y-oD72V_A|L_Nj35-#-#K@_v*l>d zBby}8^Zw!e*!u1L-8nOJ=FBPg-m|-4DR@5Um%qs?zpC=TrQGkqEwFFpCkE_&AGva{ z5;XsP|E@;QnHT7p4sgJQzN8*6MZR@4dw~`YUw-bz%6tZny+n@>0NcQqE>(WWWs0TX0hjCXFF`%Z{%u5W z8Z`Oi1M*9ddm!LXRY*x?6zL15;uUpyx(qj(@qb9e*wEezx;gc90jI9%L8A2^LAyn z1}B47ukEkU^QVG;1pf)X0s8goq<-&%?Y~w%{$JnzddP?L%|Xwq>f5OgeGB@~S3x{# z!A7tNYypn}PXJE@Bky$+d=EI2_|<}*cw}7!RqVv*!(g-cKofcS&v7eXUr<< z_qF)t=l9{CU%m?Yo57{4S$;9~UFQbXJPTY5o(^^r=Z|TZ>9?xoUOgVQyzvTj6TjWa2g}Q`|O!h0EYZIn>_z1cs}^MK>nBBt~Kfcd%#aXzrL-%Q)b_#ie=#A;4*OD@BNZ`{2R)@ z3~q(osDS(z@Wpp%`J%fNi^12ye}TT$ew5q#YnC^=hfsdyorV1x;Zs1$yoWmxIOkso+>}GFSt4fF<{<+(F^~#(4w1E6u$iEA|znbMwMDMGn|Bvd?c(5Go0QY!Q&(8qs z!7D(&KATZ)Tkw4FBG8vNJ3|6?eEH|l^CI{*XytwRk&h{JKG+2=2iyLn=i9-T!FRxr zz6F#|f;Hg3tA7f5z7MXhe@&EI1TF!s{(gOozXv&s!!^|Z2JmL^H()2|>x0Z;#n^1lT2 zDEs$$^uG!&2aC{~mDG1-@P~nY>0j~`8lG0X2J8k`f}1_7=f4H+4pKS;OFez>J)@`m z@`D5AJ3ade%AW>i4DrVNE9LytpxHG$A%CshbjlqB&INsYCHU7Ch>I`(v%f0y5?K74 z9!~;G|E9;C;OT$YQVOZ0qE&4y{lQi$}8WOJ*(GR%hU&}*QwO+ zOt2m7dS2yAw`~=L_MBmMzTu9#l%B`xt68!7{E$#z}lOOl7=${V`=vKe>1ZTaX z$47vAl>K`ecFqES1zredCG}lM?#h7tKWMM@@qa_m>SO+H)2;fy39hRDAN8SMwPyeJ zWiKnK?=HsQ>%iZDmiNAV7jgI!ypw#gys~z(yz1#z4F|pKYtrN6XxF>IzU0mBM&xA? zxCJ;6w0`bewSLfJa@e&z`@@S`!tZw%1p52$(PR3o{B!6jq1>wKdx3HrQ?3{^J$`+* zCH|RqK;H7;=x!}xac!d=mVz&WpM(ABN1K5I!BK(!W%kdvJiz|@;D6ixVB%$Qw|45n zzV$QnqltR{yK%5_$8Qhw=L-BXfA0K0^5@W3)x&zQ2|Nb${cnYDd`-`EgFjmCOX_hu z^1J^dU;Z`9tpvAvUC*b$R;ESNI-}m};NBKZoZoGrq|->$H(_?NA$0%d{@}Uj=KL@V@{|Ng2uk}x5zKcJ8 z9@G%uki9=p{xL8@-tx$|XZjx?-%Ni?Am8plZdK(?ZW-lFZ^-}0ky}-Hi_!KLz^wP0q$6e_Zk9m(q^gzM*H1=uxZ# zefi1A4S7?~Jo1*}(_lBa-`mQkz~jO5z@^{|;1=(y{NCWf*gp-t5WF0`9lRUt0#!@) z@8S5n1pJrhpV_O!ZnmVpyUeSv)z9?!_4DgvdRMhRzWrs`--dXH?2Ua#OO}E!fp3E! zf@`f%xedXA;Ev!>a11yRoDLoaR)Q&T33w{_6YwJN*WfMSo!}$jU%(f^*TE0KFTf3G zC(9R$Z!>%=_#F5exB~nP>`%TFfdj$8;2z-K;C|pFa4I+xwDvuN-&%(b3Zu5~!lz_gx$-R&KfDct-bI_N63%OO5uSQP_{2qQB7VyX9jz!+&Y6J3T zAlC-|6nql&{omzdWxfsW0geC%e5vQR2L1BiMQ+$iJ@ffzinBjgtOt(+uSQQ7_>-?x z?lJHK@N;nYs9!8l20j7)3)IrtzYpTi!{8I()8I?ss`~5O&sx%V1F82Q(66sAKa@BO z14n`uFJJx*^hTfPnM07D4;}$lgMRtFtQ=Saz5-e~-|qoms3vQ7Yqytaw^G_?E?5q3 zM7vnrterj$w3qo)hd(JW4K4z^LBD=q;?Gvt-_En|%bQ%W=dYFXLeH|sZ+=Y7R3)DQf;w>YlfPy2=M@Avxf_y5|zxx{Ne=*QFi8%+L1w6Dd}udlB! zg4(KahMgP*soded9cZ)&4J|=eq^471coG*Vba!-P$*Ye4iUqt`7 z66`CVD#){i;9~HUK>iI`OY`y`u(ZD(mxF%?Ujcppx>m8=#%mYO|C)fEkbDdB$ACWs zPXd1g{uK26y$}8=(CYP3Kz`SC)bHzP;DsSAwPMs=hg(FMl!oD|UW8 zm7fT%1iJ<(|5tFG_4U}-x4QC&qHk68S0G;v9tAdlKLCFS`u^Pne>Z6Lc`G1qak!8; zT-rxme0!6TPl5}l5;CAM}=i#l&gPK)mK6 zcPRLM@MzGF*9++B20s8l20sVqZ(O)P{$H1m@N0i?A~-MLZ#{hRCR(2tHdA~JEZ$s? z_XYiUoksaH!Lz{^z_-AV{#Dg?K6*a%^!eq@&UET?5I6@soqAmi`sGI>H+2=|-$!np zP4naSVL<-~yCD@nzBgj1gJ_UXV`u><7OYmn5 z^|ZKJy)AG2@>cF?%3EIfe!dr|-`p)U4gSEYrsXI@BbC> zw}DpQWdZqO;x-;U1iTXT+r_uHJ92xiqI_Z-ZPy3D&TaL$^qY!*19-xYh`0f&P>2M40J1oYcu7IG(pr-5gJA^CZnuL5fV z@*%ye>YvG3d@VjN2ja6e{C40D;9&4maDzbqnZx-*!1-VWXzgNp{P?sWcRY9!X#L8U zZ^MuFowVO|f|Cd9@pSMAup1n+OX2>15&BBea{!nCE5T~e?5*T@?9S-*?7hda@Bfq7 z`vNroLh^IaKOZ~+>@>Tcfeo-5iiam2l?LSJz|R9Mo__hS+YVC$?eRnSlfW~5b1D^z+1()riarryw`}0sA z<$d`l0(QFL-vHkMU&8Jy0sGG*7b@@DFGWu+m;!$h&|f=L>wmzWir)h(!JZQ3KLtC6 z>G2()Z@-puAA%bqR|5V4{4==maMf1=hV;GX=_^{r@@97o@_T{hpl>e)e<64&cv(RH z&m+|TK_e9p0M7#3!B4?xl**k9{uuln==Eo{+%;c`IE6T zU|&7%1gp?{RY3o`=-nSY1q|6U|IN;ML%L-~-?vLEruq+WSE8Ag~(zl=c`izHs}uB6l+Q zWAN9YwWI0r?Z1KE&Izjj6Y$3q_4qun9lQ;^6TBCE1Uz7pmb(MI4}2H&?Qe{|d0;7e z4gvqxNBL^X9R)4{Zv%aMRzKfPsJ>R8GW_@v=-1Eu^zE%hJS+7Fc`9L zaa`5<`ToyA|9mh3wt~KV5B~P&d=Xe0kl$*u=F1>(%PD$11oZWr+*8Oe2Umdq0@w5O zObF;Z1o=n7|CGKn&^HFVA^W!=_Ymm&@7Le=&*HQvc7}sy*DrrH=RW`k9-#3q2UFnh z!A@`mxDwoCs+JoF4h6@8hl7=13+VeZ1brdMlKc;^JuYS8x-uK7&zUpuG z{qmuBHDT{QFjT&r^OayVSO@y{j9*p#$D-#X@HFsR@J6r$^zDV@tX{tSa`b!#egO^$ zw3qRIyN2>@d-Uw$j{pTaMs`4gx3*}6&#mkTHHOQ^1{PFntBk)Y{SKy7{Z^1jkN5K`~zratx z&%v+2jmf8PfjfcU2KN9*f%}7g{rd9Pm+#AeUw(D#-l1E2G|2y`3w3ezY+4+c;$V2CTI3c|JeckW8n7&CxgcZ2I39Sow#xyaU!VWB{H@sS1Rnq&4)`t?)!=#H1)v{~Yq4_+Sc09Apf7KJJf2Xy%Rt|+kMVD7 z?5?VxzP*#t{|nI9=gZ%U+&y3oek=xkdGo)7^QU`p^X1<|@0Va-@@6*_pHRD*Uf=#- z@NXGdwm{pV4)o=}0bdGE1SbdNZ-Kubd>DKbd>ZTq52;l9ouF^u^xf;p-;De%;BN!v zPlG=bJO}(mK>khm_rOi7)W0pkZ-T{O2{;Cv03HBN180JVf`0;E27gcpd25Gk^YD`u|=3eoy`G0q+AJ1RnvP1^xQ1N4*Dv z7N4I5;$d;O_FCPz`1S`SwViea_W;iU528Kif!2=W0{)GoTrF4+wt~L>s#>+*26lii z8GodnUk3JoUxB_p({lmkOOV?;Ab;FZ*av?JUIH$w)AR3uzP&N<`+-M-#|7le;1329 zpq2CWpIWc>mxED*9*+PY0UraO0T(r@oUhL>-VUsLhQ9&q`GMB=E6}gs&sI}@40`qf z_X8(_W~ZpBaK4;|+y&qx$o(}SZ*n&y|9j-DoL`@Zk$V(;9DD)vvG3d*` z0{;g15%>kzFRk@n7u*2cy;=EE@DtG2UxWN{;K|^R!KIY@bD;cA@ZSax1CI*Gn?F-H zKhrDc``6W?^>`92U!=!7AFa3y`~)ms48KIN^jO8q!0V3F<1X++@Jp~S`z7H-0e*i89j|2Vk zr@)^Dwt>G0$S)%f4;`a<(+yf)ZA9K&0*3Nx$K$oU@6Uedn+>MGR`6^vWZ$>v>ojFy4@U0&AFAAj0r}^U z?}z+4;MSmDzp?1sA1nh80S^P~K)?Jf{Fo2cfobq)@GEe$6V?CcPbpmA3z7T6lOIUA zu9LLf*pn5X0n5;LHTW3#IQSRP_uu^aZ|VPc{dy#l@lz5%`sehT{a`wsQ~E@<(& zGY}7pyS3Nq#>KaP80~g1Xzf%Ru)heoOTf#)TR~s{20zj~xCU%LO^;KjlP70z43?aw z$Fsm8XX|kp=;X-mZ~q|d90DE=TK#RIOJJ z^2PYq`eWs<0Xxss<09g5DA)#efSuq5=cxQh@F(E);5*<);Ow8Md?R=!cma4Tco+Cj za0TesZwKmiAZYbDGf!rrHf~#f`uXPD`yO$d3mytuTz&a_y!^Cr)bc4L{{ZFw z2>uE5G$HVIXV4(iPy>TmKe^c7$zh(b`z<6ovKFbeVmstDSxNG(B{l5&oYn{tF3QU7- z;J44y^Lv0Lps%k8`PA1e|MS(fcQNvpgI9sqf;WJ7fWE)4!>UReGS>UTX4P5pXzk#~dw23L_^_$;~_@4&bK;IwZJ2^iPKdilc zKWeDgVy~XoE~~1)7(2!2u{f@-{u1=mfaY&eApWh$oeZ7|o&oy)Uj%!nUF|AgOua(&TUCFT;^#~MpZn{_%Wwa_>RUwoEZ%;3)BgeO@-g@s=*zE9yOvn{ zqQ3(i)kphmOu4~dv%J}@p}gf!jpv8uPZ@br4t9c;Pk#MIqSx0y_dlfH^jiNYAyNqmAQs(E5YL-LFp_^*Iyt?UnwU`Y%PV)yMoTL9g#m597|q;Adb_Am28; zNc;W1$XT3zjl8w9jT64TyD0w3=syU# zRh2h68{e(pTR-vZJNZhDZw1(Sl^*{c^yM3o`xRJvwaU*2efg^cdWU-Dj^y}Ku<;tz z>+5?SeXoLVf|vX{-;Y(*H->Wifz!YRU?X@k==*afe8|2pZ}r=W`t1UifC(^E|4{ke zDCgVT2Yw28AUG!=Z|yRccJSlq>yL(}m(({`ED&sNQmnCe4UNsop$i*YhAwESt*hFj zwknE`YAVt-(a@?T4N_9Exk=9~N;aiy8yoTt5^}C7Sy$l-@Ge!?91X2)sFlCX$;I-w zS`Oq~V^u|SMKm;7lc;X0s81$ps-&zPiR^-OTFWIWnwlz>XgPa-WTgl@1Z`B5YFvxbJMXG*44@WWZaBNT|Z`PLormto{d)F7B!e&ykM!my?&TYg=6>z7|F zoU5Wc=U(OY`M8N5X8t-`xv#Vwyz*nKw7lU5>zSmYZ@=9uUs9*# z4R;=!U*6i!*baH)+Q{XWdzD`~2vj}3ynlS1NIR}Sj``(%fBpL3C1p2t<>kM7)nLEo z%2l)fh?H^dXXR6rPpxA4KYQg{Dc?%@Azu88MLzfSsvP9nKmSIJ-}yJH|Nf<@#m{iL zSH9$CEnjl8mTy}p*IKs!S$X%7)FXf%3bprT$N8*EpCO-&S#; zeCl!y{CeI1;Flj7D1Y?zTK@SOv#jWs-<$G&J!fyJBkHk76fSRiCI#$2-lXMcte>Ai zR?f7R16xqL+xOAq9R%EM zK+F4qN=L4F3fXTvSIa-Ze2jRnTpKDUKFXPY$L_yVEIRfHEniB(ok6qDVf0OTf5`+}cjVCG&w$9* z6ZyPkudNqyPV|p9h;07Pp+(PzkuhO?B#wc%kgdS7V-7OF~@hn?<;cdRRrGyKS}9mXZX@%l$Z)X3cd|~9{e=Z18;iV zycXB@SQWH&ZY_Knyp5O5@a6DUuOGsv;O%n9ZH0*A0KWzPxJP=9Z-=*@&@Q}duMYZ) z`QvUyIQdTGH$cy=@LljWP23CL?eUMn_rRO~e}#{ZQ^nQ;UxhD*H~DwrOW?P`pU>dS z;P--GPbMbke;a%;{1)&X@XVIc4)C4ugOUFZd=I>}%NY3Rcoi%|egb?Md@KA+_%3*h z|9sOAZ+6r0#qL5?UY99ECz>AkU%;Oye7|UmsQvRnF=JadE{2aj%ja)`FaIQ;{{wvc zyZQVR!n=5;ey9egVfT6XPIz1Pz6IX}e>C!+z?Zcu@h$jGWRVc-hu>Y=)xCCwZ$D9w zPf>`53-9V%{L!G8vHFffzT_koOdx-7EH8P!+fFfK?O20+8}hd7I|jbf&ID?}6WgIJ^yCe5wjQ1^+30bh`3;pl1{5 z$S$5G@JaZ=@a^!;Yw3x-;ET`H`4E`PA8}=UVjt5&1Gt{z>GE&r!kC zkbe=r=x0h4!@mXJ{Zl1&g8vM@13fRouPXyrJpQ&;CG{5y9)2(T>52x z+(sZ@e6A|E6g~UHcf#)gKU4U1qm4Pzdvxxg9QkffJ`Eqa8%pxpOd&b}z8HQ8{Ey+w z;ID*tm%XmO5%F0H-vQqVza9J?!n^uDzD=og z;hmom{rv!?qwA4xrNQ|KSM)ph=qeR_6#0kH)BZQDZ!!Ec@U0&IB6_;e^BM9z$anue zU(Z+YogP0x>fze4>uOcdU&crG`iAhXUggLSR5}`reD`%q*!Z(Ie9`sF-;DfZ^mKNs zKQ_M2M7|UGM&sXHf ze-ZjSey;{umPIGQm)xN|5S{U;LmF zOv6zRdXs8^UHkrZuqT`Z-$Q^RiYFA zIMW0F0*QMXeESnBXnA-we0i7hL(ubE_%`@5_y>e{{iV%Ymp*}fH}XG3{sq(j7bWa= zz#AqHUq#&BjrGfT>y7hYB475D>Y0uFmK$n3JDyhlI_wUHFMmdfcK8wS5ew(P!H-qeq8)>_=EmxlOjRwP)zoESOvnPD&P30|ad&3vMt^7Z*J4JXGhceb1HZRYE@BDaB zT)^hpYV;JXP(4f0b3A<4yUH(yzW~0BhMEX}E&5wO$k+cH`nr@jXp|CRE#6}17rsGka+f&Sx!ckR;3dZ`HhOyt{J%HplKw z@SXjYVCz(LH+=az%CAG5AA?W18+7tA{%`QD>*w=tz_)Fvyp1O-;d?ex-qzLYZK83G zHqGb10bjIPKEE@3@fOPS5y5B_e206GC@)(NPl7M`hVnf!PrKJF)3bx}CvK{Ih3Rn* z1m$&((oq_|lnz?2r=!z_??;c3Xs}XtkaNgx}$-c_}0sWi9N8^-dSdX@c?}m5x z(cEhf(?iGI7k&(UiUFJHDmnnZbc*VKj(&QO@GhT=8ECteB{Y5 zM!sXF%AXsTilU#umz61hGW=EW-SBSybFVw#i}((`+2qO7@WoxK=azL;{$0~EUwNk6 zXjAE!F3$Gdl#`Gz7T)Dabp4=ML9wcdzKwi}0b?rhoEpo^eJXD~e;D$eb!vA4@i`LS zzUyfT^*Ry0?HHAB#%>#Y2YXYup0duEXLEtlc->OygNhM?XleGu>+!;bZ;p4T_K3R9!R%`Bo-acc0O{ zCct<9LfM1*X9)bR1{4b8RL{WXr%kva(opv00+T6o!d2KM<2m=T(7*f`v$TAj>mx;l;`p< z8VKJ5KV9972EmuIaQIk@MML2`?^I$Q@?+tP?^1py@t*>pat|itbrgCIhVSlFVmsQU z8a}#T`AYb->EVLxW8!?G@$LbKyyju|Lin!7m8aWB*THu`qx^AksVKS|zWiC`?;y^P z!59Bs`7Y#NfbW5~dc9$KUQqdG(9=&Yab4cFdHteDc-Jnauc-X~)OUCIRu*X6!jCce zEtEJ>uJhe%3Vi!(s%IYZbA)$xyBR<2dZZG*6TUds5=C|BiQZ5>){jnwFMnJ4ZP0%S zeCrD3cVzs$Hr6lqhrK+%9r=!rRDNsP>+V>7{iufqw|U_S=Jtlvz@_bY=`U`w3c5VOAE2ifOmA@Q+ z-ZlO%<=f%EGX3x@Bce^V()btOukvzXR~(mR#^7(W-8{yUVv4E_xG@}LE)x-AFXyb2aoZFvO{!HYzgYSG) zdAqLpj>*5Sd^_@^;Y*k2^Aq8_;jO|Oz)uhGHvRSfIma{LVjKxkiSLvLjB^tSWoYL zs*eQpKOfM)B9@ouwp?)R!1YD{?Fz@|8v%ZZ@P+F2UEvG)KP{l=umE2d;ExON=LGo6 zg)iji{Q>!>1N=V&{D%R4gY65)b6epH`SYEC{MZ10U_j520r}Gd{P_XCJ)r-#fc$*{ z{yE_b<-_s-|FQ6e;(d@}C6cH{PLeJc|STFyRZ?{a!%6D!``${HX!{`~ZJ_fWJrhLVi9Okbf~C z|4~4GU0I|R(!Z_nh4OPqK>oV{`KbZ^kN{sTe4+e5TKGbKo)yq@k?``b*Xw#A3+d?; zzEFMt6yX06;6DoR8|+wE|2D!Gs_$+Aey@O@NdbOtfUgShEdl=I0RO81e_eooIKVFx zzEHco9pE>X%h*EgHAMJAdcGTwpA+CK1N^Z8{w(1O*=>*Iw~Utad?e!a>wunH1H8M< zRj9r%2KcuFynAe2NYB%b3GmAU{0G7pio^Ol7mnwS0e-mfh4kzre4+7SW__^tr|N`U_&z;8UbaGZ;UFBH#F!pjid>oql?XMTV`GQgh{;C~t5 ze-q&E4)Bi!_~!!r@&Ny7fFH0+;dpKn;CBu1BLn=@06$OoLhW@_K)yA=|1!Ye5a1sX zzED2A5|IBWz^}J!;ka!Z;CB^XhT>kY3Bqq4_5K{_)PSCY1N@Nz{^$UIrtpR0e`P?v zL-<1DQnY7Fx@ph4+68+K9qM58$UQ5YnrnwPMwJzHb%}-bjSY!(b462gBy_sDrMh}( zWt2!9IAK;|+SJ)|5{alP*_2#Zn{G}vC7SCKm355`@--|4s6?WwF|n|&aY030qN=&E zDV?ZjSscmNxTNZm&B>~vqeqM=5zPgJ67D-@^t)mb@|7=5OCtS_nW~oh`Xy2%=P2R6 znkG*)QCVGGn^;g$c~r8YN_?+hkf=*GENrfE@0yz`-1puj-TTVAWJOa{*}No`tV*UU zr8aglheODH4^89I4Ydsm7gpxTIeKAbD$69Alj-K_mWE2HnY|sBeLFn+c0~5=$n4wE z(UPIVM(j0aRF)c(eLE~yYmVAsIeLfXC?1xhd039hVWV?&=IS4t!|#=SKRn0o@Ep6t zbLY5of*fu7cpf*4mD*$nI2WTCa?yM+ihX8IZ@dlUrD4*>kf~qZE$v7UQ{bkEIij^PJSihh)nULe7RDmm>BT}2JtI8a@o{>nmq*4-=44H85O3ac?Dd~jG$wXCc zWph-~+}xCKRT?^M)R>ad(E_bTO+`ahU6MLXYHCUx+$09)HZ)b#rYjc6nX)C5YwMDU zacKtxql@+OUOU${TxRwyF8x~4uY;grOEHf7znXGJ<;^P||>%?g6ockIk z86sS-NxRM*j~BJBPs1Un0ux-wCdR!h4qjd(#H}wKF6KNJCr_0+H#RxPTvuBlLzSki^HYxU4ifSuQw!V)O^rlD@@NTy3}RJ@R8wtz zZFB7+sdhzGmBdF{DVi`jZmig8&4uc^#tO-089x%qrly9*L}NqU5^Z-!Rw*lS9v2n*L5Q?6t_i1)56>`RkeA;q?3|=k;|Mq znFlNvT#M^KYEFn9%{ejTj2iFk+I!K`xZucm7>|xhE;+ifsVXgLK6=>L*g%e$6sb|eC3&pt`YT1CK_7mm5q}1Ei!@C zr)0)-oxe)vOsRuwpt!D?$;|~na}W<@O%+E=&r8=XY>+H=iQu|hRl?CaTQ632VQrl# zPq&CCxx-zJ2rJQCmrh6|qdD;qIYCFrI82hK73p+BhNpUl*5qROO1aE{ovf>?O{HsP zL~&W<`a~=$p2}gPbme%Qp5}(Aap}4E>JHui?3B_d6N~iIqlczs0W(w*BjFltfmFun z8Csiesu(&_(nVS=_QZ^_K!|%mW}4TjUu2tVD{EXJDqIu9jxaJ#Nj6VtY-p}s*wWaN z9xvlhvPmtEl0KS{PC`$wmSLyHX2eA@@yIxX)7J zTAHgQ9@M(`G?`n}&HpaixijpD;loDDEF1TC8AKYS_sV1=3p1HHbP>SNCo_=7Jt5A@ zq!XvCOM`f*jgMTnW=vd|kkN8cV{KK6WFk#1wcPyahT6(hPRAaxm$ZCd9%b?;r`>ft zboIzKpJYJA(XPpo>9pjcWJJ1Ufh-tnQ_?>1z$wR$b}6otnH^;1T&n5l=qlo7(8iP- z6J=JBIY+vDv->i}1&R8kOsO&#Wk;kDd&#&JPYP~+WbPHhWkiK6Wpll^;ZogdXlytp z8Bcs}&=A*Ei^W_#$}KD_+x+5ET09@gd;t@Y04m#xiH zoM7$eg6w*n21$lOSxKgovRJE&^gz2{bJ7lD!FVu`<%(;H%rXlVw(4SGJ94x*>8?OC za%qWjJeX+OWrhqlR_Gw1Sst%oayo(Ju}}5tu(?CJYKgxnRp0u(TN+T8OwvQ~5%fW^2a=}f&Hay1lx7spf zYStAxL&q+3Du;7(qPy02m&iKY$5;NTCCxQ50@bG%x~q)Qa#@&?Fv^^lNYNQ$F_~go z;_qQCTQYU#co~1<4nK3jk@ShATam;a*VgQE!7TkX(byCZbD5>Q(vh^4F6}FA87zYF zI2ZR#8yQt)Je|kNUB{BqB%U5~LOrTvuVHbgb3!uUxtT}PuTtw5`=CS4*pi&naw#R( z19GX6a2H$A6uCH?&9&JaHwrmLVlO@!&kj1Ey0>v?$6}o$S4Ki1-2^p6CdH+$?edb{gW#CD&Co;?**3qNA}o=O8P!8 zz{<%>n@csyjkyCD8HhwY&B}}`GlX`ZOs90MBo4%_6z7T?w(?gydC5{z5?PX4kC5TI zx-rq*A{Vr-VXU9jHY}2LOZM0WDRVNn)kh8EYGf3v&+Ju;jOwzCkFQE%=d64Vukm&# zB*Jdy7%EpaqnYJoy^yS~kX2!J?G`tdR5Fs(a+kC5as0;lF2_0x#8Ixaj;vvn;mA$p z@|DhVSu$R4mrai^S|%o|qxjOON^b4RU@&&Xuy|y)b!A{}2=!8xxC3N}%#~yg!!jVlWUrMo6pOvgu}fF8;oeIgG*-HV$zwgg zte<6MSQuuGb@7)yjOVA!q4wL%q0VaYq4Y0n8O=*OitpITZ8}--Ch99vDL38eUA#hs zOb82PJzg1)6mEShM_k3|g4oo?i)LL_xNCAfH2r$SFzb>=-^Pw65|d|*n?5NqX~smk zKdm>b?R{0c(JmVj6Azs+Zu-;-A~9$B1e2aJZRYrK(-Jc$Po6z#PGZiu@zW+HkCR3_u8U;UcV*gVzUy>pX5vP%6+=w+9? z?NQ;%<$EGCPD5pVDxXYDoikm=F?$Rk@vW1=V-B|=r%atTJHDMci)$9SGwE)p>BU0X zk~wa;wFB`XF-z~FiStBqg1cFNaI)g4S;^{jB=>Cf9)oI~+aMFS-0!cNl62vo5htA7 zD46XsUsmhlu}uH@4omG9$@GaK)s}6@v<$stMb-3Vz1$T}x+vxv6g#fbgmunJR42=w zV|m-qDAa_>T+O-Mn6y|JccB^IT<&$}qHM`{y{5_rCKfJmlOq!fF+NV#C}fIgSkjyv z7hh1(-T@8ME7C`aGZ>tjmVDvXg>%v6vQ%Vtd@oj&remMg&bWrE*)H`mUWja-7cLM7 zS2Q(9g%inm4J(b5buC$+YK|8?ZmiI-&1jV9Hp-P=CW_kDSsQZ8f1+Gqn7DL8_h><3P-oRZUbK-?q!ofNU?6`{M4VmXt{3cL%Av+?W*y;;3h+j(jp5H*3P(R@Z(lQ>L4kCpE}(1g)W_OQNFk2Q9U-hK`>JWZV_Kl9Z_eNlATX z$t|Y|+;Yl{E-jLj?piJW1%`BUlian+uTe(7dsZU-+%>lwf)ct4;F*|EY_;sLvsi#bJNKtmnj-2 z%1lj9jYlsT_fyT>eUimODk(!`ZDqb2*=Cn|y75=NpI1@WlBo`Ar^hp>2;}x&$tigN zNh#N7w8m8}-k4_1PPfVoVw3b9Xu_?%n;To|+&WEeN>|k7yIHm*Q$iAFPEBn(#|h_B zJm|Tca`z(b&a%vp5_(^g>s`|0X2_W8{Fb9kFPL5-Hy7nuOr~*Mn&{2*W;a>sbBhA` zpPl0-%DS{FIZej;hV0c-!s(G~@=UYF<6y>$O96LV!3Ci}16y_iw9)!b2H5tv!0zinj2rT1@_4{Jj%y>M zLEHf|F1x&!!7X#_GF^sU5{|(@hJB|vlQgcSW>!|VG&RYSm&^ief?V!5C*439=i<0@ z9DEs+>*J@s3c84M`fWh4NtoJA$eG-P8s~2EXM2(?6(-Cc8P&@|*^iZtq>>YTjik=T z^!Q>eq0^_#wY@S;+DnWl%G}*Qbv85A%EZ}V&8WdXOzu2StX)*=eq_i3u8Y2LY5H(F zEl<(?oN&n(=S6cxot2BbI*mNe`Q@UevqbEsds3c1!ye#%_eh?O$GO?dZ&}Sq;>OP! zscuG}T|C9=T!PMNYO#t{SGkPL&&NbUew|1LLAPTj+bC|-`JU`L5JMB){k*C=_xnrM z9&*1RQ5mO3zAna%?35;}jpSkrLfnH%Ki6DtZJn6l7QSLQ(-E3=U=b?L?iua^Uxq&S zOu;u6=cMyAcUhWK3CXNElXWI><4(3m)X8+8xzvfxNHpVBxw#R~%kyM&hYn7Y-2*W0 zMYwS|CA)YsK5KPzd#nvGHd#0yGXtlYi094NfLq7UmPhcaBBug6`Q(&#?ddY3Oz&ul zX!Z(9^+xF>X}Lq?C*^^QWTw$gPZR3o{*%nNn&sMst%>4T$UGenD47b9xWY3!xv|K- ztzFR4?5|jKvqrpSLY^dn3k~m541+RKW%I80-ki%#V7VLYp1QjoKo-I>U5H!WPDspc(8amfaFI{A2VXgJ zx?5PpGjZ%_TBh@+oMnfb&DXrvL|{z>)-S5wSZ<9BldUun14sTug`n6lTpV^D#D{o^xQ)bMKW{mmW z^~a2O@GlRq_uXGkJf$IV`My1S%IW|5OTOMdevRUdtB-qa=N;cGzc=7scK!+P_&JXG z+VjlsFw4(D#4r0jW%+u;_*H(TetKWNelC9THPVrMjbHq#;k+3y^$rH4@sU-IJG$i3E6$ow*~ z{r-|y3Ec(T+G=~*?Z>} zGI4*)>`~Tq(47yNn!9AS2hmcBtvs&3Wp_MV7+kG*ypF5cO=)pglt(rI59R=9F$F z%AC{fhPp*fxBcP1_9toicpFkYqDTtZ?!WF^^YRj_@OJ#n2WDIrOT*|Q#&%BI9%lBuX7{WP1}2SrhZ1iD0wu6vEi$A@toQK|bH3x0$pp3`*q zf9@{MsX3p6vvEDU-B!GIb(d8{W)KjHnq@w=BA+4_>qFCxLr1$0v7*Ku$DbIl`P$~4i zfj^NON`>V2lp7v}8J)pl){3+yTi!?+b-rbKXwnoaqAIpueLUy+b#HSJ%N6D zZXnLL2mI^^#MAwrdZF=r`#}C&78pNI4EW=I|GQ8;cMbS?h4i~Zakw!MhjbvXHVnvr zKhUp_548I=k|%}y*)otnV*>h5kT@68^M%~-FBG5S0`d82px?bCd?Ec01@xa4@IMjA zhoS)gWgxGf3$*)R#crW|b3fNzC=Ry<t_){J5=jK4Y9tp(fgh2bA709dS1O4>Z zfjA5d=y^B5|1RLqpuo7~erB>z{#+i2LrcKVvnB9_^!!rn7HY5BfZb(*dYuwz$9Dtu z8Y})3`^g~3j|Af16R6jgfpMcdF#gOE8-ohi{iAS&;xjmq=Z6RCb#j1zO#Ckt=kbAd zyjScNT1Tyj>)ZQxXZy+ivm)6c=l|~4hp~L`-^X%wE%duD@-x}O_x_#Kaq)QA`*%;T LmG&z1drtokWAcIB?Dv&53F+?+A61u|#d4z{3hL{JS5Mnanp{RkG zA@sJRS(kO)$A6dIbzOE>cUc$Z;VTaz0Te^x14Y+}t4wl*gZgJvhM5i{g;d-N?Hfou+X-BPCqAW}-cM zuJ^F)Iq3*a&q$4W1ZMrL*Xs%O4*h|ruXDt$LwUKNm&YJW^)lA$@Qn2i_F$wP79DP+ zHa*Mu$=ch-0gVp*fv4%5X+|n=#w_^$`XA>2pOHb6Sj@QXg2>_Y+h_acbbkkmgD~eDbe3np#w@ed^5*y;)9lWfBuDX8rNdpt}(8? zyxpd#c0XbKu?bBsop7qCr%!SE^}Ii~@pj`lym6EcSisvY<8WgVZs+*d^LDpH^{0Wu zbEEn*iqlylSjSKbE&ih{<)&D;l@TmD(&EbwH_>HXpDd&v07x>hl3@&dadb2_w zQtE$hy@NrF{yP|byRbM4{sHU%x%Tco&L8{bI$>kJ{>P2;_YHi{f$ur+JqH*ENcY5; z{zc~Wl5=6^S{CfY{-^#;V7gh?k98Lgm<+c>;F3clqEy*rzt;LSBU{IMvwgX{Y(QSetd{U9 zM-==J$M24U8~qPP!QbKdeNpf&y#K;_2OFTl|Mxk*Jqm8%508TXiQ}h7!HvA&bqI8k zn`E>>d7BBIM*x1=P4M##AkyI`_{Ao;!vyE95i3nM!MW*Ya6?`!$Z=PM!3}vKxQjvb zKZd*zJi`Q+IDK-5VodOvCV09DzQ6>BD-pgHo8ZQhpu(jl_=GUFAXJ;+Rug=U3C>+o zR$6a@bJvZ*H<{q!P!38OP4EO0{l`r3VJ7$%6Fkub-)e#9VR+!Oz<@ZybmaI0D75rrzN5_viu#Cr=_9Qv;0EJ zlPGJ|EI*s_B&ynCmM^3{iKsS{{qN(Mw{0)>R6QO0W{I!%P)1Wz6{wm6oXlizr zzm)PMdYZuU7g3%>PV4=a#(zHL9hC28`2@<3rhEs>$58%K$~Uq6nY)m`jPl!9{tL>d zQGN@{AEW%`ly7ADqm(D_L#t=`cPLMys#POTaw@6Txpz7Q$=~FO33V`mtrSQ3fCBLi zSZ(Nl6v&}==SpMxB;_N?+n2mLW>G6DCi043EDCj#JOlp_5P`qngx}m3D=95f^Rb&G zONVr*uZ~qtJ+Ta!{!Y&qizH=l=qS~%&-pp(33XRW-ki5kj3$+jJc&eai9-k`fn&j? z__JuQwHk<)FIy|=8W--bH)m5Ns(G$J=NcIOCeKB4QNIRY&@O;Q`J8zFOFr7{g%%Lc?Bs*|*z0LbY{>UEM= zvxqz9*~A@ZyeBMDSx6dsTJknqB&A4@Vv{SgI>fvd$=ga4DwTX2gZo3CYb5VYLfwnO zwdj$*sV+%Uiv)2;zOCmk;wYv@c9K@Obx|wv$s4p#JJMs)(00k&1mZ2?<|gskCP|sg zkb#%k$!hd`YT}P`USM8mC#e(XT<@89XYt%QlDa%CV^#94i=4MP7ddYSd6yu_-Yh{@ zzE!T5l$AD@GA+)n+-z@~##|uL7mJ=a1G%Amf0H{}4dYs+Qz@{4b)H3;O_}?8Zlv)I&No>}K8I~YfZ(8!!`SvxFb}H> zY`Z{Klbzy@0$b0MavP~V%nZhJD`SN*#Qq6ChmZayS&8>x73kyePsVIG+wz$$b1Nqd zE@@N035DFsYrz9pL}>Om`D%Wgtgf(W|3W|d>AM0mIJ>>4<5vy+65Oq)PC4f}=YqfB zzgyV@fy)w<>)ntlWqzDw=JaXc2J%AwPJ_=K05Eyrd~QPi{|cWcaz4L;H54-SGAQ24BPaZV>+d_wwsKP4e3o9Huw>8>d>N^Y`Nj z{>n<9w)7OKOWhu*^W&iP)SGSIW0tiS_gpKflc3vdlJ_&{qk}^Ll>)8|%bFibYG$SP z{)D8u_n@9o-pp!fU$!!h9qzwdoo35yQXhzeA|2l|qp{L^TJ%hilnE`en%KlNn>v(f zI`6(AOpAIy=#wl5v)WdTCJb?hoPat>b$cZ>S@Q0MHcf&vbFSsp1 zGH&$%39=fO#s;i7`@DNF=2n{w56_uZ6}S31Lpikeum3Q98H|s!ujfD%9aRT!H~1UI z7hlp#egRWV`k1#X?$E*BC_0k(A}i3AU_D_xVf<%xF!^$1Hw?I>H>{C*)8P}+u-qi| z{Gf7@R$jBD#u5?}uy(K>Hpbfx);DW$td1@ZWS*V#W#ug_Jmn;j(nQJoVXvgT6Z{o0WVL8Ap54kxAUZ>HGo(Pp;ahcUU@`YRZ3=IXHG|oUp zH*ZO|t3>W~xC^P5VUUvY>Kr#Xp?n=I|B9_nn_DT%kd(V7(^Ny3!$$ULlR?>-KXM)P z1p=9d`CpSQ1tt!gNp8e>;*Qw~-ea+q-ZP1-$BR2UrLvSqCCeA&_z1zNXn^F<+hk{p z<%DJJD~2nE`3KzA^KoUPX}x%^GA)3_)t6%#46BXD-`Kh_w1BW0K#Hw|H^X*^)>mBu z+npTxG8Ag$h_;?LbUAaWP?Ukxz|C-T*gDVm@AJ&==f7LER64zD5|USs%@=p%Cfr;W zx1q?=;S6=__1$W`mzD9oQV(ViM=*gR(s7(XaOeI27Xx>zvp$5M-IHm0r zxKJBj!GP;y69`4{L$}VlicnFJ7Gzns9B`$LaVtm9RTJ+A|IIr0e%@Z!WeI|`b9`mx zG73x=Dsh+XT(Ce8D)SWAWwziYUxY&5zK~OS*#krHelVG;1uB9rMPKEMTH)?0UrXyh zot%L+l|6D%i32M$rvQoPI`Ss1!C&;Ej{k_HjLZd8^!=H1N?_s+HxiKi3+stBg(@m- zRArqMfCDWlANCBbYy`2>w>yMg6wH&9W0LaE;66sM$x{p}wVX;SI*R>PT?b%ya2PZJ zgFP>)>(Xp5l8+vI3atU{PYe`%38opt^ZcSG$>8Ts$XZBR|1ymSE`OucX01c}bVU{E z>y54ah7+tM&-pY0STC)TY(86$dL@ck=y~p^syQDna=>=Zo#PFKJU8^~14$j5h4$ot zXRHtmfv&$vX%&4Rp?#^Xi8>cHij01n^&|+<1@#gbTXc&HMWplP2GnIN~=`X!b+OEW1VVZ9JEr3_v?`7N@b)>Y>&03C>E@kA|+Z=-CB0>g#K|vY$3Bbzx zZPsj#DEh6y(JsaxmulUI(#(*oXuD{CwwppP5a?jbXJ9gBOIBVMeT@K0{^K4A_&<-t zr%(>zKf>`P;@^)6Xc_xYpvq%jo}rYd_eJtiDzp9_g)meXEuaKE183Bf7;LA13Fuez zsZ*hp7}cr(Pam@AYE`WFAgk4(>*!D21!_(L^1%u;u3Af|h-5*{`RZ0sMX#EZ~(sN2e6EfomhvvWR43odf@@&q}+=n@5;=GHZC%b9uP9wVNI4EFV&|=+#!FNB!U<7YplIXh~Jn{Bf zMBiMR+$#Jbc?@{c98z0c8frtLU1@gq5Xkw5gynfZXrayI_3P3c4~EvA7Jd5(Eih3* zsSMBPr39AGd5Exkf$au8?1Zt&e7UYb`vXe#btb7J(q42BGIY!z(J6|?+#vjzkc!R<6kHT4ZVgHxja0ah&!v&!^^(3iNlv3CsjXTSPxz z)(}owCjt~B`st+_Y5ljoXhCdXGw1#G0&!zIR4?|Y@KHZPv?~aQGFE9;C;pb{D(f$h zC|`6PJJ}K|`u+_Hr#ihyvFk~Ufz}#olLK+^n-6o)G>QJ} z0OWE5Rh`*nS}=THfMGpA65Q}hwBS;cf}|z*nBdZh{tIZ3s`Yh(XYCOie#CpCj(nRy zV~$DQGo!?fue0XkuEs7(^1d1?dG{gIWPO%Ul+>TGM1rYJ!HDj%X?bXp_bZU|Hm%#` z=rYYuF-<>b^~Rq<^t6S93wvpuMO51MARD5dY+OYTsx^?Io{DmHeie(+%1JeFZ(f2oW)X7#( z*U^0CkhAN9T{NhC%RZO#+Nt+lLth*HmU8CQJEPBt&v%OX``u;xrU!~iWTtemC?gY@ zw?yCFuptl`2@QxFW*}BBDf2PHdxjSV61m9iH)g2eXN0V@gCP*1sU$+fY!+=N^dyaQ zR~+VbC;fTBfj`l)@L&)^Fwu`^ zWWNT~0TOlp#6vngyupYJMK|5*$oJ+tpf3;WT@p7Q$0*$D*tYA#PZUT5|RRhv@4?iLB&O7d=i=7#kL`_NF`BN^XV(Kj%Ct>yWr% z8f!;#Ac~NICV+30jMYohS&8@TD6t_#E5`Dfr1YAk;yPWii2iOCxjd{rj1)@y$5=M# zoAnW-qVHx*^+{_go?!@|p~=PcoO(yf8ha0wH*6(N1(sW{mq))LXB`(e{)_-H%&~n$ z4bCat;RW`StwTiL^)%>HN4y^nfg6nI5bV}5Y0Nv41y;SVTT-rrHi?n4t&58tXlA+% z=Jf|bI$5FzQp!RtYFeErcE^sb!D?`4kFBLd8C#BI)et11p6)H|-xowQ0_ zhorJjS>4<*lj+NQpbfet?LlfOv*Y_3*mc9QVvMUen~Ba{Ou$8 zE2PP)d&8~ftU_CI*85_^S`5=2m;eF$r?_!BGLR<-*j*5?F3~rQ3D|T9*lS|L3@TM- zLBI+jV8=bHNWk0yxo~>+h<4FOM{AOrG=fonRopNN=rSBt(RU|GWMwWI?_k*y@+5gHB0VOn&o|M$YJWflXV+1ea_H2d(Vr_x z&r*$pT7Y8EfgC$lZRSa+$y@P2+s@!B$dPJYgREjbhCXP82$AZZ%Ec&x_-QKvkrYj` zApW@zni=9vCKTqAcvgg5ajFo>u$&S!8_6)2|Dfn!jA;uq>|)@^${Lu1HDJ^y2bz<90Y8TE6GhX1> zvjB7*C0EA(h3MY{F&O%VlDdV^lomIp%dO0YeVlCvrQwWwP|TwLcJPbMluLQLtJ^iY zU0cPhZcZhw@HXppNXR1MF$0gfA2<$A%nx*ah!StkX-F~@(NEDRcz+E_gI69kxch?f z1ikP!5Q9$w06};a&tR-enQ9dBS9cUK)edLuX9hx08Pwuaa zf*nv_qVFvRc}I#(6{tdXs)Z6I^$W<|D(Ius&+#Cs6L;T?B#?SBYXv^=)1XNHOoF7| zV{-@MvfNosqVF~`o!qtf&>e6M??Z%OB~{Jpt4+Wt%IH~Xa|aUP5T?Eg+H9W;I&LgZ zUnf&Lx@*z{geMt7E@;AkIatH}mxDDI8jXA`sfm|^wK!@_q}hdb~rqf4mW4T(}^fuQpn?y~jNyX@=TS@va6d`w#q_Zv0 zb~P13j{(#J5FVlQl4yOB0>a}*`eQnxFZ-#EVto#YtkTmyddiLyM1MBU^`yYU$#8q* zHjpHuV}D0g19=(Jn8O%ACL*6hiV(YnLXxvy#UL$g4?EwF*9V~$Z3P-wwaR-Z*7STcQ!Zox>vHq1XlnzO$fxfARo+&^& zZ#Wj*<5ZG$Ox(DYY2uMjQXV!?N&OK$d0`s@*fr3WL9sr}$jn4{ut&HAE6uImGrTBk zvgp4G?wDj*i1m^S$}yRp&XY|{M#<@bjN)|x2&EL5Wk1<6#FGG^496O>h%TqgmVHIa zetArbjE2#YJL{mNEVYTgS$KWLotedE~|GBm$SaaUV$kQ_fT}p`j_dDxiaC>BvUJlom)tEWgQeZ{ER*96}=D9 zgXMh$+hRxd77{tQFoAiDokMAAPaXDlgUx%TG4whItydhyNXo<`giO<@jNHlU%_INp z61KiEr7r`feTCWMaw;pG&Yc)g{Z85uz?rwn>tPK9VRdDG;76qO^OX)~vu4NS;eCRA z&aQ4}pk6>|v^i+^cE>5rE=xNDZW0hS1futY800NDeL=mT=p57T3`nU`S8ys^iV@y! zi<610WMQsFx0+;S-7J_awH2hJ4^TJ-4oaPVxJgWp29n;Bp(IpaGg*DemA7vcgz8X` zxejBfDXFU)TA=3&BmO5V`y|Ug(iXC}Ic~Zd*G^`}cLw!krAbzE^{q!%3;esRHsrC& zenorctUhtWPv`;bMpmjZhXt^j1;f#+4CTWC+yx&Y|81b?m#2s;4!=RXqnLO(Jgr?vX;yoikBMXU2MSXI#pk12 zLCh#tJM%!4=B}e^(nQGt9_LM#+w$0aB6Sew{QE^eu^8M)1_~5?;n4j>N=g&?D@y9w zX{=gC5nL49b}gPvyPAh+OrPk@1ZRV99S+Ma#JiMMS)iCKGa2Mg)JHOvt-YjTO0p9Z z>h?=*m~#P!H+2DEnRs!)`Y=OHZ9-zm3kX4<;%y%pIu$G4A)y<%?R6i)_pnRe9x1bv z*j$CTJe5qZg`#b1_WuMf1;wH)4hJ*RIGi;sVn*nr@0t9@W?ZrM`O&Ukz zV^exaY#2+u%W4-lq~QV1DU>pEOyQiuNrf$^Y10Hcw^0#!%TDdh$9#Dw;?!3AoM|u@ z7Bf~ZwxVyaqF>=GR(lggm5sVnUjTt2r~Y@S1E(|uv11#8Laau%A*cX?YF&aX{8E%^ zPQoNlKMuS9Av6j#bq$DX7eeJ>zwgk7(Xo)_grxMDHtE?2-F%CX*^8(lWFFD>6H)-o z$gw|CPus2Yw#ZRm9g4SiyO|T zkbrVG*1!ySwAS~h!fmBspp1rqgl)9-0ALiSDaual^VDKQodA%r-|zcq8QC<;)dTdwSB)sQdVc66m_tlc#n2tRO;7D;oGjx z(Aoe6Sx3(wK^S|nKF@5lJr8a7{2G2px*U+H$-1N-H(MWWij`?@wE*k13S0E1y5q=z z(Nzx0bW;lrmr)CCBszkY1TMYEc)54<#ADE$S}`@L-t7QsF!E&G)0##LCN{MLrEuIn zKmrfOt)#w00H%csZRELV4X6slzv+lg3^Db$NMv{jSZ+40f<~#%z#2;WG2o)t1%UPl z)J~Do^&&b{|B~()^uThUo3I?W=Lb}>YA)rUCdZ)b7YW_?db1*Oi4gr?X>A<>4BfKA2*s_rEtGWTvV%YmCQw~a5Ipa_!HcVi&QsDH~^kcmX#Up2ZEpE7gHF;3< z6_cVXz#mBad$|rFEEOHdXg8w3^nQ(TzN4Stc|X-<_>x!w0+CaR^@zn%(i=YD2>^oK z{6Zv{N!r-YCmewec;@112%dvWyHMiIaZm})(}xj_oH@t^XLK4H`+pfvFoFUVbpZgK z`4ufs(j>RCYHVX4WH4;($0Nc8r?rFf#sSa8fSt4!0|a-UzIJx2*3eC0B_g*Q&L&ZX zxqT;FaI*3_Wnlggnq~($6JkaGar77O-S(brwjfX%hs+r4&fxqX78{xgKYQeE5EFgR z4@HJ=t#D*Pm@I-fM~~ngqu#0%!D|;AHnE0`2p-(62G$CNiF4f4wScp*FndIs=o^Q? zB-Fso078rq`$tVVd!a-0EkFr$KBlA7Go1zVt|hAKy--23O)6*vYwI4Up!oCLI=CNn)bT!=8Qy*zl(4yDxzNOe@?=WH#JKEro-bh;K}=F$`jb6Bs%x zCV&-F7zdMF0J13MRANB(-C%_aC5T88D@5N{kTAxM%h(w12RjN)>_}qm8SGevI?&=x ztPXZbCs-Rf!5jxVRRhk8yWkSSh#=XY@UWR0<^RA{2G|A!CnphH1lNx;Dgyq7B**D!1oS zHts0DE#)kmmT!qw%9{`d=tM|KRtNcQsjC=i1QD{nK*WWFgAP3C>k@q=cuAa%rWQJJ zD)ZZV#&LfoU>!}By)A`9q3}lF#hJJcW#V~kI5?M4ZUrN5wKtx$-h#!0)qNLi8z!q5 zIUM4d=0}!LIAisNxDVkS0?wX>HhcV!PUn?P@bj(4*$9mdny| zj#WBjn501QBy4C-=*CDn4Z9>+_A7_FKGxQu1wI~H6)L=Q@>#Y*AhC%*A3O8ZY;>kD zkkUejKK?nRWwIyU1emzNNg3|UXvK!y(V3xoFX+I}e3{Wf+yb-s@V(+>2-S-bCD4IIVv4LTqSYt&RXsYr`|8%_d$nO0m{k zfP-z=oh)g=Vw32J7Gd_tA_km;m=67L4&>hrfVlAjYS7y!;rNNxvYPY;n#RFxz-8MZ zokG|fUq^_4YsY}r(UMZ!X~T_pn##rno?&NY+0Ta7&1mRDd!NFm=&q1?T*{(q4HH>u z9acu_cp?^8#VFt5FA-R)#qunT2T&5F6Psv$$bTJoQ({ zJ}RjmV1toQ9MBoLkCnOrq#(m{ESEYf3$3b2*HSVDpNovKE+MH8)Yzpl&6!QPC-)*^ zMrVC`CFSW@C?Y>nCX5Z!i3y4mY?5&N zh0kzco?$H}{s5)qw@caAz#P5H%u~_@05ab_6}9B-yI?JnFdA9G&R0KQ#WwLYljJ&B ziUqI~C&_n*E%=b2O0|P+o7Fn96ue}gUIO!gO>V$?6&9n(eyZ&C0mR`UPk4`DrLjgn z#@kYuS~q0R7TmiJ-j|9eES_4oWqF#tNIB&mGxpbz<|3ui-cPT{|1X$LjHXCATcmuV zJxG$?W_4cgfJ~x?ZPrWpqxKn=FZBKUQY=n_vcC2_#NN-M=H~Y|C;B{4XZTQs*#es0 z8;Jk9QDBy0Cs~Ts3&V;pQtNFr2Xb7NrgOAjvs-C56d$5E0XH1+Zo?5rXs+vHHR-NN zm@6e8Mkk*eoqPw4h7Px$Lkf+KAP$t)jX+c;PGRWRG(*KBrjZYou>#Y-!mho~bW1%| zg@c_5G|i128M8yN)}gH0$ctD)dZce6nq?tO-RNrX!zB*u0kX-5ydO|-9FE^t#XBj5^S3p4^ya6}4P4`_UA+H@^3>5S@$L%PgILA*A05R-t&Usi=EZT7!9$2(vHPBS+ zT4WV#55!Ts2KW%oUrun)+>n&6;g8yWGBRpDwypQk8mvpvzQ7p6`h+x;athiQ2-QGf zaR|ho0$7R2bYrvQ1Szp$D(Qb7gZhg0xdCQi(pcdYRH$4715?*8Eq`Y%&qII%n`S8I z^RvyQ51NslQ7Gf?7B|*`hBKE3D zW2s;qvBBS2sHDJO?$rxYsNh|Scp3$oUhws`DCh(!C_{(#8KxdSv_sp$AhR9X@2O5$ z>#OByc6V%f+HlfG{y);{Jo-W9o-W;hyO_w27d55YRH-0kDps zq12#um`@1=$uu|z-H-}ESIg+s&ofbwP7GA`XjenjgGXAB$xiwd1vOu=P0Ch`Mtc;0 z)6Qr`l zP1rYvx)I+M{XZjYyh94LF6f6A-j|1)b_?()+Tvkl$WtB85KM)99b%&zi?49{;>3;g zH8`GZ;zs(lJUk_e4cqb57EdC?KJIKQhyy_Ac~nxzOWtoCVgtQ0h!+5dNX^G%@#e2_ zBC<$77R@}_GmOVK5NCqpBw5hm?H~bF^L8BqPpfe}b|VXDjU{PSKGORo?wE#CvU^}* zJ|m~=F?nd4>}^9#=nO_4JczktdhHny!iNq}^A>jQB{hE*3xCb>g;RCE@D0v1H|MMP zh-#nbVjP6{egka!?j+fJIzjYjp}k$$A_z{!hM*4iX3e7SVd|N32C?g&U8ING;^Bsc z$4(9$@zTUb@0r-TYn|S8X>sv&SM7x66xbW~J*kGClR)@wPbGVMtljCIvOV5&tg;aY zXOVQc{-7hQ{_gni#{tDKZ-ni7fEYD&+#U&<^v@1dvQJ9rGG6-?=vrz)CcTPTxmo`+)3NIn4B8`0!~EEuM;j>*x#Ibajr6@kZf0jNg-kZY z1m7F1v1E2K)~UstbD?5ZV}pA)8a(T{kfu`koWoZIy=R85evs)3=vfCoskj4!MGI+Y zK+u}8_^3Sx|M7#H{SEHRtiK+ zYc2@zVNGD2s3(ATUE&m|?_Z;qHW`S9{9~a&|E~ffs{Jn{9f;kP(iWp!>?spAu8 zrK|bFL}(AkP)MUThCE3oc63~bMqJ)tEV#0Ix39Aa^Dubbq>4z4EkZ&ycJt}fxXoocx)TtsEf9!Q*k~%$3|A@0;mpXKzy>C4^7L>P@8`Z zS_LvXl8*(Q-y|viYJg;@dS+`Rb@=K@WNr{3?MVS%S<25O%bCzo`o8!N5>Vahe=VS{ ztN%5VSLAjW-~8HM(v1$jsKKg%!GRa{jvSa8lJMG+n*SK{(UjK;)d?BFoSmQ*7%`k2 zBl=F>on6-``fC~K{4FjuKwSk3+^V0kYW-e)ltr5)^}em@%n`xtUFb&S_uy>b?fn`~ zEq$bgvt}5g7Z%fF^HY?-80lFuNB2P6MVO-(a)Cl0P}b`#>bFPFP}_z*S_6A@6EjBv z2%uZxt|*!m|sCFA?=f&JoVX_G_NDS-7* zg#F<_)+z7}-VWQ|Z=Lo*M#I+0hfYOXCsNXeb?RSVU&A=90=DG+8asyNgya1hJBAjF zwJm=e3BL0Mlp{l%2%!g|(p)N`Sq_)zW{FHvlXsne+fX@Br(5{d*Q+l7HpFiJc|ItY z#jR)C9w=4a-a9ceZl63qU@x1%HlhBieZg7Jz#h0_^LHrDOVfU4(i^Z_ zFOj~?-$rK3`2zJ<|JGCYN4#I##f=mR(e*g+$eeM!LQIhkuYX{KAo|JwV_Qx7xp?;L z2Bu#n(3c#RDqhH_*wjl4Q(d$P%aoe@-&v!|aIKiBEtiSItlzX@)%z1+*T_evpIh*< z-vn~UPG(z&UEo6GI^>H}@-p#`QS-Oq^8m1oS)~>t5-8fH51rJ(Ea(Y_*^?EX4`$~c zKplFq$9EO#s4<0s2~S~&kex%Yto?Sb8l~LMO?=X1=PYC+dQ5h%7Cnu&bF`Jv=Z%Dl z&&O^6_3;m6=Zb;ZZ|4eFF2c^)shvnW_bs;%u`iG&VJ43Frt6`iZTXq_#Dggrw>o$0 z3^gtz&pTz8RcyE)NO@}9E@;3aI}_Xn$B8Na}Q z*SBm%StsgtyA(!LOJk-C^DLiJ52yGsJ$p%>>30(Ft0HhPWcip#Jg_dlkf+~@N4wpj-fAz6SDXs-rY)RVLw1; z=xKtN>EJB%J`(>Wy}-c=7=3zc7)Dn6J^WbRxOc(KGtgydF1#Mpc-s8*#jl>VQ+^IR z)m`##V(GNRN@a+oS|^Tl;FG=(zD%feDG2K*(_++u5qN_KLD%^X{8Cf;<+O)_n|5JS zrS-Io9|lXwYy$553tHJuR{wdje*bA;f8nRhmZf}~rm*dpP3 zdFOMan?M?td*o)gP24ka2kM&0+t#mdF@16C5EI?z4)+=|W}g>eTP?;_%ujd-euC#2fjJ5n(>Asp^9e^m#5NYr);;J>w5PCxbdJ7{eNNZM%ox%> z_Aa24Ung!{Mo28Ucx7DJkm=qz_Y_hq8@ZogfOR(kP6FGy!p=*9`?;Smp7{x7abC%C zn6|I_{Pgc%Pe=L(hk}_;G5?^bQ4fC@{z1N={SjJ&%NO|@R@ z8%+CPlYfx&o&Ldn=wGydP{rnu{5mwo_lp#!;o_blFYBE^cQm^u-jl)mQ^8=hdmPaQ5bAHiRjTI9nk-Dx6>DAUnk z8;%KkVV=^|DeJu_VzKF7eS=(fT6Y=R;4*xI-%*=#gQVO*UOoL7625w_>2zT)=2D7$ z+DI6|etDJ4`bdOP1G}gjdR__lWc7G5gg+FEeAe$y= zx8j-hw}_Dj;_$PU*q-CaURjE-GU(IOJ+gA9NNL5_q_TR0tkz(G;Vp8t5N{UeIf`&j zi0zu6w&`-Sc z!)i!t;}`Vz$W8dp+LQKar7YgxLVpgNYG&`#i}@Y0nBRgNmL8ru@dOP|Fx*{|5>Ln9 z&06A@kGEDj#g%y(^tUjV{?49Be-|#MzjsvA-#^!*xAgEdttWcey#){2>rBf$o;I0e zQ$c7~@uY#@#fZz&`#5d|u@`zfB3;~Y2>A4tZD4yEu~x!wKm{I5>%e0$aVu)Cf4Lpc zU~k7c?45#wLfrFk-;TQy_l^99T4lerPUUpZ5=7nnL8~gsl{o%UyAp;(|Z5Jxw*em604g3MBHT6B`~tJ5nt`O((qN^1Mak3 z{4GwKiNCj{EymySv}*i)GOZpR!Nc}6#yRnU=hLzHs)B9Z#b$>}`zg3(}?h5e5K-&IcGhI6m}`jKUge+`A!;9iVd!kvM8IPNBX2jR?Y z#WSTNwuM3yzT>8Hx>Gm~rA_=^@b^$?GH%L0hI9>X2W}hgUce6Hrg8&kEAll$%}Swa zWyP9`GGTme#qwoUb!&w2)io>2#;;geSLLY{IIyzTAru$Qbjh=Y@vBN}#(P#&3**Zx zR*kP+x;uv`= zl}`rl1b%yv8aKhqP4^XePVCk1ukd-x^SCMf3NJCxy$-L8l;eIK?+JSTn(jZcjUptnYgCZD6XCkFvu&>{aIYPSlS@Z+vy15;o zgLLuxXcuV)w&h!}%&RrDk2K?R%sUj&7NnDrII&^Oo(=~%W}_b!Lr6~ zxj1o%jePSoK>_W1=AbEJ9IBd18UbyL^?5nOzyOb(U!0p0)`1hgE8w7AB z+c(Czl81X^UCEA^pClv?FG#jKlWqCKO7V)DDQ5+i_7lF$WS_L3S_bzJj)1MPmn(ZBs!SU}qFKg1!s=-vn7=^k)-& zuz zlrnxx)K8iC?IM0pWqc@(;^lPWB$an+yW*$ zn0_k5#m3L^4H&^k;C>zOO`t>mkKjtS#}p+b+otIfLG`{uc{|D%QaNM}l5Hb+BG#-O zYu)(28L61YO)rEp#jqy&R=St3v^`cjku_U4hO2cBOQ^~na(eGVQJH^n^?fXI@_J4B@)J}iDUCE1M zuZ{&ZfTG$d92UEY+Bvs`egWxawDUaKgu|gw3+7WOqVdR){4tMb<`SaSie~nLL9c*A zuR_ZmgqC|P+2$Hnh|+>VN~aBroy2-FNV#*^ecwS_8Wz)?Y-`>7%Bu%olagn8hir_0 z&>Dz)DE46z6PjlqY}ckEp%DAOJ)`)QAD(AEFIz0J;=pVvpqZxi`a0;Xfe*$0?@VTo zpr>X&9Q#mQ!1`dkcSvlBB>{_p>2O;2aj=y(EfgxnvvCof5r8iSoc&*<1JRko=*ZM= z8g4i6xAlfX?Ee;Bm>BQa7?Ti_hnDunyiPcD(K_+~?<8#U4J6l6a)%`$CO_F0^EU&B z@V>vk=fM9D95DWWLF4}uj2@GN1MGsxo*I1yL@zM*_cmU>C92%8f%q9DR$*IIx$*z> z8UL@KP8EL4<@%HH{|83H+iMJno*MYZ{|9K48uX3-_b&|R^o{@DkCr-J#{cVQ{6BsM zJbk@`iUlK2|A!-8M%1B-=M!~s`2T^YP##^z|66^bo`qp>uqV7$$u5IW7a4h8PWp&0 zqx|1zLll`4Hf?rLB3Rj9{AqNsC#Y6-(HjPI8BvP{-akW!u@~J@&e4PnuY=G9()n~X z@dDDnbU`Ju>xVp*@b&~<2E0+9-f%zJVIs~v6(=Q#QyI{3*&0nvf$IWT2BoH zp~lrNHJ++gdMd^(sj3@yN8PgJe;2ODbzhS5%ZNEk|7=r`ISc zt*I$ptJg4|?<@lvRi$=7h4ra)#j-N=V)Hn2`ks5l^Xy2%B^uH>qzM*%G)X>vZpI8xHe+^(%X4nNA z*CR%1*e{^4i<=1}E7ao2T;IX#8!3xDg|V?e=g&rZe^mW#d|*cU*nCrEJR0>3s4uF% zVMmSBurCIFbpLl^%ET&-gosUxaFbo-A))vxDbZKM>tG+$BVge@o}6r=qubf$*O zNH-e>R0oIWk7tEHmM7^&Pyvors$*hv}IfU&l?dYqX!S-hmuqr|VfFbnyCNzexv& z<>)=+3B{-{cpW;1S5GqZB>dMHzmXnAiMhVvCuQ*ZELIn;-Oqoceos_=!+&n{>6Kij zy7U+=f1d+Jw2c0D`y9xDFT8$x9Lt9PIKof*!$~BZMG+-NeI){VF7A0KH`+F%F7oTS z2;&P-bX$}+WZztWOF+-1a|J|xu^YF+H$(r?`W~qL_FwAtM?@)r==O7Y{cs<+pDb+C z>l=Qtp6hSl$dAJVzNifAf5Y$Iv|Y#W@CJ=`js6?;$-k#19&Z0phh9Vr6IYs^g#Sj@ z4;KvZ5KGYtgPy58R=7C4KQMv8M~h(C%}6*_kHHsHK`eT0*hv!@bYca={zby$1jDXH z!mWZ~uOi{`;eAphe28G!mq@rxFziMod}w%o6$wue3_TwSA0`<3I})B4*2|G_?BePj zW)ORhg=RMNsktx~8rRU1k#M_U=)Xw#dC+GLGl)IM(trNp9SHt|@P5r)DHc(8L%&4A zQw2kBM8df-HvvhGwg#K|E>+fL(KX+bexe8=rJmELU+trIjd;l!4u2nTnisp@!61e{>*a7E3T}a7WOT0336MO| zbs>j$a5y`&06ZIT;%5`LgK-QS#~BQsDr7{_pU&Y94ma@Wn{*4TZGF9iQP|4qtOuO> zBaG1j-RL)6Kjn0CIh}MJEc}hZQ-qGF{=8)1D-MR4!SU%wS&2XO9B$B|b8H6Z^tW-N zM<4DFBv&5+PW|kjqZ4Ll40xoU9U2IKuyy(^Yd2BIpm(@T*D$m{(E25mf$0Ab_-r1z zBgW2*fjfrLu?y+z9mw@xlNkJ5y>}CXrwE5RKaCpnDyu~}SMQYqejcJ+-FNGlhFVz( zI1f=7Bv|U@`1RG1_&;Iz&~Ftwyp-3X_Xf@fpY1#l$Ig&Z_RJvk=?8+&gIwiuxib3m z{vh}#IsL_#>J2XB?TQf8f%<>xAn@El;KhJDI8Ad>4LI>_OBCN8V054-({$|Hc%>f$ zZpXTNJ!)PaWB6vu`ty^VPRAvB-o{a00G!&bk81Z-hJUUd?;3>uCxgIGbNY@b`a`XQ z@N*FOq(R_CfK&gQqUhho;aj5Q>MlmdCS;7#8BoIc@W3GSAK`R_DEhzS@a`!3PjmWB zqjkb#IsF5J(Eo4{_$f}mDT+S5$3pU-%%ZS@z|O?b#>Id;cw6S=D!_?9xl#SUfx{O^ z!3#NkN2N}Mo#o-NjKR&6_2<=tz<)jnd>i0)=-aJa-x?I3VffIW+~BY?XB5)!F$}cs z-sSl0MJ3>|cNdU;X3*hs?&1x6&EbuF-i>{th|K`;b1|PUV|~$CCiOFVeWf#ePSli4 z;dFWz=|FatipPAwiT{hE=JA$6=&ay$sz>T{4E;v)Fc2SpJP7;=z#Te?h`;pT7}9u~ zIAhqEJ1`D#_%kp zIlMbfha2l%7++UgGk*E9JI0S2N6DlKPKkb%OEU%ydbZv>= zt2HGU%#!kzb$2YU7`Xhq$|{$yEcFOArK?LytC#TxJT;|Nwad{gy11lPxU+OsX-Omo z14W^Mr?qu8td}dRE2>I76)UPs=q*<;W_d+P`LY^eAovP|(wCRkdP?+{U&l?#$jIb? zDi4N9fNKY=Sy8o0C||x}MQJrSP<9t4XIX7c>9}hVp|7g-;Dy@iahcZ%)Pu@$mehi$ z15#R94Q?(gUo&VSZ^uk|;6AOW!?A?%0x!g%6q8aetf(%pHA^7s zRjYDyr@7_4sU_Efr4yNCF$|M5>22%tPIJJJj1EEkD=G$|VMs2gRZ&$AF~DS>iyjs} z&&rZ&NE|!EDZOK5O%!fPNkvUf)k^9`sRsv1k(BDH@S62qk+2fExTvIGEr3I$6pCra z`UhLPtjaT)Wy2jIjU$v)uoIz568ZrKX=Y46u{sdToFp(sA>gEJc|}w=NtPo!Ni)p2 zP93@KTACT1QzbQ#h#*(CGzwPfsi~_1I|k?=qe=bI2gkCyDxel=v77ll$SA`^CQaxc zBz2VM85f8aR}D-=N=h(>a=iAwB60vLDpr(LuZ@I-M_;`XR4Zy&D+aN;s%2}?5a@-q zKbA+h3Jnen3+Jg{U_Rv|DPTQTfi%pAr?NJ({c6wBnu^l$61G@NAVg3zkr=hcd_;n= z^2;Ndg3MrfthfsXXvF|i92PF7qNtC=ws6J}e3}##Fv^UtOcYCSEXl3kin^)+MTp64 zm=z{_QCe13Q5!XC!ZQ|e2|hd!DoJlg4zPA@EwpT9B(S7#Rmp5_Wv7xdgNZfsn-l^A zgsHD6En8Y%Q7y2wXjtQORw6?Wvxv_gBg7=oP$vEI8v!6p&)A=Nv))$Y)vVxac0A#$_PD*!ns1lct(B=7xD0fMDu_xDBV-~{_po3_?`pb zbKrXpe9wXJIq*FPzURRA9Qd9C(Yr%^>-}9j|G{@6k$$}}*ke4VaDFb6trQu(Rl+eY7Z5aHE+Wi8PjH;0$b&2t`!Dg2k$6s1ciG%9w)}jQ>1xWNe`IU<2cIcppu8;eB%St}imW z#p;;mE4(jbJ9ZYGVzk5X=>814+YHx;>`6a3N+<^28tbtoBitb9(Jvt!WkY;)NJZFXTm`S;-Gm4ZBR39sv|)>5QO7}vT?O5$01Os2l+}&0Tve6 zq5pM*UxGPAikj%j*vT1_?#L|7DrZE-WsI932z0DNM=UtL#c7cs47bdFM95v9uvKWe zbYr~yW_`w`jhpZhQu$>`cdx(gjskuh15Ev*GZ#7%xdQiA5`WUFmqdhMT%^t7KIeZg}}@=oUe`BZIZ(ahWDU-;U;M%CSWJnO>C zM}}_q9k2H1E&BD4h3OA0*?#Mx5!c*)W>a>`*+s?gUH8|2ecA$=x6OLt*0P(HH2!o% zTutd6v8%H$SlIOT-3vxsJFEKb-5)-(?yL9*@<;xocymng)2l!Db@Bb1*IsHV1-(V6 zo0tE_r)zJxB>U697To!9&)Nre1wK!nzwWwR8Uyh=1vg$p5b(i-@My)@*Vn9kb@2s{ SH}#FnsCntZ7tXLZ75^7aC(SGX literal 0 HcmV?d00001 diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/LICENSE.txt b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/LICENSE.txt similarity index 100% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/LICENSE.txt rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/LICENSE.txt diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/PKG-INFO b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/PKG-INFO similarity index 98% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/PKG-INFO rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/PKG-INFO index b2284b3..9bbb9ee 100644 --- a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/PKG-INFO +++ b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: cffi -Version: 1.12.3 +Version: 1.13.2 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/RECORD b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/RECORD similarity index 55% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/RECORD rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/RECORD index 3f1bcd6..ae97c04 100644 --- a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/RECORD +++ b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/RECORD @@ -1,28 +1,28 @@ -_cffi_backend.cpython-36m-x86_64-linux-gnu.so,sha256=MTEsB338OuQyMi8196lpH7vjq-KEeSk7gL0CvOXwiiU,849704 -cffi/cffi_opcode.py,sha256=v9RdD_ovA8rCtqsC95Ivki5V667rAOhGgs3fb2q9xpM,5724 -cffi/lock.py,sha256=l9TTdwMIMpi6jDkJGnQgE9cvTIR7CAntIJr8EGHt3pY,747 -cffi/vengine_gen.py,sha256=Zkq0-EdeZwn6qUvf_CI8iUEs2UxVIvDmKCH1j0-y0GI,26676 -cffi/cparser.py,sha256=dcVqrRob1zqrCO--RZ6e-TtobJ7VMDpCU85W6QJ-N-4,40874 -cffi/backend_ctypes.py,sha256=_WkpD1SJel5gJovV-0u8hw-XvD3Efapqm9pIAEHTHn4,42449 -cffi/vengine_cpy.py,sha256=hdyjjZNijLrg_uGMnnFyC-7GG_LxWtwB8BlS2vvVDQ0,41470 -cffi/verifier.py,sha256=J9Enz2rbJb9CHPqWlWQ5uQESoyr0uc7MNWugchjXBv4,11207 -cffi/pkgconfig.py,sha256=LP1w7vmWvmKwyqLaU1Z243FOWGNQMrgMUZrvgFuOlco,4374 -cffi/model.py,sha256=AYyjS26uiFKXtkm43qmStpy9zfGh5HVJF4UETYFBt6w,21682 +_cffi_backend.cpython-36m-x86_64-linux-gnu.so,sha256=2jHTJqc6kEwGMSsuUSQ_w346-dhNO5-zIOYuCGaHDvA,849704 +.libs_cffi_backend/libffi-806b1a9d.so.6.0.4,sha256=qR92z2wgl-zMALZZsvAiVl3h4r-CgLMTm-qtfpu9ioc,46632 cffi/api.py,sha256=Q07iwDD0FRwWa2fx2ZzQft69iJs9aNR52fvrtUy3EY4,41800 -cffi/_cffi_include.h,sha256=JuFfmwpRE65vym3Nxr9vDMOIEuv21tXdarkL1l2WNms,12149 +cffi/backend_ctypes.py,sha256=h5ZIzLc6BFVXnGyc9xPqZWUS7qGy7yFSDqXe68Sa8z4,42454 cffi/commontypes.py,sha256=QS4uxCDI7JhtTyjh1hlnCA-gynmaszWxJaRRLGkJa1A,2689 -cffi/ffiplatform.py,sha256=HMXqR8ks2wtdsNxGaWpQ_PyqIvtiuos_vf1qKCy-cwg,4046 cffi/parse_c_type.h,sha256=OdwQfwM9ktq6vlCB43exFQmxDBtj2MBNdK8LYl15tjw,5976 -cffi/_embedding.h,sha256=PuNkRzXjURiRh7tXzVdIn0RD9pTJx04ZokHbcEO_3OY,17226 +cffi/cparser.py,sha256=l4Hy6H2H3q4-0-Mv-5ld3mkH4qRFybWz2CTwNUtNpw0,42071 +cffi/model.py,sha256=AYyjS26uiFKXtkm43qmStpy9zfGh5HVJF4UETYFBt6w,21682 +cffi/recompiler.py,sha256=9BR4oOQ9wFTMrp6CGa4Pa4U1pAU64Mv5-KwW5Hdn3ZM,62755 cffi/setuptools_ext.py,sha256=qc6arfrSzm4RNT5oJz6d5td7KJ-pHfI7bqYD0X4Q-08,8848 -cffi/__init__.py,sha256=XPx-ySmw7OmYmr-7iXd3YoXhXj1HQLHYviMKpmAuWLc,513 +cffi/vengine_gen.py,sha256=Zkq0-EdeZwn6qUvf_CI8iUEs2UxVIvDmKCH1j0-y0GI,26676 +cffi/cffi_opcode.py,sha256=v9RdD_ovA8rCtqsC95Ivki5V667rAOhGgs3fb2q9xpM,5724 +cffi/pkgconfig.py,sha256=LP1w7vmWvmKwyqLaU1Z243FOWGNQMrgMUZrvgFuOlco,4374 cffi/error.py,sha256=v6xTiS4U0kvDcy4h_BDRo5v39ZQuj-IMRYLv5ETddZs,877 +cffi/__init__.py,sha256=S9BTr5ma0KrdRubi0WQGrLfmLhRgkYWvLaGRqy2xiPc,513 +cffi/ffiplatform.py,sha256=HMXqR8ks2wtdsNxGaWpQ_PyqIvtiuos_vf1qKCy-cwg,4046 +cffi/_cffi_include.h,sha256=JuFfmwpRE65vym3Nxr9vDMOIEuv21tXdarkL1l2WNms,12149 +cffi/verifier.py,sha256=J9Enz2rbJb9CHPqWlWQ5uQESoyr0uc7MNWugchjXBv4,11207 +cffi/vengine_cpy.py,sha256=hdyjjZNijLrg_uGMnnFyC-7GG_LxWtwB8BlS2vvVDQ0,41470 +cffi/lock.py,sha256=l9TTdwMIMpi6jDkJGnQgE9cvTIR7CAntIJr8EGHt3pY,747 cffi/_cffi_errors.h,sha256=6nFQ-4dRQI1bXRoSeqdvyKU33TmutQJB_2fAhWSzdl8,3856 -cffi/recompiler.py,sha256=LGqj7GPuq4KIG4axrN5G0Oy6YGmrLbBA0bHE-jCl6Oo,62711 -.libs_cffi_backend/libffi-ae16d830.so.6.0.4,sha256=DIjdi229NoMS7VUut0J5Q7Rk88JhtOndGB6xPyyszZM,149064 -cffi-1.12.3.dist-info/entry_points.txt,sha256=Q9f5C9IpjYxo0d2PK9eUcnkgxHc9pHWwjEMaANPKNCI,76 -cffi-1.12.3.dist-info/top_level.txt,sha256=rE7WR3rZfNKxWI9-jn6hsHCAl7MDkB-FmuQbxWjFehQ,19 -cffi-1.12.3.dist-info/RECORD,, -cffi-1.12.3.dist-info/WHEEL,sha256=d2ILPScH-y2UwGxsW1PeA2TT-KW0Git4AJ6LeOK8sQo,109 -cffi-1.12.3.dist-info/LICENSE.txt,sha256=BLgPWwd7vtaICM_rreteNSPyqMmpZJXFh72W3x6sKjM,1294 -cffi-1.12.3.dist-info/METADATA,sha256=OA_DlKzbYB72gWWz0R2ds_RJzTIzvFx5cnHf5NXTRuo,1140 +cffi/_embedding.h,sha256=fXmvYWE96kCgekPNX1_FnYAUJ9I6gnSrBhhRAHKdhww,17411 +cffi-1.13.2.dist-info/RECORD,, +cffi-1.13.2.dist-info/METADATA,sha256=7iXowU_BLqDyZXb5vOztg3wha0RmjMcxL_MtvN0EnDo,1140 +cffi-1.13.2.dist-info/entry_points.txt,sha256=Q9f5C9IpjYxo0d2PK9eUcnkgxHc9pHWwjEMaANPKNCI,76 +cffi-1.13.2.dist-info/top_level.txt,sha256=rE7WR3rZfNKxWI9-jn6hsHCAl7MDkB-FmuQbxWjFehQ,19 +cffi-1.13.2.dist-info/WHEEL,sha256=d2ILPScH-y2UwGxsW1PeA2TT-KW0Git4AJ6LeOK8sQo,109 +cffi-1.13.2.dist-info/LICENSE.txt,sha256=BLgPWwd7vtaICM_rreteNSPyqMmpZJXFh72W3x6sKjM,1294 diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/WHEEL b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/WHEEL similarity index 100% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/WHEEL rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/WHEEL diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/entry_points.txt b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/entry_points.txt similarity index 100% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/entry_points.txt rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/entry_points.txt diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/requires.txt b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/requires.txt similarity index 100% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/requires.txt rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/requires.txt diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/top_level.txt b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/top_level.txt similarity index 100% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/EGG-INFO/top_level.txt rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/EGG-INFO/top_level.txt diff --git a/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/_cffi_backend.cpython-36m-x86_64-linux-gnu.so b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/_cffi_backend.cpython-36m-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..9560f0aa1aac39fa5b686e4c2a39d7d89a03439b GIT binary patch literal 849704 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 IV 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 z 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 -7iR7bWPKa+_q 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

xVY3Svx$9_KE@SqfS^v2obSy$j_}fXh4XgvOcB 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': + return left >> right + elif exprnode.op == '&': + return left & right + elif exprnode.op == '|': + return left | right + elif exprnode.op == '^': + return left ^ right # raise FFIError(":%d: unsupported expression: expected a " "simple numeric constant" % exprnode.coord.line) + def _c_div(self, a, b): + result = a // b + if ((a < 0) ^ (b < 0)) and (a % b) != 0: + result += 1 + return result + def _build_enum_type(self, explicit_name, decls): if decls is not None: partial = False diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/error.py b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/error.py similarity index 100% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/error.py rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/error.py diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/ffiplatform.py b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/ffiplatform.py similarity index 100% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/ffiplatform.py rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/ffiplatform.py diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/lock.py b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/lock.py similarity index 100% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/lock.py rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/lock.py diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/model.py b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/model.py similarity index 100% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/model.py rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/model.py diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/parse_c_type.h b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/parse_c_type.h similarity index 100% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/parse_c_type.h rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/parse_c_type.h diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/pkgconfig.py b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/pkgconfig.py similarity index 100% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/pkgconfig.py rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/pkgconfig.py diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/recompiler.py b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/recompiler.py similarity index 99% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/recompiler.py rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/recompiler.py index 20e912b..d6530e5 100644 --- a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/recompiler.py +++ b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/recompiler.py @@ -855,8 +855,9 @@ class Recompiler: try: if ftype.is_integer_type() or fbitsize >= 0: # accept all integers, but complain on float or double - prnt(" (void)((p->%s) | 0); /* check that '%s.%s' is " - "an integer */" % (fname, cname, fname)) + if fname != '': + prnt(" (void)((p->%s) | 0); /* check that '%s.%s' is " + "an integer */" % (fname, cname, fname)) continue # only accept exactly the type declared, except that '[]' # is interpreted as a '*' and so will match any array length. diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/setuptools_ext.py b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/setuptools_ext.py similarity index 100% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/setuptools_ext.py rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/setuptools_ext.py diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/vengine_cpy.py b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/vengine_cpy.py similarity index 100% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/vengine_cpy.py rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/vengine_cpy.py diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/vengine_gen.py b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/vengine_gen.py similarity index 100% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/vengine_gen.py rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/vengine_gen.py diff --git a/py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/verifier.py b/py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/verifier.py similarity index 100% rename from py3/lib/python3.6/site-packages/cffi-1.12.3-py3.6-linux-x86_64.egg/cffi/verifier.py rename to py3/lib/python3.6/site-packages/cffi-1.13.2-py3.6-linux-x86_64.egg/cffi/verifier.py diff --git a/py3/lib/python3.6/site-packages/chardet-3.0.4.dist-info/RECORD b/py3/lib/python3.6/site-packages/chardet-3.0.4.dist-info/RECORD index 1039602..9ea244b 100644 --- a/py3/lib/python3.6/site-packages/chardet-3.0.4.dist-info/RECORD +++ b/py3/lib/python3.6/site-packages/chardet-3.0.4.dist-info/RECORD @@ -46,7 +46,7 @@ chardet-3.0.4.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34 chardet-3.0.4.dist-info/entry_points.txt,sha256=fAMmhu5eJ-zAJ-smfqQwRClQ3-nozOCmvJ6-E8lgGJo,60 chardet-3.0.4.dist-info/metadata.json,sha256=0htbRM18ujyGZDdfowgAqj6Hq2eQtwzwyhaEveKntgo,1375 chardet-3.0.4.dist-info/top_level.txt,sha256=AowzBbZy4x8EirABDdJSLJZMkJ_53iIag8xfKR6D7kI,8 -../../../bin/chardetect,sha256=uu2ZsZAI3jsrnNJYytQUBkm4KhtQyOiN6rwz0BVApeQ,263 +../../../bin/chardetect,sha256=EqBu90VkIxP-0q8wpBd9kmUpJ7O_IFmliH0EmbaRk1c,248 chardet-3.0.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 chardet/cli/__pycache__/__init__.cpython-36.pyc,, chardet/cli/__pycache__/chardetect.cpython-36.pyc,, diff --git a/py3/lib/python3.6/site-packages/dateutil/_version.py b/py3/lib/python3.6/site-packages/dateutil/_version.py index 670d7ab..eac1209 100644 --- a/py3/lib/python3.6/site-packages/dateutil/_version.py +++ b/py3/lib/python3.6/site-packages/dateutil/_version.py @@ -1,4 +1,4 @@ # coding: utf-8 # file generated by setuptools_scm # don't change, don't track in version control -version = '2.8.0' +version = '2.8.1' diff --git a/py3/lib/python3.6/site-packages/dateutil/parser/__init__.py b/py3/lib/python3.6/site-packages/dateutil/parser/__init__.py index 216762c..d174b0e 100644 --- a/py3/lib/python3.6/site-packages/dateutil/parser/__init__.py +++ b/py3/lib/python3.6/site-packages/dateutil/parser/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from ._parser import parse, parser, parserinfo +from ._parser import parse, parser, parserinfo, ParserError from ._parser import DEFAULTPARSER, DEFAULTTZPARSER from ._parser import UnknownTimezoneWarning @@ -9,6 +9,7 @@ from .isoparser import isoparser, isoparse __all__ = ['parse', 'parser', 'parserinfo', 'isoparse', 'isoparser', + 'ParserError', 'UnknownTimezoneWarning'] diff --git a/py3/lib/python3.6/site-packages/dateutil/parser/_parser.py b/py3/lib/python3.6/site-packages/dateutil/parser/_parser.py index 0da0f3e..458aa6a 100644 --- a/py3/lib/python3.6/site-packages/dateutil/parser/_parser.py +++ b/py3/lib/python3.6/site-packages/dateutil/parser/_parser.py @@ -49,7 +49,7 @@ from warnings import warn from .. import relativedelta from .. import tz -__all__ = ["parse", "parserinfo"] +__all__ = ["parse", "parserinfo", "ParserError"] # TODO: pandas.core.tools.datetimes imports this explicitly. Might be worth @@ -423,7 +423,7 @@ class _ymd(list): elif not self.has_month: return 1 <= value <= 31 elif not self.has_year: - # Be permissive, assume leapyear + # Be permissive, assume leap year month = self[self.mstridx] return 1 <= value <= monthrange(2000, month)[1] else: @@ -539,7 +539,7 @@ class _ymd(list): year, month, day = self else: # 01-Jan-01 - # Give precendence to day-first, since + # Give precedence to day-first, since # two-digit years is usually hand-written. day, month, year = self @@ -626,7 +626,7 @@ class parser(object): first element being a :class:`datetime.datetime` object, the second a tuple containing the fuzzy tokens. - :raises ValueError: + :raises ParserError: Raised for invalid or unknown string format, if the provided :class:`tzinfo` is not in a valid format, or if an invalid date would be created. @@ -646,12 +646,15 @@ class parser(object): res, skipped_tokens = self._parse(timestr, **kwargs) if res is None: - raise ValueError("Unknown string format:", timestr) + raise ParserError("Unknown string format: %s", timestr) if len(res) == 0: - raise ValueError("String does not contain a date:", timestr) + raise ParserError("String does not contain a date: %s", timestr) - ret = self._build_naive(res, default) + try: + ret = self._build_naive(res, default) + except ValueError as e: + six.raise_from(ParserError(e.args[0] + ": %s", timestr), e) if not ignoretz: ret = self._build_tzaware(ret, res, tzinfos) @@ -1022,7 +1025,7 @@ class parser(object): hms_idx = idx + 2 elif idx > 0 and info.hms(tokens[idx-1]) is not None: - # There is a "h", "m", or "s" preceeding this token. Since neither + # There is a "h", "m", or "s" preceding this token. Since neither # of the previous cases was hit, there is no label following this # token, so we use the previous label. # e.g. the "04" in "12h04" @@ -1102,7 +1105,7 @@ class parser(object): def _parse_min_sec(self, value): # TODO: Every usage of this function sets res.second to the return # value. Are there any cases where second will be returned as None and - # we *dont* want to set res.second = None? + # we *don't* want to set res.second = None? minute = int(value) second = None @@ -1111,14 +1114,6 @@ class parser(object): second = int(60 * sec_remainder) return (minute, second) - def _parsems(self, value): - """Parse a I[.F] seconds value into (seconds, microseconds).""" - if "." not in value: - return int(value), 0 - else: - i, f = value.split(".") - return int(i), int(f.ljust(6, "0")[:6]) - def _parse_hms(self, idx, tokens, info, hms_idx): # TODO: Is this going to admit a lot of false-positives for when we # just happen to have digits and "h", "m" or "s" characters in non-date @@ -1137,21 +1132,35 @@ class parser(object): return (new_idx, hms) - def _recombine_skipped(self, tokens, skipped_idxs): - """ - >>> tokens = ["foo", " ", "bar", " ", "19June2000", "baz"] - >>> skipped_idxs = [0, 1, 2, 5] - >>> _recombine_skipped(tokens, skipped_idxs) - ["foo bar", "baz"] - """ - skipped_tokens = [] - for i, idx in enumerate(sorted(skipped_idxs)): - if i > 0 and idx - 1 == skipped_idxs[i - 1]: - skipped_tokens[-1] = skipped_tokens[-1] + tokens[idx] - else: - skipped_tokens.append(tokens[idx]) + # ------------------------------------------------------------------ + # Handling for individual tokens. These are kept as methods instead + # of functions for the sake of customizability via subclassing. - return skipped_tokens + def _parsems(self, value): + """Parse a I[.F] seconds value into (seconds, microseconds).""" + if "." not in value: + return int(value), 0 + else: + i, f = value.split(".") + return int(i), int(f.ljust(6, "0")[:6]) + + def _to_decimal(self, val): + try: + decimal_value = Decimal(val) + # See GH 662, edge case, infinite value should not be converted + # via `_to_decimal` + if not decimal_value.is_finite(): + raise ValueError("Converted decimal value is infinite or NaN") + except Exception as e: + msg = "Could not convert %s to decimal" % val + six.raise_from(ValueError(msg), e) + else: + return decimal_value + + # ------------------------------------------------------------------ + # Post-Parsing construction of datetime output. These are kept as + # methods instead of functions for the sake of customizability via + # subclassing. def _build_tzinfo(self, tzinfos, tzname, tzoffset): if callable(tzinfos): @@ -1166,6 +1175,9 @@ class parser(object): tzinfo = tz.tzstr(tzdata) elif isinstance(tzdata, integer_types): tzinfo = tz.tzoffset(tzname, tzdata) + else: + raise TypeError("Offset must be tzinfo subclass, tz string, " + "or int offset.") return tzinfo def _build_tzaware(self, naive, res, tzinfos): @@ -1183,10 +1195,10 @@ class parser(object): # This is mostly relevant for winter GMT zones parsed in the UK if (aware.tzname() != res.tzname and res.tzname in self.info.UTCZONE): - aware = aware.replace(tzinfo=tz.tzutc()) + aware = aware.replace(tzinfo=tz.UTC) elif res.tzoffset == 0: - aware = naive.replace(tzinfo=tz.tzutc()) + aware = naive.replace(tzinfo=tz.UTC) elif res.tzoffset: aware = naive.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset)) @@ -1241,17 +1253,21 @@ class parser(object): return dt - def _to_decimal(self, val): - try: - decimal_value = Decimal(val) - # See GH 662, edge case, infinite value should not be converted via `_to_decimal` - if not decimal_value.is_finite(): - raise ValueError("Converted decimal value is infinite or NaN") - except Exception as e: - msg = "Could not convert %s to decimal" % val - six.raise_from(ValueError(msg), e) - else: - return decimal_value + def _recombine_skipped(self, tokens, skipped_idxs): + """ + >>> tokens = ["foo", " ", "bar", " ", "19June2000", "baz"] + >>> skipped_idxs = [0, 1, 2, 5] + >>> _recombine_skipped(tokens, skipped_idxs) + ["foo bar", "baz"] + """ + skipped_tokens = [] + for i, idx in enumerate(sorted(skipped_idxs)): + if i > 0 and idx - 1 == skipped_idxs[i - 1]: + skipped_tokens[-1] = skipped_tokens[-1] + tokens[idx] + else: + skipped_tokens.append(tokens[idx]) + + return skipped_tokens DEFAULTPARSER = parser() @@ -1575,6 +1591,19 @@ DEFAULTTZPARSER = _tzparser() def _parsetz(tzstr): return DEFAULTTZPARSER.parse(tzstr) + +class ParserError(ValueError): + """Error class for representing failure to parse a datetime string.""" + def __str__(self): + try: + return self.args[0] % self.args[1:] + except (TypeError, IndexError): + return super(ParserError, self).__str__() + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, str(self)) + + class UnknownTimezoneWarning(RuntimeWarning): """Raised when the parser finds a timezone it cannot parse into a tzinfo""" # vim:ts=4:sw=4:et diff --git a/py3/lib/python3.6/site-packages/dateutil/parser/isoparser.py b/py3/lib/python3.6/site-packages/dateutil/parser/isoparser.py index e3cf6d8..48f86a3 100644 --- a/py3/lib/python3.6/site-packages/dateutil/parser/isoparser.py +++ b/py3/lib/python3.6/site-packages/dateutil/parser/isoparser.py @@ -377,7 +377,7 @@ class isoparser(object): def _parse_tzstr(self, tzstr, zero_as_utc=True): if tzstr == b'Z' or tzstr == b'z': - return tz.tzutc() + return tz.UTC if len(tzstr) not in {3, 5, 6}: raise ValueError('Time zone offset must be 1, 3, 5 or 6 characters') @@ -396,7 +396,7 @@ class isoparser(object): minutes = int(tzstr[(4 if tzstr[3:4] == self._TIME_SEP else 3):]) if zero_as_utc and hours == 0 and minutes == 0: - return tz.tzutc() + return tz.UTC else: if minutes > 59: raise ValueError('Invalid minutes in time zone offset') diff --git a/py3/lib/python3.6/site-packages/dateutil/relativedelta.py b/py3/lib/python3.6/site-packages/dateutil/relativedelta.py index c65c66e..a9e85f7 100644 --- a/py3/lib/python3.6/site-packages/dateutil/relativedelta.py +++ b/py3/lib/python3.6/site-packages/dateutil/relativedelta.py @@ -45,7 +45,7 @@ class relativedelta(object): years, months, weeks, days, hours, minutes, seconds, microseconds: Relative information, may be negative (argument is plural); adding or subtracting a relativedelta with relative information performs - the corresponding aritmetic operation on the original datetime value + the corresponding arithmetic operation on the original datetime value with the information in the relativedelta. weekday: diff --git a/py3/lib/python3.6/site-packages/dateutil/rrule.py b/py3/lib/python3.6/site-packages/dateutil/rrule.py index 20a0c4a..6bf0ea9 100644 --- a/py3/lib/python3.6/site-packages/dateutil/rrule.py +++ b/py3/lib/python3.6/site-packages/dateutil/rrule.py @@ -21,7 +21,6 @@ from six.moves import _thread, range import heapq from ._common import weekday as weekdaybase -from .tz import tzutc, tzlocal # For warning about deprecation of until and count from warnings import warn @@ -178,7 +177,7 @@ class rrulebase(object): return False return False - # __len__() introduces a large performance penality. + # __len__() introduces a large performance penalty. def count(self): """ Returns the number of recurrences in this set. It will have go trough the whole recurrence, if this hasn't been done before. """ diff --git a/py3/lib/python3.6/site-packages/dateutil/tz/__init__.py b/py3/lib/python3.6/site-packages/dateutil/tz/__init__.py index 5a2d9cd..af1352c 100644 --- a/py3/lib/python3.6/site-packages/dateutil/tz/__init__.py +++ b/py3/lib/python3.6/site-packages/dateutil/tz/__init__.py @@ -2,11 +2,6 @@ from .tz import * from .tz import __doc__ -#: Convenience constant providing a :class:`tzutc()` instance -#: -#: .. versionadded:: 2.7.0 -UTC = tzutc() - __all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange", "tzstr", "tzical", "tzwin", "tzwinlocal", "gettz", "enfold", "datetime_ambiguous", "datetime_exists", diff --git a/py3/lib/python3.6/site-packages/dateutil/tz/_common.py b/py3/lib/python3.6/site-packages/dateutil/tz/_common.py index 594e082..e6ac118 100644 --- a/py3/lib/python3.6/site-packages/dateutil/tz/_common.py +++ b/py3/lib/python3.6/site-packages/dateutil/tz/_common.py @@ -212,7 +212,7 @@ class _tzinfo(tzinfo): Since this is the one time that we *know* we have an unambiguous datetime object, we take this opportunity to determine whether the datetime is ambiguous and in a "fold" state (e.g. if it's the first - occurence, chronologically, of the ambiguous datetime). + occurrence, chronologically, of the ambiguous datetime). :param dt: A timezone-aware :class:`datetime.datetime` object. @@ -250,7 +250,7 @@ class _tzinfo(tzinfo): Since this is the one time that we *know* we have an unambiguous datetime object, we take this opportunity to determine whether the datetime is ambiguous and in a "fold" state (e.g. if it's the first - occurance, chronologically, of the ambiguous datetime). + occurrence, chronologically, of the ambiguous datetime). :param dt: A timezone-aware :class:`datetime.datetime` object. diff --git a/py3/lib/python3.6/site-packages/dateutil/tz/_factories.py b/py3/lib/python3.6/site-packages/dateutil/tz/_factories.py index d2560eb..f8a6589 100644 --- a/py3/lib/python3.6/site-packages/dateutil/tz/_factories.py +++ b/py3/lib/python3.6/site-packages/dateutil/tz/_factories.py @@ -2,6 +2,8 @@ from datetime import timedelta import weakref from collections import OrderedDict +from six.moves import _thread + class _TzSingleton(type): def __init__(cls, *args, **kwargs): @@ -26,6 +28,8 @@ class _TzOffsetFactory(_TzFactory): cls.__strong_cache = OrderedDict() cls.__strong_cache_size = 8 + cls._cache_lock = _thread.allocate_lock() + def __call__(cls, name, offset): if isinstance(offset, timedelta): key = (name, offset.total_seconds()) @@ -37,12 +41,13 @@ class _TzOffsetFactory(_TzFactory): instance = cls.__instances.setdefault(key, cls.instance(name, offset)) - cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance) + # This lock may not be necessary in Python 3. See GH issue #901 + with cls._cache_lock: + cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance) - # Remove an item if the strong cache is overpopulated - # TODO: Maybe this should be under a lock? - if len(cls.__strong_cache) > cls.__strong_cache_size: - cls.__strong_cache.popitem(last=False) + # Remove an item if the strong cache is overpopulated + if len(cls.__strong_cache) > cls.__strong_cache_size: + cls.__strong_cache.popitem(last=False) return instance @@ -53,6 +58,8 @@ class _TzStrFactory(_TzFactory): cls.__strong_cache = OrderedDict() cls.__strong_cache_size = 8 + cls.__cache_lock = _thread.allocate_lock() + def __call__(cls, s, posix_offset=False): key = (s, posix_offset) instance = cls.__instances.get(key, None) @@ -61,13 +68,13 @@ class _TzStrFactory(_TzFactory): instance = cls.__instances.setdefault(key, cls.instance(s, posix_offset)) - cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance) + # This lock may not be necessary in Python 3. See GH issue #901 + with cls.__cache_lock: + cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance) - - # Remove an item if the strong cache is overpopulated - # TODO: Maybe this should be under a lock? - if len(cls.__strong_cache) > cls.__strong_cache_size: - cls.__strong_cache.popitem(last=False) + # Remove an item if the strong cache is overpopulated + if len(cls.__strong_cache) > cls.__strong_cache_size: + cls.__strong_cache.popitem(last=False) return instance diff --git a/py3/lib/python3.6/site-packages/dateutil/tz/tz.py b/py3/lib/python3.6/site-packages/dateutil/tz/tz.py index d05414e..af81e88 100644 --- a/py3/lib/python3.6/site-packages/dateutil/tz/tz.py +++ b/py3/lib/python3.6/site-packages/dateutil/tz/tz.py @@ -123,6 +123,12 @@ class tzutc(datetime.tzinfo): __reduce__ = object.__reduce__ +#: Convenience constant providing a :class:`tzutc()` instance +#: +#: .. versionadded:: 2.7.0 +UTC = tzutc() + + @six.add_metaclass(_TzOffsetFactory) class tzoffset(datetime.tzinfo): """ @@ -379,7 +385,7 @@ class _tzfile(object): class tzfile(_tzinfo): """ - This is a ``tzinfo`` subclass thant allows one to use the ``tzfile(5)`` + This is a ``tzinfo`` subclass that allows one to use the ``tzfile(5)`` format timezone files to extract current and historical zone information. :param fileobj: @@ -1609,8 +1615,15 @@ def __get_gettz(): else: tz = tzlocal() else: - if name.startswith(":"): - name = name[1:] + try: + if name.startswith(":"): + name = name[1:] + except TypeError as e: + if isinstance(name, bytes): + new_msg = "gettz argument should be str, not bytes" + six.raise_from(TypeError(new_msg), e) + else: + raise if os.path.isabs(name): if os.path.isfile(name): tz = tzfile(name) @@ -1655,7 +1668,7 @@ def __get_gettz(): break else: if name in ("GMT", "UTC"): - tz = tzutc() + tz = UTC elif name in time.tzname: tz = tzlocal() return tz @@ -1695,7 +1708,7 @@ def datetime_exists(dt, tz=None): # This is essentially a test of whether or not the datetime can survive # a round trip to UTC. - dt_rt = dt.replace(tzinfo=tz).astimezone(tzutc()).astimezone(tz) + dt_rt = dt.replace(tzinfo=tz).astimezone(UTC).astimezone(tz) dt_rt = dt_rt.replace(tzinfo=None) return dt == dt_rt @@ -1817,7 +1830,7 @@ else: try: # Python 3.7 feature - from contextmanager import nullcontext as _nullcontext + from contextlib import nullcontext as _nullcontext except ImportError: class _nullcontext(object): """ diff --git a/py3/lib/python3.6/site-packages/dateutil/utils.py b/py3/lib/python3.6/site-packages/dateutil/utils.py index ebcce6a..44d9c99 100644 --- a/py3/lib/python3.6/site-packages/dateutil/utils.py +++ b/py3/lib/python3.6/site-packages/dateutil/utils.py @@ -28,7 +28,7 @@ def today(tzinfo=None): def default_tzinfo(dt, tzinfo): """ - Sets the the ``tzinfo`` parameter on naive datetimes only + Sets the ``tzinfo`` parameter on naive datetimes only This is useful for example when you are provided a datetime that may have either an implicit or explicit time zone, such as when parsing a time zone diff --git a/py3/lib/python3.6/site-packages/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz b/py3/lib/python3.6/site-packages/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz index 124f3e14c68f4e94808400af9a8d4ecdb2178880..89e83517b562451622cea7cbe1dbfac5c3d2513e 100644 GIT binary patch literal 153315 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%0D!KtMVr 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

yja~WxFc`yfrj%BE^ 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%0Ay}5phF%Yq4Q1qkIf-;CS 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 a$1xo%1ox9%9ceNF__ldZ2ky8&yz@WAsp(Gu literal 154405 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 R+?^>J*5HKbLj12+fLcm@iV1fvkXsEd) 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 E0mcVuvH$=8 diff --git a/py3/lib/python3.6/site-packages/easy-install.pth b/py3/lib/python3.6/site-packages/easy-install.pth index b7b07c6..a164ce0 100644 --- a/py3/lib/python3.6/site-packages/easy-install.pth +++ b/py3/lib/python3.6/site-packages/easy-install.pth @@ -1,4 +1,4 @@ ./pybtc-2.0.9-py3.6.egg ./secp256k1-0.13.2-py3.6-linux-x86_64.egg -./cffi-1.12.3-py3.6-linux-x86_64.egg +./cffi-1.13.2-py3.6-linux-x86_64.egg ./pycparser-2.19-py3.6.egg diff --git a/py3/lib/python3.6/site-packages/engineio/__init__.py b/py3/lib/python3.6/site-packages/engineio/__init__.py index f7b2172..f9814bc 100644 --- a/py3/lib/python3.6/site-packages/engineio/__init__.py +++ b/py3/lib/python3.6/site-packages/engineio/__init__.py @@ -17,7 +17,7 @@ else: # pragma: no cover get_tornado_handler = None ASGIApp = None -__version__ = '3.9.3' +__version__ = '3.10.0' __all__ = ['__version__', 'Server', 'WSGIApp', 'Middleware', 'Client'] if AsyncServer is not None: # pragma: no cover diff --git a/py3/lib/python3.6/site-packages/engineio/asyncio_client.py b/py3/lib/python3.6/site-packages/engineio/asyncio_client.py index abaab3c..eb4cc9e 100644 --- a/py3/lib/python3.6/site-packages/engineio/asyncio_client.py +++ b/py3/lib/python3.6/site-packages/engineio/asyncio_client.py @@ -1,4 +1,5 @@ import asyncio +import ssl try: import aiohttp @@ -180,7 +181,7 @@ class AsyncClient(client.Client): self._reset() raise exceptions.ConnectionError( 'Connection refused by the server') - if r.status != 200: + if r.status < 200 or r.status >= 300: raise exceptions.ConnectionError( 'Unexpected status code {} in server response'.format( r.status)) @@ -248,9 +249,17 @@ class AsyncClient(client.Client): headers['Cookie'] = cookies try: - ws = await websockets.connect( - websocket_url + self._get_url_timestamp(), - extra_headers=headers) + if not self.ssl_verify: + ssl_context = ssl.create_default_context() + ssl_context.check_hostname = False + ssl_context.verify_mode = ssl.CERT_NONE + ws = await websockets.connect( + websocket_url + self._get_url_timestamp(), + extra_headers=headers, ssl=ssl_context) + else: + ws = await websockets.connect( + websocket_url + self._get_url_timestamp(), + extra_headers=headers) except (websockets.exceptions.InvalidURI, websockets.exceptions.InvalidHandshake, OSError): @@ -357,10 +366,17 @@ class AsyncClient(client.Client): if self.http is None or self.http.closed: self.http = aiohttp.ClientSession() http_method = getattr(self.http, method.lower()) + try: - return await http_method( - url, headers=headers, data=body, - timeout=aiohttp.ClientTimeout(total=timeout)) + if not self.ssl_verify: + return await http_method( + url, headers=headers, data=body, + timeout=aiohttp.ClientTimeout(total=timeout), ssl=False) + else: + return await http_method( + url, headers=headers, data=body, + timeout=aiohttp.ClientTimeout(total=timeout)) + except (aiohttp.ClientError, asyncio.TimeoutError) as exc: self.logger.info('HTTP %s request to %s failed with error %s.', method, url, exc) @@ -439,7 +455,7 @@ class AsyncClient(client.Client): 'Connection refused by the server, aborting') await self.queue.put(None) break - if r.status != 200: + if r.status < 200 or r.status >= 300: self.logger.warning('Unexpected status code %s in server ' 'response, aborting', r.status) await self.queue.put(None) @@ -547,7 +563,7 @@ class AsyncClient(client.Client): self.logger.warning( 'Connection refused by the server, aborting') break - if r.status != 200: + if r.status < 200 or r.status >= 300: self.logger.warning('Unexpected status code %s in server ' 'response, aborting', r.status) self._reset() diff --git a/py3/lib/python3.6/site-packages/engineio/asyncio_server.py b/py3/lib/python3.6/site-packages/engineio/asyncio_server.py index 5e203d2..4ae2612 100644 --- a/py3/lib/python3.6/site-packages/engineio/asyncio_server.py +++ b/py3/lib/python3.6/site-packages/engineio/asyncio_server.py @@ -27,7 +27,11 @@ class AsyncServer(server.Server): :param ping_timeout: The time in seconds that the client waits for the server to respond before disconnecting. :param ping_interval: The interval in seconds at which the client pings - the server. + the server. The default is 25 seconds. For advanced + control, a two element tuple can be given, where + the first number is the ping interval and the second + is a grace period added by the server. The default + grace period is 5 seconds. :param max_http_buffer_size: The maximum size of a message when using the polling transport. :param allow_upgrades: Whether to allow transport upgrades or not. diff --git a/py3/lib/python3.6/site-packages/engineio/asyncio_socket.py b/py3/lib/python3.6/site-packages/engineio/asyncio_socket.py index c4afcfe..7057a6c 100644 --- a/py3/lib/python3.6/site-packages/engineio/asyncio_socket.py +++ b/py3/lib/python3.6/site-packages/engineio/asyncio_socket.py @@ -54,7 +54,8 @@ class AsyncSocket(socket.Socket): """ if self.closed: raise exceptions.SocketIsClosedError() - if time.time() - self.last_ping > self.server.ping_interval + 5: + if time.time() - self.last_ping > self.server.ping_interval + \ + self.server.ping_interval_grace_period: self.server.logger.info('%s: Client is gone, closing socket', self.sid) # Passing abort=False here will cause close() to write a diff --git a/py3/lib/python3.6/site-packages/engineio/client.py b/py3/lib/python3.6/site-packages/engineio/client.py index 192e924..a105310 100644 --- a/py3/lib/python3.6/site-packages/engineio/client.py +++ b/py3/lib/python3.6/site-packages/engineio/client.py @@ -4,6 +4,7 @@ try: except ImportError: # pragma: no cover import Queue as queue import signal +import ssl import threading import time @@ -38,7 +39,11 @@ def signal_handler(sig, frame): client.start_background_task(client.disconnect, abort=True) else: client.disconnect(abort=True) - return original_signal_handler(sig, frame) + if callable(original_signal_handler): + return original_signal_handler(sig, frame) + else: # pragma: no cover + # Handle case where no original SIGINT handler was present. + return signal.def_int_handler(sig, frame) original_signal_handler = signal.signal(signal.SIGINT, signal_handler) @@ -59,10 +64,18 @@ class Client(object): versions. :param request_timeout: A timeout in seconds for requests. The default is 5 seconds. + :param ssl_verify: ``True`` if SSL connections should be fully verified or + ``False`` to skip SSL certificate verification allowing + connection to server with self signed certificates. The + default is ``True`` """ event_names = ['connect', 'disconnect', 'message'] - def __init__(self, logger=False, json=None, request_timeout=5): + def __init__(self, + logger=False, + json=None, + request_timeout=5, + ssl_verify=True): self.handlers = {} self.base_url = None self.transports = None @@ -80,6 +93,7 @@ class Client(object): self.ping_loop_event = self.create_event() self.queue = None self.state = 'disconnected' + self.ssl_verify = ssl_verify if json is not None: packet.Packet.json = json @@ -274,7 +288,7 @@ class Client(object): self._reset() raise exceptions.ConnectionError( 'Connection refused by the server') - if r.status_code != 200: + if r.status_code < 200 or r.status_code >= 300: raise exceptions.ConnectionError( 'Unexpected status code {} in server response'.format( r.status_code)) @@ -340,10 +354,16 @@ class Client(object): if self.http: cookies = '; '.join(["{}={}".format(cookie.name, cookie.value) for cookie in self.http.cookies]) + try: - ws = websocket.create_connection( - websocket_url + self._get_url_timestamp(), header=headers, - cookie=cookies) + if not self.ssl_verify: + ws = websocket.create_connection( + websocket_url + self._get_url_timestamp(), header=headers, + cookie=cookies, sslopt={"cert_reqs": ssl.CERT_NONE}) + else: + ws = websocket.create_connection( + websocket_url + self._get_url_timestamp(), header=headers, + cookie=cookies) except ConnectionError: if upgrade: self.logger.warning( @@ -448,7 +468,7 @@ class Client(object): self.http = requests.Session() try: return self.http.request(method, url, headers=headers, data=body, - timeout=timeout) + timeout=timeout, verify=self.ssl_verify) except requests.exceptions.RequestException as exc: self.logger.info('HTTP %s request to %s failed with error %s.', method, url, exc) @@ -522,7 +542,7 @@ class Client(object): 'Connection refused by the server, aborting') self.queue.put(None) break - if r.status_code != 200: + if r.status_code < 200 or r.status_code >= 300: self.logger.warning('Unexpected status code %s in server ' 'response, aborting', r.status_code) self.queue.put(None) @@ -629,7 +649,7 @@ class Client(object): self.logger.warning( 'Connection refused by the server, aborting') break - if r.status_code != 200: + if r.status_code < 200 or r.status_code >= 300: self.logger.warning('Unexpected status code %s in server ' 'response, aborting', r.status_code) self._reset() diff --git a/py3/lib/python3.6/site-packages/engineio/payload.py b/py3/lib/python3.6/site-packages/engineio/payload.py index cfff557..fbf9cbd 100644 --- a/py3/lib/python3.6/site-packages/engineio/payload.py +++ b/py3/lib/python3.6/site-packages/engineio/payload.py @@ -7,6 +7,8 @@ from six.moves import urllib class Payload(object): """Engine.IO payload.""" + max_decode_packets = 16 + def __init__(self, packets=None, encoded_payload=None): self.packets = packets or [] if encoded_payload is not None: @@ -42,39 +44,38 @@ class Payload(object): def decode(self, encoded_payload): """Decode a transmitted payload.""" self.packets = [] - while encoded_payload: - # JSONP POST payload starts with 'd=' - if encoded_payload.startswith(b'd='): - encoded_payload = urllib.parse.parse_qs( - encoded_payload)[b'd'][0] - if six.byte2int(encoded_payload[0:1]) <= 1: + if len(encoded_payload) == 0: + return + + # JSONP POST payload starts with 'd=' + if encoded_payload.startswith(b'd='): + encoded_payload = urllib.parse.parse_qs( + encoded_payload)[b'd'][0] + + i = 0 + if six.byte2int(encoded_payload[0:1]) <= 1: + # binary encoding + while i < len(encoded_payload): + if len(self.packets) >= self.max_decode_packets: + raise ValueError('Too many packets in payload') packet_len = 0 - i = 1 + i += 1 while six.byte2int(encoded_payload[i:i + 1]) != 255: packet_len = packet_len * 10 + six.byte2int( encoded_payload[i:i + 1]) i += 1 self.packets.append(packet.Packet( encoded_packet=encoded_payload[i + 1:i + 1 + packet_len])) - else: - i = encoded_payload.find(b':') - if i == -1: - raise ValueError('invalid payload') - - # extracting the packet out of the payload is extremely - # inefficient, because the payload needs to be treated as - # binary, but the non-binary packets have to be parsed as - # unicode. Luckily this complication only applies to long - # polling, as the websocket transport sends packets - # individually wrapped. - packet_len = int(encoded_payload[0:i]) - pkt = encoded_payload.decode('utf-8', errors='ignore')[ - i + 1: i + 1 + packet_len].encode('utf-8') + i += packet_len + 1 + else: + # assume text encoding + encoded_payload = encoded_payload.decode('utf-8') + while i < len(encoded_payload): + if len(self.packets) >= self.max_decode_packets: + raise ValueError('Too many packets in payload') + j = encoded_payload.find(':', i) + packet_len = int(encoded_payload[i:j]) + pkt = encoded_payload[j + 1:j + 1 + packet_len] self.packets.append(packet.Packet(encoded_packet=pkt)) - - # the engine.io protocol sends the packet length in - # utf-8 characters, but we need it in bytes to be able to - # jump to the next packet in the payload - packet_len = len(pkt) - encoded_payload = encoded_payload[i + 1 + packet_len:] + i = j + 1 + packet_len diff --git a/py3/lib/python3.6/site-packages/engineio/server.py b/py3/lib/python3.6/site-packages/engineio/server.py index 24c5ded..b34fd01 100644 --- a/py3/lib/python3.6/site-packages/engineio/server.py +++ b/py3/lib/python3.6/site-packages/engineio/server.py @@ -33,7 +33,11 @@ class Server(object): server to respond before disconnecting. The default is 60 seconds. :param ping_interval: The interval in seconds at which the client pings - the server. The default is 25 seconds. + the server. The default is 25 seconds. For advanced + control, a two element tuple can be given, where + the first number is the ping interval and the second + is a grace period added by the server. The default + grace period is 5 seconds. :param max_http_buffer_size: The maximum size of a message when using the polling transport. The default is 100,000,000 bytes. @@ -83,7 +87,12 @@ class Server(object): cors_credentials=True, logger=False, json=None, async_handlers=True, monitor_clients=None, **kwargs): self.ping_timeout = ping_timeout - self.ping_interval = ping_interval + if isinstance(ping_interval, tuple): + self.ping_interval = ping_interval[0] + self.ping_interval_grace_period = ping_interval[1] + else: + self.ping_interval = ping_interval + self.ping_interval_grace_period = 5 self.max_http_buffer_size = max_http_buffer_size self.allow_upgrades = allow_upgrades self.http_compression = http_compression @@ -643,7 +652,7 @@ class Server(object): continue # go through the entire client list in a ping interval cycle - sleep_interval = self.ping_timeout / len(self.sockets) + sleep_interval = float(self.ping_timeout) / len(self.sockets) try: # iterate over the current clients diff --git a/py3/lib/python3.6/site-packages/engineio/socket.py b/py3/lib/python3.6/site-packages/engineio/socket.py index 495088a..38593e7 100644 --- a/py3/lib/python3.6/site-packages/engineio/socket.py +++ b/py3/lib/python3.6/site-packages/engineio/socket.py @@ -70,7 +70,8 @@ class Socket(object): """ if self.closed: raise exceptions.SocketIsClosedError() - if time.time() - self.last_ping > self.server.ping_interval + 5: + if time.time() - self.last_ping > self.server.ping_interval + \ + self.server.ping_interval_grace_period: self.server.logger.info('%s: Client is gone, closing socket', self.sid) # Passing abort=False here will cause close() to write a diff --git a/py3/lib/python3.6/site-packages/python_engineio-3.9.3.dist-info/INSTALLER b/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/INSTALLER similarity index 100% rename from py3/lib/python3.6/site-packages/python_engineio-3.9.3.dist-info/INSTALLER rename to py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/INSTALLER diff --git a/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/LICENSE b/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/LICENSE new file mode 100755 index 0000000..b5083a5 --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Timothy Edmund Crosley + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/METADATA b/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/METADATA new file mode 100644 index 0000000..fbc7f6c --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/METADATA @@ -0,0 +1,697 @@ +Metadata-Version: 2.1 +Name: isort +Version: 4.3.21 +Summary: A Python utility / library to sort Python imports. +Home-page: https://github.com/timothycrosley/isort +Author: Timothy Crosley +Author-email: timothy.crosley@gmail.com +License: MIT +Keywords: Refactor,Python,Python2,Python3,Refactoring,Imports,Sort,Clean +Platform: UNKNOWN +Classifier: Development Status :: 6 - Mature +Classifier: Intended Audience :: Developers +Classifier: Natural Language :: English +Classifier: Environment :: Console +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Utilities +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* +Requires-Dist: futures ; python_version < "3.2" +Requires-Dist: backports.functools-lru-cache ; python_version < "3.2" +Provides-Extra: pipfile +Requires-Dist: pipreqs ; extra == 'pipfile' +Requires-Dist: requirementslib ; extra == 'pipfile' +Provides-Extra: pyproject +Requires-Dist: toml ; extra == 'pyproject' +Provides-Extra: requirements +Requires-Dist: pipreqs ; extra == 'requirements' +Requires-Dist: pip-api ; extra == 'requirements' +Provides-Extra: xdg_home +Requires-Dist: appdirs (>=1.4.0) ; extra == 'xdg_home' + +.. image:: https://raw.github.com/timothycrosley/isort/master/logo.png + :alt: isort + +######## + +.. image:: https://badge.fury.io/py/isort.svg + :target: https://badge.fury.io/py/isort + :alt: PyPI version + +.. image:: https://travis-ci.org/timothycrosley/isort.svg?branch=master + :target: https://travis-ci.org/timothycrosley/isort + :alt: Build Status + + +.. image:: https://coveralls.io/repos/timothycrosley/isort/badge.svg?branch=release%2F2.6.0&service=github + :target: https://coveralls.io/github/timothycrosley/isort?branch=release%2F2.6.0 + :alt: Coverage + +.. image:: https://img.shields.io/github/license/mashape/apistatus.svg + :target: https://pypi.org/project/hug/ + :alt: License + +.. image:: https://badges.gitter.im/Join%20Chat.svg + :alt: Join the chat at https://gitter.im/timothycrosley/isort + :target: https://gitter.im/timothycrosley/isort?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge + +.. image:: https://pepy.tech/badge/isort + :alt: Downloads + :target: https://pepy.tech/project/isort + +isort your python imports for you so you don't have to. + +isort is a Python utility / library to sort imports alphabetically, and automatically separated into sections. +It provides a command line utility, Python library and `plugins for various editors `_ to quickly sort all your imports. +It currently cleanly supports Python 2.7 and 3.4+ without any dependencies. + +.. image:: https://raw.github.com/timothycrosley/isort/develop/example.gif + :alt: Example Usage + +Before isort: + +.. code-block:: python + + from my_lib import Object + + print("Hey") + + import os + + from my_lib import Object3 + + from my_lib import Object2 + + import sys + + from third_party import lib15, lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14 + + import sys + + from __future__ import absolute_import + + from third_party import lib3 + + print("yo") + +After isort: + +.. code-block:: python + + from __future__ import absolute_import + + import os + import sys + + from third_party import (lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, + lib9, lib10, lib11, lib12, lib13, lib14, lib15) + + from my_lib import Object, Object2, Object3 + + print("Hey") + print("yo") + +Installing isort +================ + +Installing isort is as simple as: + +.. code-block:: bash + + pip install isort + +Install isort with requirements.txt support: + +.. code-block:: bash + + pip install isort[requirements] + +Install isort with Pipfile support: + +.. code-block:: bash + + pip install isort[pipfile] + +Install isort with both formats support: + +.. code-block:: bash + + pip install isort[requirements,pipfile] + +Using isort +=========== + +**From the command line**: + +.. code-block:: bash + + isort mypythonfile.py mypythonfile2.py + +or recursively: + +.. code-block:: bash + + isort -rc . + +*which is equivalent to:* + +.. code-block:: bash + + isort **/*.py + +or to see the proposed changes without applying them: + +.. code-block:: bash + + isort mypythonfile.py --diff + +Finally, to atomically run isort against a project, only applying changes if they don't introduce syntax errors do: + +.. code-block:: bash + + isort -rc --atomic . + +(Note: this is disabled by default as it keeps isort from being able to run against code written using a different version of Python) + +**From within Python**: + +.. code-block:: bash + + from isort import SortImports + + SortImports("pythonfile.py") + +or: + +.. code-block:: bash + + from isort import SortImports + + new_contents = SortImports(file_contents=old_contents).output + +**From within Kate:** + +.. code-block:: bash + + ctrl+[ + +or: + +.. code-block:: bash + + menu > Python > Sort Imports + +Installing isort's Kate plugin +============================== + +For KDE 4.13+ / Pate 2.0+: + +.. code-block:: bash + + wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/isort_plugin.py --output-document ~/.kde/share/apps/kate/pate/isort_plugin.py + wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/isort_plugin_ui.rc --output-document ~/.kde/share/apps/kate/pate/isort_plugin_ui.rc + wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/katepart_isort.desktop --output-document ~/.kde/share/kde4/services/katepart_isort.desktop + +For all older versions: + +.. code-block:: bash + + wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/isort_plugin_old.py --output-document ~/.kde/share/apps/kate/pate/isort_plugin.py + +You will then need to restart kate and enable Python Plugins as well as the isort plugin itself. + +Installing isort's for your preferred text editor +================================================= + +Several plugins have been written that enable to use isort from within a variety of text-editors. +You can find a full list of them `on the isort wiki `_. +Additionally, I will enthusiastically accept pull requests that include plugins for other text editors +and add documentation for them as I am notified. + +How does isort work? +==================== + +isort parses specified files for global level import lines (imports outside of try / except blocks, functions, etc..) +and puts them all at the top of the file grouped together by the type of import: + +- Future +- Python Standard Library +- Third Party +- Current Python Project +- Explicitly Local (. before import, as in: ``from . import x``) +- Custom Separate Sections (Defined by forced_separate list in configuration file) +- Custom Sections (Defined by sections list in configuration file) + +Inside of each section the imports are sorted alphabetically. isort automatically removes duplicate python imports, +and wraps long from imports to the specified line length (defaults to 79). + +When will isort not work? +========================= + +If you ever have the situation where you need to have a try / except block in the middle of top-level imports or if +your import order is directly linked to precedence. + +For example: a common practice in Django settings files is importing * from various settings files to form +a new settings file. In this case if any of the imports change order you are changing the settings definition itself. + +However, you can configure isort to skip over just these files - or even to force certain imports to the top. + +Configuring isort +================= + +If you find the default isort settings do not work well for your project, isort provides several ways to adjust +the behavior. + +To configure isort for a single user create a ``~/.isort.cfg`` or ``$XDG_CONFIG_HOME/isort.cfg`` file: + +.. code-block:: ini + + [settings] + line_length=120 + force_to_top=file1.py,file2.py + skip=file3.py,file4.py + known_future_library=future,pies + known_standard_library=std,std2 + known_third_party=randomthirdparty + known_first_party=mylib1,mylib2 + indent=' ' + multi_line_output=3 + length_sort=1 + forced_separate=django.contrib,django.utils + default_section=FIRSTPARTY + no_lines_before=LOCALFOLDER + +Additionally, you can specify project level configuration simply by placing a ``.isort.cfg`` file at the root of your +project. isort will look up to 25 directories up, from the file it is ran against, to find a project specific configuration. + +Or, if you prefer, you can add an ``isort`` or ``tool:isort`` section to your project's ``setup.cfg`` or ``tox.ini`` file with any desired settings. + +You can also add your desired settings under a ``[tool.isort]`` section in your ``pyproject.toml`` file. + +You can then override any of these settings by using command line arguments, or by passing in override values to the +SortImports class. + +Finally, as of version 3.0 isort supports editorconfig files using the standard syntax defined here: +https://editorconfig.org/ + +Meaning you place any standard isort configuration parameters within a .editorconfig file under the ``*.py`` section +and they will be honored. + +For a full list of isort settings and their meanings `take a look at the isort wiki `_. + +Multi line output modes +======================= + +You will notice above the "multi_line_output" setting. This setting defines how from imports wrap when they extend +past the line_length limit and has 6 possible settings: + +**0 - Grid** + +.. code-block:: python + + from third_party import (lib1, lib2, lib3, + lib4, lib5, ...) + +**1 - Vertical** + +.. code-block:: python + + from third_party import (lib1, + lib2, + lib3 + lib4, + lib5, + ...) + +**2 - Hanging Indent** + +.. code-block:: python + + from third_party import \ + lib1, lib2, lib3, \ + lib4, lib5, lib6 + +**3 - Vertical Hanging Indent** + +.. code-block:: python + + from third_party import ( + lib1, + lib2, + lib3, + lib4, + ) + +**4 - Hanging Grid** + +.. code-block:: python + + from third_party import ( + lib1, lib2, lib3, lib4, + lib5, ...) + +**5 - Hanging Grid Grouped** + +.. code-block:: python + + from third_party import ( + lib1, lib2, lib3, lib4, + lib5, ... + ) + +**6 - Hanging Grid Grouped, No Trailing Comma** + +In Mode 5 isort leaves a single extra space to maintain consistency of output when a comma is added at the end. +Mode 6 is the same - except that no extra space is maintained leading to the possibility of lines one character longer. +You can enforce a trailing comma by using this in conjunction with `-tc` or `trailing_comma: True`. + +.. code-block:: python + + from third_party import ( + lib1, lib2, lib3, lib4, + lib5 + ) + +**7 - NOQA** + +.. code-block:: python + + from third_party import lib1, lib2, lib3, ... # NOQA + +Alternatively, you can set ``force_single_line`` to ``True`` (``-sl`` on the command line) and every import will appear on its +own line: + +.. code-block:: python + + from third_party import lib1 + from third_party import lib2 + from third_party import lib3 + ... + +Note: to change the how constant indents appear - simply change the indent property with the following accepted formats: + +* Number of spaces you would like. For example: 4 would cause standard 4 space indentation. +* Tab +* A verbatim string with quotes around it. + +For example: + +.. code-block:: python + + " " + +is equivalent to 4. + +For the import styles that use parentheses, you can control whether or not to +include a trailing comma after the last import with the ``include_trailing_comma`` +option (defaults to ``False``). + +Intelligently Balanced Multi-line Imports +========================================= + +As of isort 3.1.0 support for balanced multi-line imports has been added. +With this enabled isort will dynamically change the import length to the one that produces the most balanced grid, +while staying below the maximum import length defined. + +Example: + +.. code-block:: python + + from __future__ import (absolute_import, division, + print_function, unicode_literals) + +Will be produced instead of: + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function, + unicode_literals) + +To enable this set ``balanced_wrapping`` to ``True`` in your config or pass the ``-e`` option into the command line utility. + +Custom Sections and Ordering +============================ + +You can change the section order with ``sections`` option from the default of: + +.. code-block:: ini + + FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER + +to your preference: + +.. code-block:: ini + + sections=FUTURE,STDLIB,FIRSTPARTY,THIRDPARTY,LOCALFOLDER + +You also can define your own sections and their order. + +Example: + +.. code-block:: ini + + known_django=django + known_pandas=pandas,numpy + sections=FUTURE,STDLIB,DJANGO,THIRDPARTY,PANDAS,FIRSTPARTY,LOCALFOLDER + +would create two new sections with the specified known modules. + +The ``no_lines_before`` option will prevent the listed sections from being split from the previous section by an empty line. + +Example: + +.. code-block:: ini + + sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER + no_lines_before=LOCALFOLDER + +would produce a section with both FIRSTPARTY and LOCALFOLDER modules combined. + +Auto-comment import sections +============================ + +Some projects prefer to have import sections uniquely titled to aid in identifying the sections quickly +when visually scanning. isort can automate this as well. To do this simply set the ``import_heading_{section_name}`` +setting for each section you wish to have auto commented - to the desired comment. + +For Example: + +.. code-block:: ini + + import_heading_stdlib=Standard Library + import_heading_firstparty=My Stuff + +Would lead to output looking like the following: + +.. code-block:: python + + # Standard Library + import os + import sys + + import django.settings + + # My Stuff + import myproject.test + +Ordering by import length +========================= + +isort also makes it easy to sort your imports by length, simply by setting the ``length_sort`` option to ``True``. +This will result in the following output style: + +.. code-block:: python + + from evn.util import ( + Pool, + Dict, + Options, + Constant, + DecayDict, + UnexpectedCodePath, + ) + +It is also possible to opt-in to sorting imports by length for only specific +sections by using ``length_sort_`` followed by the section name as a +configuration item, e.g.:: + + length_sort_stdlib=1 + +Skip processing of imports (outside of configuration) +===================================================== + +To make isort ignore a single import simply add a comment at the end of the import line containing the text ``isort:skip``: + +.. code-block:: python + + import module # isort:skip + +or: + +.. code-block:: python + + from xyz import (abc, # isort:skip + yo, + hey) + +To make isort skip an entire file simply add ``isort:skip_file`` to the module's doc string: + +.. code-block:: python + + """ my_module.py + Best module ever + + isort:skip_file + """ + + import b + import a + +Adding an import to multiple files +================================== + +isort makes it easy to add an import statement across multiple files, while being assured it's correctly placed. + +From the command line: + +.. code-block:: bash + + isort -a "from __future__ import print_function" *.py + +from within Kate: + +.. code-block:: + + ctrl+] + +or: + +.. code-block:: + + menu > Python > Add Import + +Removing an import from multiple files +====================================== + +isort also makes it easy to remove an import from multiple files, without having to be concerned with how it was originally +formatted. + +From the command line: + +.. code-block:: bash + + isort -rm "os.system" *.py + +from within Kate: + +.. code-block:: + + ctrl+shift+] + +or: + +.. code-block:: + + menu > Python > Remove Import + +Using isort to verify code +========================== + +The ``--check-only`` option +--------------------------- + +isort can also be used to used to verify that code is correctly formatted by running it with ``-c``. +Any files that contain incorrectly sorted and/or formatted imports will be outputted to ``stderr``. + +.. code-block:: bash + + isort **/*.py -c -vb + + SUCCESS: /home/timothy/Projects/Open_Source/isort/isort_kate_plugin.py Everything Looks Good! + ERROR: /home/timothy/Projects/Open_Source/isort/isort/isort.py Imports are incorrectly sorted. + +One great place this can be used is with a pre-commit git hook, such as this one by @acdha: + +https://gist.github.com/acdha/8717683 + +This can help to ensure a certain level of code quality throughout a project. + + +Git hook +-------- + +isort provides a hook function that can be integrated into your Git pre-commit script to check +Python code before committing. + +To cause the commit to fail if there are isort errors (strict mode), include the following in +``.git/hooks/pre-commit``: + +.. code-block:: python + + #!/usr/bin/env python + import sys + from isort.hooks import git_hook + + sys.exit(git_hook(strict=True, modify=True)) + +If you just want to display warnings, but allow the commit to happen anyway, call ``git_hook`` without +the `strict` parameter. If you want to display warnings, but not also fix the code, call ``git_hook`` without +the `modify` parameter. + +Setuptools integration +---------------------- + +Upon installation, isort enables a ``setuptools`` command that checks Python files +declared by your project. + +Running ``python setup.py isort`` on the command line will check the files +listed in your ``py_modules`` and ``packages``. If any warning is found, +the command will exit with an error code: + +.. code-block:: bash + + $ python setup.py isort + +Also, to allow users to be able to use the command without having to install +isort themselves, add isort to the setup_requires of your ``setup()`` like so: + +.. code-block:: python + + setup( + name="project", + packages=["project"], + + setup_requires=[ + "isort" + ] + ) + + +Why isort? +========== + +isort simply stands for import sort. It was originally called "sortImports" however I got tired of typing the extra +characters and came to the realization camelCase is not pythonic. + +I wrote isort because in an organization I used to work in the manager came in one day and decided all code must +have alphabetically sorted imports. The code base was huge - and he meant for us to do it by hand. However, being a +programmer - I'm too lazy to spend 8 hours mindlessly performing a function, but not too lazy to spend 16 +hours automating it. I was given permission to open source sortImports and here we are :) + +-------------------------------------------- + +Thanks and I hope you find isort useful! + +~Timothy Crosley + + diff --git a/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/RECORD b/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/RECORD new file mode 100644 index 0000000..93fb83d --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/RECORD @@ -0,0 +1,30 @@ +isort/__init__.py,sha256=_DTTMASePJCqsKnRJPf_YgFv5ZJOHg1uPLkrQHcqA2c,1380 +isort/__main__.py,sha256=9tThPqyOnY86bHaxJ0WciTd-rfKN3O-PQoNGBO2xhio,205 +isort/finders.py,sha256=0w39ygCFuOv40OHixflrOv_Xna8K78usa5ySwS9GkWE,13185 +isort/hooks.py,sha256=GcyPMF7raq3B1z4ubbzIWoMiY5DePDni0Nct5U87uMQ,3230 +isort/isort.py,sha256=krLW0QgwnVjUD3hYTpQmWkMa5TDEZxx6AbX80vlVNoA,53910 +isort/main.py,sha256=rS7dAu_0T-8Jxi3sDWu00IOjt4j0r3vJi6bXZn6RnQg,21974 +isort/natural.py,sha256=hlcWsGKfIUC4Atjp5IIqDCmg1madY6ave9oNiTGjJ0Q,1794 +isort/pie_slice.py,sha256=hO6l1XocvGAd8XTR8526r-G7XIncUQB53_DHQ4AZEYI,5612 +isort/pylama_isort.py,sha256=wF6NOEVuibme0l-5pH9pCW1j4vGaFamuwll494TnzDI,785 +isort/settings.py,sha256=4_Jf-9GaBy9fi6UJctLqesIAMAegWekRIJdJmH5TBNE,17452 +isort/utils.py,sha256=KtazEoeX9XmtcrUGP6xl5lBX7Ye2N08ACGaWxiGcIaE,1344 +isort-4.3.21.dist-info/LICENSE,sha256=BjKUABw9Uj26y6ud1UrCKZgnVsyvWSylMkCysM3YIGU,1089 +isort-4.3.21.dist-info/METADATA,sha256=8fY1DuLOn_UnCH58A8AcsCUZpYWeLCsQF-n-GIXlxOM,19749 +isort-4.3.21.dist-info/WHEEL,sha256=h_aVn5OB2IERUjMbi2pucmR_zzWJtk303YXvhh60NJ8,110 +isort-4.3.21.dist-info/entry_points.txt,sha256=2M99eSFpnteDm3ekW8jya2a3A0-vFntKdT1fP93Tyks,148 +isort-4.3.21.dist-info/top_level.txt,sha256=mrBLoVpJnQWBbnMOSdzkjN1E9Z-e3Zd-MRlo88bstUk,6 +isort-4.3.21.dist-info/RECORD,, +../../../bin/isort,sha256=vnaBGzysKtdqYDdoR_7R4aaYHjJQghK_5ckLLbfr3rU,236 +isort-4.3.21.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +isort/__pycache__/natural.cpython-36.pyc,, +isort/__pycache__/isort.cpython-36.pyc,, +isort/__pycache__/pie_slice.cpython-36.pyc,, +isort/__pycache__/pylama_isort.cpython-36.pyc,, +isort/__pycache__/__main__.cpython-36.pyc,, +isort/__pycache__/__init__.cpython-36.pyc,, +isort/__pycache__/finders.cpython-36.pyc,, +isort/__pycache__/utils.cpython-36.pyc,, +isort/__pycache__/main.cpython-36.pyc,, +isort/__pycache__/hooks.cpython-36.pyc,, +isort/__pycache__/settings.cpython-36.pyc,, diff --git a/py3/lib/python3.6/site-packages/python_engineio-3.9.3.dist-info/WHEEL b/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/WHEEL similarity index 100% rename from py3/lib/python3.6/site-packages/python_engineio-3.9.3.dist-info/WHEEL rename to py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/WHEEL diff --git a/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/entry_points.txt b/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/entry_points.txt new file mode 100644 index 0000000..3a77a18 --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/entry_points.txt @@ -0,0 +1,9 @@ +[console_scripts] +isort = isort.main:main + +[distutils.commands] +isort = isort.main:ISortCommand + +[pylama.linter] +isort = isort.pylama_isort:Linter + diff --git a/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/top_level.txt b/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/top_level.txt new file mode 100644 index 0000000..2a79243 --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort-4.3.21.dist-info/top_level.txt @@ -0,0 +1 @@ +isort diff --git a/py3/lib/python3.6/site-packages/isort/__init__.py b/py3/lib/python3.6/site-packages/isort/__init__.py new file mode 100644 index 0000000..9a0a073 --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort/__init__.py @@ -0,0 +1,28 @@ +"""__init__.py. + +Defines the isort module to include the SortImports utility class as well as any defined settings. + +Copyright (C) 2013 Timothy Edmund Crosley + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +""" + +from __future__ import absolute_import, division, print_function, unicode_literals + +from . import settings # noqa: F401 +from .isort import SortImports # noqa: F401 + +__version__ = "4.3.21" diff --git a/py3/lib/python3.6/site-packages/isort/__main__.py b/py3/lib/python3.6/site-packages/isort/__main__.py new file mode 100644 index 0000000..91cc154 --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort/__main__.py @@ -0,0 +1,9 @@ +from __future__ import absolute_import + +from isort.pie_slice import apply_changes_to_python_environment + +apply_changes_to_python_environment() + +from isort.main import main # noqa: E402 isort:skip + +main() diff --git a/py3/lib/python3.6/site-packages/isort/finders.py b/py3/lib/python3.6/site-packages/isort/finders.py new file mode 100644 index 0000000..225bd12 --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort/finders.py @@ -0,0 +1,382 @@ +"""Finders try to find right section for passed module name +""" +from __future__ import absolute_import, division, print_function, unicode_literals + +import inspect +import os +import os.path +import re +import sys +import sysconfig +from fnmatch import fnmatch +from glob import glob + +from .pie_slice import PY2 +from .utils import chdir, exists_case_sensitive + +try: + from pipreqs import pipreqs +except ImportError: + pipreqs = None + +try: + from pip_api import parse_requirements +except ImportError: + parse_requirements = None + +try: + from requirementslib import Pipfile +except ImportError: + Pipfile = None + +try: + from functools import lru_cache +except ImportError: + from backports.functools_lru_cache import lru_cache + + +KNOWN_SECTION_MAPPING = { + 'STDLIB': 'STANDARD_LIBRARY', + 'FUTURE': 'FUTURE_LIBRARY', + 'FIRSTPARTY': 'FIRST_PARTY', + 'THIRDPARTY': 'THIRD_PARTY', +} + + +class BaseFinder(object): + def __init__(self, config, sections): + self.config = config + self.sections = sections + + +class ForcedSeparateFinder(BaseFinder): + def find(self, module_name): + for forced_separate in self.config['forced_separate']: + # Ensure all forced_separate patterns will match to end of string + path_glob = forced_separate + if not forced_separate.endswith('*'): + path_glob = '%s*' % forced_separate + + if fnmatch(module_name, path_glob) or fnmatch(module_name, '.' + path_glob): + return forced_separate + + +class LocalFinder(BaseFinder): + def find(self, module_name): + if module_name.startswith("."): + return self.sections.LOCALFOLDER + + +class KnownPatternFinder(BaseFinder): + def __init__(self, config, sections): + super(KnownPatternFinder, self).__init__(config, sections) + + self.known_patterns = [] + for placement in reversed(self.sections): + known_placement = KNOWN_SECTION_MAPPING.get(placement, placement) + config_key = 'known_{0}'.format(known_placement.lower()) + known_patterns = self.config.get(config_key, []) + known_patterns = [ + pattern + for known_pattern in known_patterns + for pattern in self._parse_known_pattern(known_pattern) + ] + for known_pattern in known_patterns: + regexp = '^' + known_pattern.replace('*', '.*').replace('?', '.?') + '$' + self.known_patterns.append((re.compile(regexp), placement)) + + @staticmethod + def _is_package(path): + """ + Evaluates if path is a python package + """ + if PY2: + return os.path.exists(os.path.join(path, '__init__.py')) + else: + return os.path.isdir(path) + + def _parse_known_pattern(self, pattern): + """ + Expand pattern if identified as a directory and return found sub packages + """ + if pattern.endswith(os.path.sep): + patterns = [ + filename + for filename in os.listdir(pattern) + if self._is_package(os.path.join(pattern, filename)) + ] + else: + patterns = [pattern] + + return patterns + + def find(self, module_name): + # Try to find most specific placement instruction match (if any) + parts = module_name.split('.') + module_names_to_check = ('.'.join(parts[:first_k]) for first_k in range(len(parts), 0, -1)) + for module_name_to_check in module_names_to_check: + for pattern, placement in self.known_patterns: + if pattern.match(module_name_to_check): + return placement + + +class PathFinder(BaseFinder): + def __init__(self, config, sections): + super(PathFinder, self).__init__(config, sections) + + # restore the original import path (i.e. not the path to bin/isort) + self.paths = [os.getcwd()] + + # virtual env + self.virtual_env = self.config.get('virtual_env') or os.environ.get('VIRTUAL_ENV') + if self.virtual_env: + self.virtual_env = os.path.realpath(self.virtual_env) + self.virtual_env_src = False + if self.virtual_env: + self.virtual_env_src = '{0}/src/'.format(self.virtual_env) + for path in glob('{0}/lib/python*/site-packages'.format(self.virtual_env)): + if path not in self.paths: + self.paths.append(path) + for path in glob('{0}/lib/python*/*/site-packages'.format(self.virtual_env)): + if path not in self.paths: + self.paths.append(path) + for path in glob('{0}/src/*'.format(self.virtual_env)): + if os.path.isdir(path): + self.paths.append(path) + + # conda + self.conda_env = self.config.get('conda_env') or os.environ.get('CONDA_PREFIX') + if self.conda_env: + self.conda_env = os.path.realpath(self.conda_env) + for path in glob('{0}/lib/python*/site-packages'.format(self.conda_env)): + if path not in self.paths: + self.paths.append(path) + for path in glob('{0}/lib/python*/*/site-packages'.format(self.conda_env)): + if path not in self.paths: + self.paths.append(path) + + # handle case-insensitive paths on windows + self.stdlib_lib_prefix = os.path.normcase(sysconfig.get_paths()['stdlib']) + if self.stdlib_lib_prefix not in self.paths: + self.paths.append(self.stdlib_lib_prefix) + + # handle compiled libraries + self.ext_suffix = sysconfig.get_config_var("EXT_SUFFIX") or ".so" + + # add system paths + for path in sys.path[1:]: + if path not in self.paths: + self.paths.append(path) + + def find(self, module_name): + for prefix in self.paths: + package_path = "/".join((prefix, module_name.split(".")[0])) + is_module = (exists_case_sensitive(package_path + ".py") or + exists_case_sensitive(package_path + ".so") or + exists_case_sensitive(package_path + self.ext_suffix) or + exists_case_sensitive(package_path + "/__init__.py")) + is_package = exists_case_sensitive(package_path) and os.path.isdir(package_path) + if is_module or is_package: + if 'site-packages' in prefix: + return self.sections.THIRDPARTY + if 'dist-packages' in prefix: + return self.sections.THIRDPARTY + if self.virtual_env and self.virtual_env_src in prefix: + return self.sections.THIRDPARTY + if self.conda_env and self.conda_env in prefix: + return self.sections.THIRDPARTY + if os.path.normcase(prefix).startswith(self.stdlib_lib_prefix): + return self.sections.STDLIB + return self.config['default_section'] + + +class ReqsBaseFinder(BaseFinder): + def __init__(self, config, sections, path='.'): + super(ReqsBaseFinder, self).__init__(config, sections) + self.path = path + if self.enabled: + self.mapping = self._load_mapping() + self.names = self._load_names() + + @staticmethod + def _load_mapping(): + """Return list of mappings `package_name -> module_name` + + Example: + django-haystack -> haystack + """ + if not pipreqs: + return + path = os.path.dirname(inspect.getfile(pipreqs)) + path = os.path.join(path, 'mapping') + with open(path) as f: + # pypi_name: import_name + return dict(line.strip().split(":")[::-1] for line in f) + + def _load_names(self): + """Return list of thirdparty modules from requirements + """ + names = [] + for path in self._get_files(): + for name in self._get_names(path): + names.append(self._normalize_name(name)) + return names + + @staticmethod + def _get_parents(path): + prev = '' + while path != prev: + prev = path + yield path + path = os.path.dirname(path) + + def _get_files(self): + """Return paths to all requirements files + """ + path = os.path.abspath(self.path) + if os.path.isfile(path): + path = os.path.dirname(path) + + for path in self._get_parents(path): + for file_path in self._get_files_from_dir(path): + yield file_path + + def _normalize_name(self, name): + """Convert package name to module name + + Examples: + Django -> django + django-haystack -> haystack + Flask-RESTFul -> flask_restful + """ + if self.mapping: + name = self.mapping.get(name, name) + return name.lower().replace('-', '_') + + def find(self, module_name): + # required lib not installed yet + if not self.enabled: + return + + module_name, _sep, _submodules = module_name.partition('.') + module_name = module_name.lower() + if not module_name: + return + + for name in self.names: + if module_name == name: + return self.sections.THIRDPARTY + + +class RequirementsFinder(ReqsBaseFinder): + exts = ('.txt', '.in') + enabled = bool(parse_requirements) + + def _get_files_from_dir(self, path): + """Return paths to requirements files from passed dir. + """ + return RequirementsFinder._get_files_from_dir_cached(path) + + @classmethod + @lru_cache(maxsize=16) + def _get_files_from_dir_cached(cls, path): + result = [] + + for fname in os.listdir(path): + if 'requirements' not in fname: + continue + full_path = os.path.join(path, fname) + + # *requirements*/*.{txt,in} + if os.path.isdir(full_path): + for subfile_name in os.listdir(path): + for ext in cls.exts: + if subfile_name.endswith(ext): + result.append(os.path.join(path, subfile_name)) + continue + + # *requirements*.{txt,in} + if os.path.isfile(full_path): + for ext in cls.exts: + if fname.endswith(ext): + result.append(full_path) + break + + return result + + def _get_names(self, path): + """Load required packages from path to requirements file + """ + return RequirementsFinder._get_names_cached(path) + + @classmethod + @lru_cache(maxsize=16) + def _get_names_cached(cls, path): + results = [] + + with chdir(os.path.dirname(path)): + requirements = parse_requirements(path) + for req in requirements.values(): + if req.name: + results.append(req.name) + + return results + + +class PipfileFinder(ReqsBaseFinder): + enabled = bool(Pipfile) + + def _get_names(self, path): + with chdir(path): + project = Pipfile.load(path) + for req in project.packages: + yield req.name + + def _get_files_from_dir(self, path): + if 'Pipfile' in os.listdir(path): + yield path + + +class DefaultFinder(BaseFinder): + def find(self, module_name): + return self.config['default_section'] + + +class FindersManager(object): + finders = ( + ForcedSeparateFinder, + LocalFinder, + KnownPatternFinder, + PathFinder, + PipfileFinder, + RequirementsFinder, + DefaultFinder, + ) + + def __init__(self, config, sections, finders=None): + self.verbose = config.get('verbose', False) + + finders = self.finders if finders is None else finders + self.finders = [] + for finder in finders: + try: + self.finders.append(finder(config, sections)) + except Exception as exception: + # if one finder fails to instantiate isort can continue using the rest + if self.verbose: + print('{} encountered an error ({}) during instantiation and cannot be used'.format(finder.__name__, + str(exception))) + self.finders = tuple(self.finders) + + def find(self, module_name): + for finder in self.finders: + try: + section = finder.find(module_name) + except Exception as exception: + # isort has to be able to keep trying to identify the correct import section even if one approach fails + if self.verbose: + print('{} encountered an error ({}) while trying to identify the {} module'.format(finder.__name__, + str(exception), + module_name)) + if section is not None: + return section diff --git a/py3/lib/python3.6/site-packages/isort/hooks.py b/py3/lib/python3.6/site-packages/isort/hooks.py new file mode 100644 index 0000000..16a16e1 --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort/hooks.py @@ -0,0 +1,91 @@ +"""isort.py. + +Defines a git hook to allow pre-commit warnings and errors about import order. + +usage: + exit_code = git_hook(strict=True|False, modify=True|False) + +Copyright (C) 2015 Helen Sherwood-Taylor + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +""" +import subprocess + +from isort import SortImports + + +def get_output(command): + """ + Run a command and return raw output + + :param str command: the command to run + :returns: the stdout output of the command + """ + return subprocess.check_output(command.split()) + + +def get_lines(command): + """ + Run a command and return lines of output + + :param str command: the command to run + :returns: list of whitespace-stripped lines output by command + """ + stdout = get_output(command) + return [line.strip().decode('utf-8') for line in stdout.splitlines()] + + +def git_hook(strict=False, modify=False): + """ + Git pre-commit hook to check staged files for isort errors + + :param bool strict - if True, return number of errors on exit, + causing the hook to fail. If False, return zero so it will + just act as a warning. + :param bool modify - if True, fix the sources if they are not + sorted properly. If False, only report result without + modifying anything. + + :return number of errors if in strict mode, 0 otherwise. + """ + + # Get list of files modified and staged + diff_cmd = "git diff-index --cached --name-only --diff-filter=ACMRTUXB HEAD" + files_modified = get_lines(diff_cmd) + + errors = 0 + for filename in files_modified: + if filename.endswith('.py'): + # Get the staged contents of the file + staged_cmd = "git show :%s" % filename + staged_contents = get_output(staged_cmd) + + sort = SortImports( + file_path=filename, + file_contents=staged_contents.decode(), + check=True + ) + + if sort.incorrectly_sorted: + errors += 1 + if modify: + SortImports( + file_path=filename, + file_contents=staged_contents.decode(), + check=False, + ) + + return errors if strict else 0 diff --git a/py3/lib/python3.6/site-packages/isort/isort.py b/py3/lib/python3.6/site-packages/isort/isort.py new file mode 100644 index 0000000..245e53f --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort/isort.py @@ -0,0 +1,1060 @@ +"""isort.py. + +Exposes a simple library to sort through imports within Python code + +usage: + SortImports(file_name) +or: + sorted = SortImports(file_contents=file_contents).output + +Copyright (C) 2013 Timothy Edmund Crosley + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +""" +from __future__ import absolute_import, division, print_function, unicode_literals + +import codecs +import copy +import io +import itertools +import os +import re +import sys +from collections import OrderedDict, namedtuple +from datetime import datetime +from difflib import unified_diff + +from . import settings +from .finders import FindersManager +from .natural import nsorted +from .pie_slice import input + + +class SortImports(object): + incorrectly_sorted = False + skipped = False + + def __init__(self, file_path=None, file_contents=None, file_=None, write_to_stdout=False, check=False, + show_diff=False, settings_path=None, ask_to_apply=False, run_path='', check_skip=True, + extension=None, **setting_overrides): + if not settings_path and file_path: + settings_path = os.path.dirname(os.path.abspath(file_path)) + settings_path = settings_path or os.getcwd() + + self.config = settings.from_path(settings_path).copy() + for key, value in setting_overrides.items(): + access_key = key.replace('not_', '').lower() + # The sections config needs to retain order and can't be converted to a set. + if access_key != 'sections' and type(self.config.get(access_key)) in (list, tuple): + if key.startswith('not_'): + self.config[access_key] = list(set(self.config[access_key]).difference(value)) + else: + self.config[access_key] = list(set(self.config[access_key]).union(value)) + else: + self.config[key] = value + + if self.config['force_alphabetical_sort']: + self.config.update({'force_alphabetical_sort_within_sections': True, + 'no_sections': True, + 'lines_between_types': 1, + 'from_first': True}) + + indent = str(self.config['indent']) + if indent.isdigit(): + indent = " " * int(indent) + else: + indent = indent.strip("'").strip('"') + if indent.lower() == "tab": + indent = "\t" + self.config['indent'] = indent + + self.config['comment_prefix'] = self.config['comment_prefix'].strip("'").strip('"') + + self.place_imports = {} + self.import_placements = {} + self.remove_imports = [self._format_simplified(removal) for removal in self.config['remove_imports']] + self.add_imports = [self._format_natural(addition) for addition in self.config['add_imports']] + self._section_comments = ["# " + value for key, value in self.config.items() if + key.startswith('import_heading') and value] + + self.file_encoding = 'utf-8' + file_name = file_path + self.file_path = file_path or "" + if file_path: + file_path = os.path.abspath(file_path) + if check_skip: + if run_path and file_path.startswith(run_path): + file_name = file_path.replace(run_path, '', 1) + else: + file_name = file_path + run_path = '' + + if settings.should_skip(file_name, self.config, run_path): + self.skipped = True + if self.config['verbose']: + print("WARNING: {0} was skipped as it's listed in 'skip' setting" + " or matches a glob in 'skip_glob' setting".format(file_path)) + file_contents = None + if not self.skipped and not file_contents: + with io.open(file_path, 'rb') as f: + file_encoding = coding_check(f) + with io.open(file_path, encoding=file_encoding, newline='') as file_to_import_sort: + try: + file_contents = file_to_import_sort.read() + self.file_path = file_path + self.file_encoding = file_encoding + encoding_success = True + except UnicodeDecodeError: + encoding_success = False + + if not encoding_success: + with io.open(file_path, newline='') as file_to_import_sort: + try: + file_contents = file_to_import_sort.read() + self.file_path = file_path + self.file_encoding = file_to_import_sort.encoding + except UnicodeDecodeError: + encoding_success = False + file_contents = None + self.skipped = True + if self.config['verbose']: + print("WARNING: {} was skipped as it couldn't be opened with the given " + "{} encoding or {} fallback encoding".format(file_path, + self.file_encoding, + file_to_import_sort.encoding)) + elif file_: + try: + file_.seek(0) + self.file_encoding = coding_check(file_) + file_.seek(0) + except (io.UnsupportedOperation, IOError): + pass + reader = codecs.getreader(self.file_encoding) + file_contents = reader(file_).read() + + # try to decode file_contents + if file_contents: + try: + basestring + # python 2 + need_decode = (str, bytes) + except NameError: + # python 3 + need_decode = bytes + + if isinstance(file_contents, need_decode): + file_contents = file_contents.decode(coding_check(file_contents.splitlines())) + + if file_contents is None or ("isort:" + "skip_file") in file_contents: + self.skipped = True + self.output = None + if write_to_stdout and file_contents: + sys.stdout.write(file_contents) + return + + if self.config['line_ending']: + self.line_separator = self.config['line_ending'] + else: + if '\r\n' in file_contents: + self.line_separator = '\r\n' + elif '\r' in file_contents: + self.line_separator = '\r' + else: + self.line_separator = '\n' + self.in_lines = file_contents.split(self.line_separator) + self.original_length = len(self.in_lines) + if (self.original_length > 1 or self.in_lines[:1] not in ([], [""])) or self.config['force_adds']: + for add_import in self.add_imports: + self.in_lines.append(add_import) + self.number_of_lines = len(self.in_lines) + + if not extension: + self.extension = file_name.split('.')[-1] if file_name else "py" + else: + self.extension = extension + + self.out_lines = [] + self.comments = {'from': {}, 'straight': {}, 'nested': {}, 'above': {'straight': {}, 'from': {}}} + self.imports = OrderedDict() + self.as_map = {} + + section_names = self.config['sections'] + self.sections = namedtuple('Sections', section_names)(*[name for name in section_names]) + for section in itertools.chain(self.sections, self.config['forced_separate']): + self.imports[section] = {'straight': OrderedDict(), 'from': OrderedDict()} + + self.finder = FindersManager(config=self.config, sections=self.sections) + + self.index = 0 + self.import_index = -1 + self._first_comment_index_start = -1 + self._first_comment_index_end = -1 + self._parse() + if self.import_index != -1: + self._add_formatted_imports() + self.length_change = len(self.out_lines) - self.original_length + while self.out_lines and self.out_lines[-1].strip() == "": + self.out_lines.pop(-1) + self.out_lines.append("") + self.output = self.line_separator.join(self.out_lines) + if self.config['atomic']: + try: + compile(self._strip_top_comments(self.out_lines, self.line_separator), self.file_path, 'exec', 0, 1) + except SyntaxError: + self.output = file_contents + self.incorrectly_sorted = True + try: + compile(self._strip_top_comments(self.in_lines, self.line_separator), self.file_path, 'exec', 0, 1) + print("ERROR: {0} isort would have introduced syntax errors, please report to the project!". + format(self.file_path)) + except SyntaxError: + print("ERROR: {0} File contains syntax errors.".format(self.file_path)) + + return + if check: + check_output = self.output + check_against = file_contents + if self.config['ignore_whitespace']: + check_output = check_output.replace(self.line_separator, "").replace(" ", "").replace("\x0c", "") + check_against = check_against.replace(self.line_separator, "").replace(" ", "").replace("\x0c", "") + + if check_output.strip() == check_against.strip(): + if self.config['verbose']: + print("SUCCESS: {0} Everything Looks Good!".format(self.file_path)) + return + + print("ERROR: {0} Imports are incorrectly sorted.".format(self.file_path)) + self.incorrectly_sorted = True + if show_diff or self.config['show_diff']: + self._show_diff(file_contents) + elif write_to_stdout: + if sys.version_info[0] < 3: + self.output = self.output.encode(self.file_encoding) + sys.stdout.write(self.output) + elif file_name and not check: + if self.output == file_contents: + return + + if ask_to_apply: + self._show_diff(file_contents) + answer = None + while answer not in ('yes', 'y', 'no', 'n', 'quit', 'q'): + answer = input("Apply suggested changes to '{0}' [y/n/q]? ".format(self.file_path)).lower() + if answer in ('no', 'n'): + return + if answer in ('quit', 'q'): + sys.exit(1) + with io.open(self.file_path, encoding=self.file_encoding, mode='w', newline='') as output_file: + if not self.config['quiet']: + print("Fixing {0}".format(self.file_path)) + output_file.write(self.output) + + @property + def correctly_sorted(self): + return not self.incorrectly_sorted + + def _show_diff(self, file_contents): + for line in unified_diff( + file_contents.splitlines(1), + self.output.splitlines(1), + fromfile=self.file_path + ':before', + tofile=self.file_path + ':after', + fromfiledate=str(datetime.fromtimestamp(os.path.getmtime(self.file_path)) + if self.file_path else datetime.now()), + tofiledate=str(datetime.now()) + ): + sys.stdout.write(line) + + @staticmethod + def _strip_top_comments(lines, line_separator): + """Strips # comments that exist at the top of the given lines""" + lines = copy.copy(lines) + while lines and lines[0].startswith("#"): + lines = lines[1:] + return line_separator.join(lines) + + def place_module(self, module_name): + """Tries to determine if a module is a python std import, third party import, or project code: + + if it can't determine - it assumes it is project code + + """ + return self.finder.find(module_name) + + def _get_line(self): + """Returns the current line from the file while incrementing the index.""" + line = self.in_lines[self.index] + self.index += 1 + return line + + @staticmethod + def _import_type(line): + """If the current line is an import line it will return its type (from or straight)""" + if "isort:skip" in line: + return + elif line.startswith('import '): + return "straight" + elif line.startswith('from '): + return "from" + + def _at_end(self): + """returns True if we are at the end of the file.""" + return self.index == self.number_of_lines + + @staticmethod + def _module_key(module_name, config, sub_imports=False, ignore_case=False, section_name=None): + match = re.match(r'^(\.+)\s*(.*)', module_name) + if match: + sep = ' ' if config['reverse_relative'] else '_' + module_name = sep.join(match.groups()) + + prefix = "" + if ignore_case: + module_name = str(module_name).lower() + else: + module_name = str(module_name) + + if sub_imports and config['order_by_type']: + if module_name.isupper() and len(module_name) > 1: + prefix = "A" + elif module_name[0:1].isupper(): + prefix = "B" + else: + prefix = "C" + if not config['case_sensitive']: + module_name = module_name.lower() + if section_name is None or 'length_sort_' + str(section_name).lower() not in config: + length_sort = config['length_sort'] + else: + length_sort = config['length_sort_' + str(section_name).lower()] + return "{0}{1}{2}".format(module_name in config['force_to_top'] and "A" or "B", prefix, + length_sort and (str(len(module_name)) + ":" + module_name) or module_name) + + def _add_comments(self, comments, original_string=""): + """ + Returns a string with comments added if ignore_comments is not set. + """ + + if not self.config['ignore_comments']: + return comments and "{0}{1} {2}".format(self._strip_comments(original_string)[0], + self.config['comment_prefix'], + "; ".join(comments)) or original_string + + return comments and self._strip_comments(original_string)[0] + + def _wrap(self, line): + """ + Returns an import wrapped to the specified line-length, if possible. + """ + wrap_mode = self.config['multi_line_output'] + if len(line) > self.config['line_length'] and wrap_mode != settings.WrapModes.NOQA: + line_without_comment = line + comment = None + if '#' in line: + line_without_comment, comment = line.split('#', 1) + for splitter in ("import ", ".", "as "): + exp = r"\b" + re.escape(splitter) + r"\b" + if re.search(exp, line_without_comment) and not line_without_comment.strip().startswith(splitter): + line_parts = re.split(exp, line_without_comment) + if comment: + line_parts[-1] = '{0}#{1}'.format(line_parts[-1], comment) + next_line = [] + while (len(line) + 2) > (self.config['wrap_length'] or self.config['line_length']) and line_parts: + next_line.append(line_parts.pop()) + line = splitter.join(line_parts) + if not line: + line = next_line.pop() + + cont_line = self._wrap(self.config['indent'] + splitter.join(next_line).lstrip()) + if self.config['use_parentheses']: + if splitter == "as ": + output = "{0}{1}{2}".format(line, splitter, cont_line.lstrip()) + else: + output = "{0}{1}({2}{3}{4}{5})".format( + line, splitter, self.line_separator, cont_line, + "," if self.config['include_trailing_comma'] else "", + self.line_separator if wrap_mode in (settings.WrapModes.VERTICAL_HANGING_INDENT, + settings.WrapModes.VERTICAL_GRID_GROUPED) + else "") + lines = output.split(self.line_separator) + if self.config['comment_prefix'] in lines[-1] and lines[-1].endswith(')'): + line, comment = lines[-1].split(self.config['comment_prefix'], 1) + lines[-1] = line + ')' + self.config['comment_prefix'] + comment[:-1] + return self.line_separator.join(lines) + return "{0}{1}\\{2}{3}".format(line, splitter, self.line_separator, cont_line) + elif len(line) > self.config['line_length'] and wrap_mode == settings.WrapModes.NOQA: + if "# NOQA" not in line: + return "{0}{1} NOQA".format(line, self.config['comment_prefix']) + + return line + + def _add_straight_imports(self, straight_modules, section, section_output): + for module in straight_modules: + if module in self.remove_imports: + continue + + if module in self.as_map: + import_definition = '' + if self.config['keep_direct_and_as_imports']: + import_definition = "import {0}\n".format(module) + import_definition += "import {0} as {1}".format(module, self.as_map[module]) + else: + import_definition = "import {0}".format(module) + + comments_above = self.comments['above']['straight'].pop(module, None) + if comments_above: + section_output.extend(comments_above) + section_output.append(self._add_comments(self.comments['straight'].get(module), import_definition)) + + def _add_from_imports(self, from_modules, section, section_output, ignore_case): + for module in from_modules: + if module in self.remove_imports: + continue + + import_start = "from {0} import ".format(module) + from_imports = list(self.imports[section]['from'][module]) + if not self.config['no_inline_sort'] or self.config['force_single_line']: + from_imports = nsorted(from_imports, key=lambda key: self._module_key(key, self.config, True, ignore_case, section_name=section)) + if self.remove_imports: + from_imports = [line for line in from_imports if not "{0}.{1}".format(module, line) in + self.remove_imports] + + sub_modules = ['{0}.{1}'.format(module, from_import) for from_import in from_imports] + as_imports = { + from_import: "{0} as {1}".format(from_import, self.as_map[sub_module]) + for from_import, sub_module in zip(from_imports, sub_modules) + if sub_module in self.as_map + } + if self.config['combine_as_imports'] and not ("*" in from_imports and self.config['combine_star']): + for from_import in copy.copy(from_imports): + if from_import in as_imports: + from_imports[from_imports.index(from_import)] = as_imports.pop(from_import) + + while from_imports: + comments = self.comments['from'].pop(module, ()) + if "*" in from_imports and self.config['combine_star']: + import_statement = self._wrap(self._add_comments(comments, "{0}*".format(import_start))) + from_imports = None + elif self.config['force_single_line']: + import_statements = [] + while from_imports: + from_import = from_imports.pop(0) + if from_import in as_imports: + from_comments = self.comments['straight'].get('{}.{}'.format(module, from_import)) + import_statements.append(self._add_comments(from_comments, + self._wrap(import_start + as_imports[from_import]))) + continue + single_import_line = self._add_comments(comments, import_start + from_import) + comment = self.comments['nested'].get(module, {}).pop(from_import, None) + if comment: + single_import_line += "{0} {1}".format(comments and ";" or self.config['comment_prefix'], + comment) + import_statements.append(self._wrap(single_import_line)) + comments = None + import_statement = self.line_separator.join(import_statements) + else: + while from_imports and from_imports[0] in as_imports: + from_import = from_imports.pop(0) + from_comments = self.comments['straight'].get('{}.{}'.format(module, from_import)) + above_comments = self.comments['above']['from'].pop(module, None) + if above_comments: + section_output.extend(above_comments) + + section_output.append(self._add_comments(from_comments, + self._wrap(import_start + as_imports[from_import]))) + + star_import = False + if "*" in from_imports: + section_output.append(self._add_comments(comments, "{0}*".format(import_start))) + from_imports.remove('*') + star_import = True + comments = None + + for from_import in copy.copy(from_imports): + if from_import in as_imports: + continue + comment = self.comments['nested'].get(module, {}).pop(from_import, None) + if comment: + single_import_line = self._add_comments(comments, import_start + from_import) + single_import_line += "{0} {1}".format(comments and ";" or self.config['comment_prefix'], + comment) + above_comments = self.comments['above']['from'].pop(module, None) + if above_comments: + section_output.extend(above_comments) + section_output.append(self._wrap(single_import_line)) + from_imports.remove(from_import) + comments = None + + from_import_section = [] + while from_imports and from_imports[0] not in as_imports: + from_import_section.append(from_imports.pop(0)) + if star_import: + import_statement = import_start + (", ").join(from_import_section) + else: + import_statement = self._add_comments(comments, import_start + (", ").join(from_import_section)) + if not from_import_section: + import_statement = "" + + do_multiline_reformat = False + + force_grid_wrap = self.config['force_grid_wrap'] + if force_grid_wrap and len(from_import_section) >= force_grid_wrap: + do_multiline_reformat = True + + if len(import_statement) > self.config['line_length'] and len(from_import_section) > 1: + do_multiline_reformat = True + + # If line too long AND have imports AND we are NOT using GRID or VERTICAL wrap modes + if (len(import_statement) > self.config['line_length'] and len(from_import_section) > 0 and + self.config['multi_line_output'] not in (1, 0)): + do_multiline_reformat = True + + if do_multiline_reformat: + import_statement = self._multi_line_reformat(import_start, from_import_section, comments) + if self.config['multi_line_output'] == 0: + self.config['multi_line_output'] = 4 + try: + other_import_statement = self._multi_line_reformat(import_start, from_import_section, comments) + if (max(len(x) + for x in import_statement.split('\n')) > self.config['line_length']): + import_statement = other_import_statement + finally: + self.config['multi_line_output'] = 0 + if not do_multiline_reformat and len(import_statement) > self.config['line_length']: + import_statement = self._wrap(import_statement) + + if import_statement: + above_comments = self.comments['above']['from'].pop(module, None) + if above_comments: + section_output.extend(above_comments) + section_output.append(import_statement) + + def _multi_line_reformat(self, import_start, from_imports, comments): + output_mode = settings.WrapModes._fields[self.config['multi_line_output']].lower() + formatter = getattr(self, "_output_" + output_mode, self._output_grid) + dynamic_indent = " " * (len(import_start) + 1) + indent = self.config['indent'] + line_length = self.config['wrap_length'] or self.config['line_length'] + import_statement = formatter(import_start, copy.copy(from_imports), + dynamic_indent, indent, line_length, comments) + if self.config['balanced_wrapping']: + lines = import_statement.split(self.line_separator) + line_count = len(lines) + if len(lines) > 1: + minimum_length = min(len(line) for line in lines[:-1]) + else: + minimum_length = 0 + new_import_statement = import_statement + while (len(lines[-1]) < minimum_length and + len(lines) == line_count and line_length > 10): + import_statement = new_import_statement + line_length -= 1 + new_import_statement = formatter(import_start, copy.copy(from_imports), + dynamic_indent, indent, line_length, comments) + lines = new_import_statement.split(self.line_separator) + if import_statement.count(self.line_separator) == 0: + return self._wrap(import_statement) + return import_statement + + def _add_formatted_imports(self): + """Adds the imports back to the file. + + (at the index of the first import) sorted alphabetically and split between groups + + """ + sort_ignore_case = self.config['force_alphabetical_sort_within_sections'] + sections = itertools.chain(self.sections, self.config['forced_separate']) + + if self.config['no_sections']: + self.imports['no_sections'] = {'straight': [], 'from': {}} + for section in sections: + self.imports['no_sections']['straight'].extend(self.imports[section].get('straight', [])) + self.imports['no_sections']['from'].update(self.imports[section].get('from', {})) + sections = ('no_sections', ) + + output = [] + pending_lines_before = False + for section in sections: + straight_modules = self.imports[section]['straight'] + straight_modules = nsorted(straight_modules, key=lambda key: self._module_key(key, self.config, section_name=section)) + from_modules = self.imports[section]['from'] + from_modules = nsorted(from_modules, key=lambda key: self._module_key(key, self.config, section_name=section)) + + section_output = [] + if self.config['from_first']: + self._add_from_imports(from_modules, section, section_output, sort_ignore_case) + if self.config['lines_between_types'] and from_modules and straight_modules: + section_output.extend([''] * self.config['lines_between_types']) + self._add_straight_imports(straight_modules, section, section_output) + else: + self._add_straight_imports(straight_modules, section, section_output) + if self.config['lines_between_types'] and from_modules and straight_modules: + section_output.extend([''] * self.config['lines_between_types']) + self._add_from_imports(from_modules, section, section_output, sort_ignore_case) + + if self.config['force_sort_within_sections']: + def by_module(line): + section = 'B' + if line.startswith('#'): + return 'AA' + + line = re.sub('^from ', '', line) + line = re.sub('^import ', '', line) + if line.split(' ')[0] in self.config['force_to_top']: + section = 'A' + if not self.config['order_by_type']: + line = line.lower() + return '{0}{1}'.format(section, line) + section_output = nsorted(section_output, key=by_module) + + section_name = section + no_lines_before = section_name in self.config['no_lines_before'] + + if section_output: + if section_name in self.place_imports: + self.place_imports[section_name] = section_output + continue + + section_title = self.config.get('import_heading_' + str(section_name).lower(), '') + if section_title: + section_comment = "# {0}".format(section_title) + if section_comment not in self.out_lines[0:1] and section_comment not in self.in_lines[0:1]: + section_output.insert(0, section_comment) + + if pending_lines_before or not no_lines_before: + output += ([''] * self.config['lines_between_sections']) + + output += section_output + + pending_lines_before = False + else: + pending_lines_before = pending_lines_before or not no_lines_before + + while output and output[-1].strip() == '': + output.pop() + while output and output[0].strip() == '': + output.pop(0) + + output_at = 0 + if self.import_index < self.original_length: + output_at = self.import_index + elif self._first_comment_index_end != -1 and self._first_comment_index_start <= 2: + output_at = self._first_comment_index_end + self.out_lines[output_at:0] = output + + imports_tail = output_at + len(output) + while [character.strip() for character in self.out_lines[imports_tail: imports_tail + 1]] == [""]: + self.out_lines.pop(imports_tail) + + if len(self.out_lines) > imports_tail: + next_construct = "" + self._in_quote = False + tail = self.out_lines[imports_tail:] + + for index, line in enumerate(tail): + in_quote = self._in_quote + if not self._skip_line(line) and line.strip(): + if line.strip().startswith("#") and len(tail) > (index + 1) and tail[index + 1].strip(): + continue + next_construct = line + break + elif not in_quote: + parts = line.split() + if len(parts) >= 3 and parts[1] == '=' and "'" not in parts[0] and '"' not in parts[0]: + next_construct = line + break + + if self.config['lines_after_imports'] != -1: + self.out_lines[imports_tail:0] = ["" for line in range(self.config['lines_after_imports'])] + elif self.extension != "pyi" and (next_construct.startswith("def ") or + next_construct.startswith("class ") or + next_construct.startswith("@") or + next_construct.startswith("async def")): + self.out_lines[imports_tail:0] = ["", ""] + else: + self.out_lines[imports_tail:0] = [""] + + if self.place_imports: + new_out_lines = [] + for index, line in enumerate(self.out_lines): + new_out_lines.append(line) + if line in self.import_placements: + new_out_lines.extend(self.place_imports[self.import_placements[line]]) + if len(self.out_lines) <= index or self.out_lines[index + 1].strip() != "": + new_out_lines.append("") + self.out_lines = new_out_lines + + def _output_grid(self, statement, imports, white_space, indent, line_length, comments): + statement += "(" + imports.pop(0) + while imports: + next_import = imports.pop(0) + next_statement = self._add_comments(comments, statement + ", " + next_import) + if len(next_statement.split(self.line_separator)[-1]) + 1 > line_length: + lines = ['{0}{1}'.format(white_space, next_import.split(" ")[0])] + for part in next_import.split(" ")[1:]: + new_line = '{0} {1}'.format(lines[-1], part) + if len(new_line) + 1 > line_length: + lines.append('{0}{1}'.format(white_space, part)) + else: + lines[-1] = new_line + next_import = self.line_separator.join(lines) + statement = (self._add_comments(comments, "{0},".format(statement)) + + "{0}{1}".format(self.line_separator, next_import)) + comments = None + else: + statement += ", " + next_import + return statement + ("," if self.config['include_trailing_comma'] else "") + ")" + + def _output_vertical(self, statement, imports, white_space, indent, line_length, comments): + first_import = self._add_comments(comments, imports.pop(0) + ",") + self.line_separator + white_space + return "{0}({1}{2}{3})".format( + statement, + first_import, + ("," + self.line_separator + white_space).join(imports), + "," if self.config['include_trailing_comma'] else "", + ) + + def _output_hanging_indent(self, statement, imports, white_space, indent, line_length, comments): + statement += imports.pop(0) + while imports: + next_import = imports.pop(0) + next_statement = self._add_comments(comments, statement + ", " + next_import) + if len(next_statement.split(self.line_separator)[-1]) + 3 > line_length: + next_statement = (self._add_comments(comments, "{0}, \\".format(statement)) + + "{0}{1}{2}".format(self.line_separator, indent, next_import)) + comments = None + statement = next_statement + return statement + + def _output_vertical_hanging_indent(self, statement, imports, white_space, indent, line_length, comments): + return "{0}({1}{2}{3}{4}{5}{2})".format( + statement, + self._add_comments(comments), + self.line_separator, + indent, + ("," + self.line_separator + indent).join(imports), + "," if self.config['include_trailing_comma'] else "", + ) + + def _output_vertical_grid_common(self, statement, imports, white_space, indent, line_length, comments, + need_trailing_char): + statement += self._add_comments(comments, "(") + self.line_separator + indent + imports.pop(0) + while imports: + next_import = imports.pop(0) + next_statement = "{0}, {1}".format(statement, next_import) + current_line_length = len(next_statement.split(self.line_separator)[-1]) + if imports or need_trailing_char: + # If we have more imports we need to account for a comma after this import + # We might also need to account for a closing ) we're going to add. + current_line_length += 1 + if current_line_length > line_length: + next_statement = "{0},{1}{2}{3}".format(statement, self.line_separator, indent, next_import) + statement = next_statement + if self.config['include_trailing_comma']: + statement += ',' + return statement + + def _output_vertical_grid(self, statement, imports, white_space, indent, line_length, comments): + return self._output_vertical_grid_common(statement, imports, white_space, indent, line_length, comments, + True) + ")" + + def _output_vertical_grid_grouped(self, statement, imports, white_space, indent, line_length, comments): + return self._output_vertical_grid_common(statement, imports, white_space, indent, line_length, comments, + True) + self.line_separator + ")" + + def _output_vertical_grid_grouped_no_comma(self, statement, imports, white_space, indent, line_length, comments): + return self._output_vertical_grid_common(statement, imports, white_space, indent, line_length, comments, + False) + self.line_separator + ")" + + def _output_noqa(self, statement, imports, white_space, indent, line_length, comments): + retval = '{0}{1}'.format(statement, ', '.join(imports)) + comment_str = ' '.join(comments) + if comments: + if len(retval) + len(self.config['comment_prefix']) + 1 + len(comment_str) <= line_length: + return '{0}{1} {2}'.format(retval, self.config['comment_prefix'], comment_str) + else: + if len(retval) <= line_length: + return retval + if comments: + if "NOQA" in comments: + return '{0}{1} {2}'.format(retval, self.config['comment_prefix'], comment_str) + else: + return '{0}{1} NOQA {2}'.format(retval, self.config['comment_prefix'], comment_str) + else: + return '{0}{1} NOQA'.format(retval, self.config['comment_prefix']) + + @staticmethod + def _strip_comments(line, comments=None): + """Removes comments from import line.""" + if comments is None: + comments = [] + + new_comments = False + comment_start = line.find("#") + if comment_start != -1: + comments.append(line[comment_start + 1:].strip()) + new_comments = True + line = line[:comment_start] + + return line, comments, new_comments + + @staticmethod + def _format_simplified(import_line): + import_line = import_line.strip() + if import_line.startswith("from "): + import_line = import_line.replace("from ", "") + import_line = import_line.replace(" import ", ".") + elif import_line.startswith("import "): + import_line = import_line.replace("import ", "") + + return import_line + + @staticmethod + def _format_natural(import_line): + import_line = import_line.strip() + if not import_line.startswith("from ") and not import_line.startswith("import "): + if "." not in import_line: + return "import {0}".format(import_line) + parts = import_line.split(".") + end = parts.pop(-1) + return "from {0} import {1}".format(".".join(parts), end) + + return import_line + + def _skip_line(self, line): + skip_line = self._in_quote + if self.index == 1 and line.startswith("#"): + self._in_top_comment = True + return True + elif self._in_top_comment: + if not line.startswith("#") or line in self._section_comments: + self._in_top_comment = False + self._first_comment_index_end = self.index - 1 + + if '"' in line or "'" in line: + index = 0 + if self._first_comment_index_start == -1 and (line.startswith('"') or line.startswith("'")): + self._first_comment_index_start = self.index + while index < len(line): + if line[index] == "\\": + index += 1 + elif self._in_quote: + if line[index:index + len(self._in_quote)] == self._in_quote: + self._in_quote = False + if self._first_comment_index_end < self._first_comment_index_start: + self._first_comment_index_end = self.index + elif line[index] in ("'", '"'): + long_quote = line[index:index + 3] + if long_quote in ('"""', "'''"): + self._in_quote = long_quote + index += 2 + else: + self._in_quote = line[index] + elif line[index] == "#": + break + index += 1 + + return skip_line or self._in_quote or self._in_top_comment + + def _strip_syntax(self, import_string): + import_string = import_string.replace("_import", "[[i]]") + for remove_syntax in ['\\', '(', ')', ',']: + import_string = import_string.replace(remove_syntax, " ") + import_list = import_string.split() + for key in ('from', 'import'): + if key in import_list: + import_list.remove(key) + import_string = ' '.join(import_list) + import_string = import_string.replace("[[i]]", "_import") + return import_string.replace("{ ", "{|").replace(" }", "|}") + + def _parse(self): + """Parses a python file taking out and categorizing imports.""" + self._in_quote = False + self._in_top_comment = False + while not self._at_end(): + raw_line = line = self._get_line() + line = line.replace("from.import ", "from . import ") + line = line.replace("\t", " ").replace('import*', 'import *') + line = line.replace(" .import ", " . import ") + statement_index = self.index + skip_line = self._skip_line(line) + + if line in self._section_comments and not skip_line: + if self.import_index == -1: + self.import_index = self.index - 1 + continue + + if "isort:imports-" in line and line.startswith("#"): + section = line.split("isort:imports-")[-1].split()[0].upper() + self.place_imports[section] = [] + self.import_placements[line] = section + + if ";" in line: + for part in (part.strip() for part in line.split(";")): + if part and not part.startswith("from ") and not part.startswith("import "): + skip_line = True + + import_type = self._import_type(line) + if not import_type or skip_line: + self.out_lines.append(raw_line) + continue + + for line in (line.strip() for line in line.split(";")): + import_type = self._import_type(line) + if not import_type: + self.out_lines.append(line) + continue + + if self.import_index == -1: + self.import_index = self.index - 1 + nested_comments = {} + import_string, comments, new_comments = self._strip_comments(line) + stripped_line = [part for part in self._strip_syntax(import_string).strip().split(" ") if part] + if import_type == "from" and len(stripped_line) == 2 and stripped_line[1] != "*" and new_comments: + nested_comments[stripped_line[-1]] = comments[0] + + if "(" in line.split("#")[0] and not self._at_end(): + while not line.strip().endswith(")") and not self._at_end(): + line, comments, new_comments = self._strip_comments(self._get_line(), comments) + stripped_line = self._strip_syntax(line).strip() + if import_type == "from" and stripped_line and " " not in stripped_line and new_comments: + nested_comments[stripped_line] = comments[-1] + import_string += self.line_separator + line + else: + while line.strip().endswith("\\"): + line, comments, new_comments = self._strip_comments(self._get_line(), comments) + + # Still need to check for parentheses after an escaped line + if "(" in line.split("#")[0] and ")" not in line.split("#")[0] and not self._at_end(): + stripped_line = self._strip_syntax(line).strip() + if import_type == "from" and stripped_line and " " not in stripped_line and new_comments: + nested_comments[stripped_line] = comments[-1] + import_string += self.line_separator + line + + while not line.strip().endswith(")") and not self._at_end(): + line, comments, new_comments = self._strip_comments(self._get_line(), comments) + stripped_line = self._strip_syntax(line).strip() + if import_type == "from" and stripped_line and " " not in stripped_line and new_comments: + nested_comments[stripped_line] = comments[-1] + import_string += self.line_separator + line + + stripped_line = self._strip_syntax(line).strip() + if import_type == "from" and stripped_line and " " not in stripped_line and new_comments: + nested_comments[stripped_line] = comments[-1] + if import_string.strip().endswith(" import") or line.strip().startswith("import "): + import_string += self.line_separator + line + else: + import_string = import_string.rstrip().rstrip("\\") + " " + line.lstrip() + + if import_type == "from": + import_string = import_string.replace("import(", "import (") + parts = import_string.split(" import ") + from_import = parts[0].split(" ") + import_string = " import ".join([from_import[0] + " " + "".join(from_import[1:])] + parts[1:]) + + imports = [item.replace("{|", "{ ").replace("|}", " }") for item in + self._strip_syntax(import_string).split()] + if "as" in imports and (imports.index('as') + 1) < len(imports): + while "as" in imports: + index = imports.index('as') + if import_type == "from": + module = imports[0] + "." + imports[index - 1] + self.as_map[module] = imports[index + 1] + else: + module = imports[index - 1] + self.as_map[module] = imports[index + 1] + if not self.config['combine_as_imports']: + self.comments['straight'][module] = comments + comments = [] + del imports[index:index + 2] + if import_type == "from": + import_from = imports.pop(0) + placed_module = self.place_module(import_from) + if self.config['verbose']: + print("from-type place_module for %s returned %s" % (import_from, placed_module)) + if placed_module == '': + print( + "WARNING: could not place module {0} of line {1} --" + " Do you need to define a default section?".format(import_from, line) + ) + root = self.imports[placed_module][import_type] + for import_name in imports: + associated_comment = nested_comments.get(import_name) + if associated_comment: + self.comments['nested'].setdefault(import_from, {})[import_name] = associated_comment + comments.pop(comments.index(associated_comment)) + if comments: + self.comments['from'].setdefault(import_from, []).extend(comments) + + if len(self.out_lines) > max(self.import_index, self._first_comment_index_end + 1, 1) - 1: + last = self.out_lines and self.out_lines[-1].rstrip() or "" + while (last.startswith("#") and not last.endswith('"""') and not last.endswith("'''") and + 'isort:imports-' not in last): + self.comments['above']['from'].setdefault(import_from, []).insert(0, self.out_lines.pop(-1)) + if len(self.out_lines) > max(self.import_index - 1, self._first_comment_index_end + 1, 1) - 1: + last = self.out_lines[-1].rstrip() + else: + last = "" + if statement_index - 1 == self.import_index: + self.import_index -= len(self.comments['above']['from'].get(import_from, [])) + + if import_from not in root: + root[import_from] = OrderedDict() + root[import_from].update((module, None) for module in imports) + else: + for module in imports: + if comments: + self.comments['straight'][module] = comments + comments = None + + if len(self.out_lines) > max(self.import_index, self._first_comment_index_end + 1, 1) - 1: + + last = self.out_lines and self.out_lines[-1].rstrip() or "" + while (last.startswith("#") and not last.endswith('"""') and not last.endswith("'''") and + 'isort:imports-' not in last): + self.comments['above']['straight'].setdefault(module, []).insert(0, + self.out_lines.pop(-1)) + if len(self.out_lines) > 0 and len(self.out_lines) != self._first_comment_index_end: + last = self.out_lines[-1].rstrip() + else: + last = "" + if self.index - 1 == self.import_index: + self.import_index -= len(self.comments['above']['straight'].get(module, [])) + placed_module = self.place_module(module) + if self.config['verbose']: + print("else-type place_module for %s returned %s" % (module, placed_module)) + if placed_module == '': + print( + "WARNING: could not place module {0} of line {1} --" + " Do you need to define a default section?".format(import_from, line) + ) + self.imports[placed_module][import_type][module] = None + + +def coding_check(lines, default='utf-8'): + + # see https://www.python.org/dev/peps/pep-0263/ + pattern = re.compile(br'coding[:=]\s*([-\w.]+)') + + for line_number, line in enumerate(lines, 1): + groups = re.findall(pattern, line) + if groups: + return groups[0].decode('ascii') + if line_number > 2: + break + + return default diff --git a/py3/lib/python3.6/site-packages/isort/main.py b/py3/lib/python3.6/site-packages/isort/main.py new file mode 100644 index 0000000..fe36d11 --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort/main.py @@ -0,0 +1,401 @@ +''' Tool for sorting imports alphabetically, and automatically separated into sections. + +Copyright (C) 2013 Timothy Edmund Crosley + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +''' +from __future__ import absolute_import, division, print_function, unicode_literals + +import argparse +import functools +import glob +import os +import re +import sys + +import setuptools + +from isort import SortImports, __version__ +from isort.settings import DEFAULT_SECTIONS, WrapModes, default, from_path, should_skip + +INTRO = r""" +/#######################################################################\ + + `sMMy` + .yyyy- ` + ##soos## ./o. + ` ``..-..` ``...`.`` ` ```` ``-ssso``` + .s:-y- .+osssssso/. ./ossss+:so+:` :+o-`/osso:+sssssssso/ + .s::y- osss+.``.`` -ssss+-.`-ossso` ssssso/::..::+ssss:::. + .s::y- /ssss+//:-.` `ssss+ `ssss+ sssso` :ssss` + .s::y- `-/+oossssso/ `ssss/ sssso ssss/ :ssss` + .y-/y- ````:ssss` ossso. :ssss: ssss/ :ssss. + `/so:` `-//::/osss+ `+ssss+-/ossso: /sso- `osssso/. + \/ `-/oooo++/- .:/++:/++/-` .. `://++/. + + + isort your Python imports for you so you don't have to + + VERSION {0} + +\########################################################################/ +""".format(__version__) + +shebang_re = re.compile(br'^#!.*\bpython[23w]?\b') + + +def is_python_file(path): + _root, ext = os.path.splitext(path) + if ext in ('.py', '.pyi'): + return True + if ext in ('.pex', ): + return False + + # Skip editor backup files. + if path.endswith('~'): + return False + + try: + with open(path, 'rb') as fp: + line = fp.readline(100) + except IOError: + return False + else: + return bool(shebang_re.match(line)) + + +class SortAttempt(object): + def __init__(self, incorrectly_sorted, skipped): + self.incorrectly_sorted = incorrectly_sorted + self.skipped = skipped + + +def sort_imports(file_name, **arguments): + try: + result = SortImports(file_name, **arguments) + return SortAttempt(result.incorrectly_sorted, result.skipped) + except IOError as e: + print("WARNING: Unable to parse file {0} due to {1}".format(file_name, e)) + return None + + +def iter_source_code(paths, config, skipped): + """Iterate over all Python source files defined in paths.""" + if 'not_skip' in config: + config['skip'] = list(set(config['skip']).difference(config['not_skip'])) + + for path in paths: + if os.path.isdir(path): + for dirpath, dirnames, filenames in os.walk(path, topdown=True, followlinks=True): + for dirname in list(dirnames): + if should_skip(dirname, config, dirpath): + skipped.append(dirname) + dirnames.remove(dirname) + for filename in filenames: + filepath = os.path.join(dirpath, filename) + if is_python_file(filepath): + relative_file = os.path.relpath(filepath, path) + if should_skip(relative_file, config, path): + skipped.append(filename) + else: + yield filepath + else: + yield path + + +class ISortCommand(setuptools.Command): + """The :class:`ISortCommand` class is used by setuptools to perform + imports checks on registered modules. + """ + + description = "Run isort on modules registered in setuptools" + user_options = [] + + def initialize_options(self): + default_settings = default.copy() + for key, value in default_settings.items(): + setattr(self, key, value) + + def finalize_options(self): + "Get options from config files." + self.arguments = {} + computed_settings = from_path(os.getcwd()) + for key, value in computed_settings.items(): + self.arguments[key] = value + + def distribution_files(self): + """Find distribution packages.""" + # This is verbatim from flake8 + if self.distribution.packages: + package_dirs = self.distribution.package_dir or {} + for package in self.distribution.packages: + pkg_dir = package + if package in package_dirs: + pkg_dir = package_dirs[package] + elif '' in package_dirs: + pkg_dir = package_dirs[''] + os.path.sep + pkg_dir + yield pkg_dir.replace('.', os.path.sep) + + if self.distribution.py_modules: + for filename in self.distribution.py_modules: + yield "%s.py" % filename + # Don't miss the setup.py file itself + yield "setup.py" + + def run(self): + arguments = self.arguments + wrong_sorted_files = False + arguments['check'] = True + for path in self.distribution_files(): + for python_file in glob.iglob(os.path.join(path, '*.py')): + try: + incorrectly_sorted = SortImports(python_file, **arguments).incorrectly_sorted + if incorrectly_sorted: + wrong_sorted_files = True + except IOError as e: + print("WARNING: Unable to parse file {0} due to {1}".format(python_file, e)) + if wrong_sorted_files: + sys.exit(1) + + +def parse_args(argv=None): + parser = argparse.ArgumentParser(description='Sort Python import definitions alphabetically ' + 'within logical sections. Run with no arguments to run ' + 'interactively. Run with `-` as the first argument to read from ' + 'stdin. Otherwise provide a list of files to sort.') + inline_args_group = parser.add_mutually_exclusive_group() + parser.add_argument('-a', '--add-import', dest='add_imports', action='append', + help='Adds the specified import line to all files, ' + 'automatically determining correct placement.') + parser.add_argument('-ac', '--atomic', dest='atomic', action='store_true', + help="Ensures the output doesn't save if the resulting file contains syntax errors.") + parser.add_argument('-af', '--force-adds', dest='force_adds', action='store_true', + help='Forces import adds even if the original file is empty.') + parser.add_argument('-b', '--builtin', dest='known_standard_library', action='append', + help='Force sortImports to recognize a module as part of the python standard library.') + parser.add_argument('-c', '--check-only', action='store_true', dest="check", + help='Checks the file for unsorted / unformatted imports and prints them to the ' + 'command line without modifying the file.') + parser.add_argument('-ca', '--combine-as', dest='combine_as_imports', action='store_true', + help="Combines as imports on the same line.") + parser.add_argument('-cs', '--combine-star', dest='combine_star', action='store_true', + help="Ensures that if a star import is present, nothing else is imported from that namespace.") + parser.add_argument('-d', '--stdout', help='Force resulting output to stdout, instead of in-place.', + dest='write_to_stdout', action='store_true') + parser.add_argument('-df', '--diff', dest='show_diff', action='store_true', + help="Prints a diff of all the changes isort would make to a file, instead of " + "changing it in place") + parser.add_argument('-ds', '--no-sections', help='Put all imports into the same section bucket', dest='no_sections', + action='store_true') + parser.add_argument('-dt', '--dont-order-by-type', dest='dont_order_by_type', + action='store_true', help='Only order imports alphabetically, do not attempt type ordering') + parser.add_argument('-e', '--balanced', dest='balanced_wrapping', action='store_true', + help='Balances wrapping to produce the most consistent line length possible') + parser.add_argument('-f', '--future', dest='known_future_library', action='append', + help='Force sortImports to recognize a module as part of the future compatibility libraries.') + parser.add_argument('-fas', '--force-alphabetical-sort', action='store_true', dest="force_alphabetical_sort", + help='Force all imports to be sorted as a single section') + parser.add_argument('-fass', '--force-alphabetical-sort-within-sections', action='store_true', + dest="force_alphabetical_sort", help='Force all imports to be sorted alphabetically within a ' + 'section') + parser.add_argument('-ff', '--from-first', dest='from_first', + help="Switches the typical ordering preference, showing from imports first then straight ones.") + parser.add_argument('-fgw', '--force-grid-wrap', nargs='?', const=2, type=int, dest="force_grid_wrap", + help='Force number of from imports (defaults to 2) to be grid wrapped regardless of line ' + 'length') + parser.add_argument('-fss', '--force-sort-within-sections', action='store_true', dest="force_sort_within_sections", + help='Force imports to be sorted by module, independent of import_type') + parser.add_argument('-i', '--indent', help='String to place for indents defaults to " " (4 spaces).', + dest='indent', type=str) + parser.add_argument('-j', '--jobs', help='Number of files to process in parallel.', + dest='jobs', type=int) + parser.add_argument('-k', '--keep-direct-and-as', dest='keep_direct_and_as_imports', action='store_true', + help="Turns off default behavior that removes direct imports when as imports exist.") + parser.add_argument('-l', '--lines', help='[Deprecated] The max length of an import line (used for wrapping ' + 'long imports).', + dest='line_length', type=int) + parser.add_argument('-lai', '--lines-after-imports', dest='lines_after_imports', type=int) + parser.add_argument('-lbt', '--lines-between-types', dest='lines_between_types', type=int) + parser.add_argument('-le', '--line-ending', dest='line_ending', + help="Forces line endings to the specified value. If not set, values will be guessed per-file.") + parser.add_argument('-ls', '--length-sort', help='Sort imports by their string length.', + dest='length_sort', action='store_true') + parser.add_argument('-m', '--multi-line', dest='multi_line_output', type=int, choices=range(len(WrapModes)), + help='Multi line output (0-grid, 1-vertical, 2-hanging, 3-vert-hanging, 4-vert-grid, ' + '5-vert-grid-grouped, 6-vert-grid-grouped-no-comma).') + inline_args_group.add_argument('-nis', '--no-inline-sort', dest='no_inline_sort', action='store_true', + help='Leaves `from` imports with multiple imports \'as-is\' (e.g. `from foo import a, c ,b`).') + parser.add_argument('-nlb', '--no-lines-before', help='Sections which should not be split with previous by empty lines', + dest='no_lines_before', action='append') + parser.add_argument('-ns', '--dont-skip', help='Files that sort imports should never skip over.', + dest='not_skip', action='append') + parser.add_argument('-o', '--thirdparty', dest='known_third_party', action='append', + help='Force sortImports to recognize a module as being part of a third party library.') + parser.add_argument('-ot', '--order-by-type', dest='order_by_type', + action='store_true', help='Order imports by type in addition to alphabetically') + parser.add_argument('-p', '--project', dest='known_first_party', action='append', + help='Force sortImports to recognize a module as being part of the current python project.') + parser.add_argument('-q', '--quiet', action='store_true', dest="quiet", + help='Shows extra quiet output, only errors are outputted.') + parser.add_argument('-r', dest='ambiguous_r_flag', action='store_true') + parser.add_argument('-rm', '--remove-import', dest='remove_imports', action='append', + help='Removes the specified import from all files.') + parser.add_argument('-rr', '--reverse-relative', dest='reverse_relative', action='store_true', + help='Reverse order of relative imports.') + parser.add_argument('-rc', '--recursive', dest='recursive', action='store_true', + help='Recursively look for Python files of which to sort imports') + parser.add_argument('-s', '--skip', help='Files that sort imports should skip over. If you want to skip multiple ' + 'files you should specify twice: --skip file1 --skip file2.', dest='skip', action='append') + parser.add_argument('-sd', '--section-default', dest='default_section', + help='Sets the default section for imports (by default FIRSTPARTY) options: ' + + str(DEFAULT_SECTIONS)) + parser.add_argument('-sg', '--skip-glob', help='Files that sort imports should skip over.', dest='skip_glob', + action='append') + inline_args_group.add_argument('-sl', '--force-single-line-imports', dest='force_single_line', action='store_true', + help='Forces all from imports to appear on their own line') + parser.add_argument('-sp', '--settings-path', dest="settings_path", + help='Explicitly set the settings path instead of auto determining based on file location.') + parser.add_argument('-t', '--top', help='Force specific imports to the top of their appropriate section.', + dest='force_to_top', action='append') + parser.add_argument('-tc', '--trailing-comma', dest='include_trailing_comma', action='store_true', + help='Includes a trailing comma on multi line imports that include parentheses.') + parser.add_argument('-up', '--use-parentheses', dest='use_parentheses', action='store_true', + help='Use parenthesis for line continuation on length limit instead of slashes.') + parser.add_argument('-v', '--version', action='store_true', dest='show_version') + parser.add_argument('-vb', '--verbose', action='store_true', dest="verbose", + help='Shows verbose output, such as when files are skipped or when a check is successful.') + parser.add_argument('--virtual-env', dest='virtual_env', + help='Virtual environment to use for determining whether a package is third-party') + parser.add_argument('--conda-env', dest='conda_env', + help='Conda environment to use for determining whether a package is third-party') + parser.add_argument('-vn', '--version-number', action='version', version=__version__, + help='Returns just the current version number without the logo') + parser.add_argument('-w', '--line-width', help='The max length of an import line (used for wrapping long imports).', + dest='line_length', type=int) + parser.add_argument('-wl', '--wrap-length', dest='wrap_length', + help="Specifies how long lines that are wrapped should be, if not set line_length is used.") + parser.add_argument('-ws', '--ignore-whitespace', action='store_true', dest="ignore_whitespace", + help='Tells isort to ignore whitespace differences when --check-only is being used.') + parser.add_argument('-y', '--apply', dest='apply', action='store_true', + help='Tells isort to apply changes recursively without asking') + parser.add_argument('--unsafe', dest='unsafe', action='store_true', + help='Tells isort to look for files in standard library directories, etc. ' + 'where it may not be safe to operate in') + parser.add_argument('--case-sensitive', dest='case_sensitive', action='store_true', + help='Tells isort to include casing when sorting module names') + parser.add_argument('--filter-files', dest='filter_files', action='store_true', + help='Tells isort to filter files even when they are explicitly passed in as part of the command') + parser.add_argument('files', nargs='*', help='One or more Python source files that need their imports sorted.') + + arguments = {key: value for key, value in vars(parser.parse_args(argv)).items() if value} + if 'dont_order_by_type' in arguments: + arguments['order_by_type'] = False + if arguments.pop('unsafe', False): + arguments['safety_excludes'] = False + return arguments + + +def main(argv=None): + arguments = parse_args(argv) + if arguments.get('show_version'): + print(INTRO) + return + + if arguments.get('ambiguous_r_flag'): + print('ERROR: Deprecated -r flag set. This flag has been replaced with -rm to remove ambiguity between it and ' + '-rc for recursive') + sys.exit(1) + + arguments['check_skip'] = False + if 'settings_path' in arguments: + sp = arguments['settings_path'] + arguments['settings_path'] = os.path.abspath(sp) if os.path.isdir(sp) else os.path.dirname(os.path.abspath(sp)) + if not os.path.isdir(arguments['settings_path']): + print("WARNING: settings_path dir does not exist: {0}".format(arguments['settings_path'])) + + if 'virtual_env' in arguments: + venv = arguments['virtual_env'] + arguments['virtual_env'] = os.path.abspath(venv) + if not os.path.isdir(arguments['virtual_env']): + print("WARNING: virtual_env dir does not exist: {0}".format(arguments['virtual_env'])) + + file_names = arguments.pop('files', []) + if file_names == ['-']: + try: + # python 3 + file_ = sys.stdin.buffer + except AttributeError: + # python 2 + file_ = sys.stdin + SortImports(file_=file_, write_to_stdout=True, **arguments) + else: + if not file_names: + file_names = ['.'] + arguments['recursive'] = True + if not arguments.get('apply', False): + arguments['ask_to_apply'] = True + + config = from_path(arguments.get('settings_path', '') or os.path.abspath(file_names[0]) or os.getcwd()).copy() + config.update(arguments) + wrong_sorted_files = False + skipped = [] + + if config.get('filter_files'): + filtered_files = [] + for file_name in file_names: + if should_skip(file_name, config): + skipped.append(file_name) + else: + filtered_files.append(file_name) + file_names = filtered_files + + if arguments.get('recursive', False): + file_names = iter_source_code(file_names, config, skipped) + num_skipped = 0 + if config['verbose'] or config.get('show_logo', False): + print(INTRO) + + jobs = arguments.get('jobs') + if jobs: + import multiprocessing + executor = multiprocessing.Pool(jobs) + attempt_iterator = executor.imap(functools.partial(sort_imports, **arguments), file_names) + else: + attempt_iterator = (sort_imports(file_name, **arguments) for file_name in file_names) + + for sort_attempt in attempt_iterator: + if not sort_attempt: + continue + incorrectly_sorted = sort_attempt.incorrectly_sorted + if arguments.get('check', False) and incorrectly_sorted: + wrong_sorted_files = True + if sort_attempt.skipped: + num_skipped += 1 + + if wrong_sorted_files: + sys.exit(1) + + num_skipped += len(skipped) + if num_skipped and not arguments.get('quiet', False): + if config['verbose']: + for was_skipped in skipped: + print("WARNING: {0} was skipped as it's listed in 'skip' setting" + " or matches a glob in 'skip_glob' setting".format(was_skipped)) + print("Skipped {0} files".format(num_skipped)) + + +if __name__ == "__main__": + main() diff --git a/py3/lib/python3.6/site-packages/isort/natural.py b/py3/lib/python3.6/site-packages/isort/natural.py new file mode 100644 index 0000000..c02b42c --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort/natural.py @@ -0,0 +1,47 @@ +"""isort/natural.py. + +Enables sorting strings that contain numbers naturally + +usage: + natural.nsorted(list) + +Copyright (C) 2013 Timothy Edmund Crosley + +Implementation originally from @HappyLeapSecond stack overflow user in response to: + https://stackoverflow.com/questions/5967500/how-to-correctly-sort-a-string-with-a-number-inside + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +""" +import re + + +def _atoi(text): + return int(text) if text.isdigit() else text + + +def _natural_keys(text): + return [_atoi(c) for c in re.split(r'(\d+)', text)] + + +def nsorted(to_sort, key=None): + """Returns a naturally sorted list""" + if key is None: + key_callback = _natural_keys + else: + def key_callback(item): + return _natural_keys(key(item)) + + return sorted(to_sort, key=key_callback) diff --git a/py3/lib/python3.6/site-packages/isort/pie_slice.py b/py3/lib/python3.6/site-packages/isort/pie_slice.py new file mode 100644 index 0000000..569ea76 --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort/pie_slice.py @@ -0,0 +1,154 @@ +"""pie_slice/overrides.py. + +Overrides Python syntax to conform to the Python3 version as much as possible using a '*' import + +Copyright (C) 2013 Timothy Edmund Crosley + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +""" +from __future__ import absolute_import + +import collections +import sys + +__version__ = "1.1.0" + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +VERSION = sys.version_info + +__all__ = ['PY2', 'PY3', 'lru_cache', 'apply_changes_to_python_environment'] + + +if PY3: + input = input + + def apply_changes_to_python_environment(): + pass +else: + input = raw_input # noqa: F821 + + python_environment_changes_applied = False + + import sys + stdout = sys.stdout + stderr = sys.stderr + + def apply_changes_to_python_environment(): + global python_environment_changes_applied + if python_environment_changes_applied or sys.getdefaultencoding() == 'utf-8': + python_environment_changes_applied = True + return + + try: + reload(sys) + sys.stdout = stdout + sys.stderr = stderr + sys.setdefaultencoding('utf-8') + except NameError: # Python 3 + sys.exit('This should not happen!') + + python_environment_changes_applied = True + + +if sys.version_info < (3, 2): + try: + from threading import Lock + except ImportError: + from dummy_threading import Lock + + from functools import wraps + + _CacheInfo = collections.namedtuple("CacheInfo", "hits misses maxsize currsize") + + def lru_cache(maxsize=100): + """Least-recently-used cache decorator. + Taking from: https://github.com/MiCHiLU/python-functools32/blob/master/functools32/functools32.py + with slight modifications. + If *maxsize* is set to None, the LRU features are disabled and the cache + can grow without bound. + Arguments to the cached function must be hashable. + View the cache statistics named tuple (hits, misses, maxsize, currsize) with + f.cache_info(). Clear the cache and statistics with f.cache_clear(). + Access the underlying function with f.__wrapped__. + See: https://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used + + """ + def decorating_function(user_function, tuple=tuple, sorted=sorted, len=len, KeyError=KeyError): + hits, misses = [0], [0] + kwd_mark = (object(),) # separates positional and keyword args + lock = Lock() + + if maxsize is None: + CACHE = {} + + @wraps(user_function) + def wrapper(*args, **kwds): + key = args + if kwds: + key += kwd_mark + tuple(sorted(kwds.items())) + try: + result = CACHE[key] + hits[0] += 1 + return result + except KeyError: + pass + result = user_function(*args, **kwds) + CACHE[key] = result + misses[0] += 1 + return result + else: + CACHE = collections.OrderedDict() + + @wraps(user_function) + def wrapper(*args, **kwds): + key = args + if kwds: + key += kwd_mark + tuple(sorted(kwds.items())) + with lock: + cached = CACHE.get(key, None) + if cached: + del CACHE[key] + CACHE[key] = cached + hits[0] += 1 + return cached + result = user_function(*args, **kwds) + with lock: + CACHE[key] = result # record recent use of this key + misses[0] += 1 + while len(CACHE) > maxsize: + CACHE.popitem(last=False) + return result + + def cache_info(): + """Report CACHE statistics.""" + with lock: + return _CacheInfo(hits[0], misses[0], maxsize, len(CACHE)) + + def cache_clear(): + """Clear the CACHE and CACHE statistics.""" + with lock: + CACHE.clear() + hits[0] = misses[0] = 0 + + wrapper.cache_info = cache_info + wrapper.cache_clear = cache_clear + return wrapper + + return decorating_function + +else: + from functools import lru_cache diff --git a/py3/lib/python3.6/site-packages/isort/pylama_isort.py b/py3/lib/python3.6/site-packages/isort/pylama_isort.py new file mode 100644 index 0000000..6fa235f --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort/pylama_isort.py @@ -0,0 +1,29 @@ +import os +import sys + +from pylama.lint import Linter as BaseLinter + +from .isort import SortImports + + +class Linter(BaseLinter): + + def allow(self, path): + """Determine if this path should be linted.""" + return path.endswith('.py') + + def run(self, path, **meta): + """Lint the file. Return an array of error dicts if appropriate.""" + with open(os.devnull, 'w') as devnull: + # Suppress isort messages + sys.stdout = devnull + + if SortImports(path, check=True).incorrectly_sorted: + return [{ + 'lnum': 0, + 'col': 0, + 'text': 'Incorrectly sorted imports.', + 'type': 'ISORT' + }] + else: + return [] diff --git a/py3/lib/python3.6/site-packages/isort/settings.py b/py3/lib/python3.6/site-packages/isort/settings.py new file mode 100644 index 0000000..a69471e --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort/settings.py @@ -0,0 +1,356 @@ +"""isort/settings.py. + +Defines how the default settings for isort should be loaded + +(First from the default setting dictionary at the top of the file, then overridden by any settings + in ~/.isort.cfg or $XDG_CONFIG_HOME/isort.cfg if there are any) + +Copyright (C) 2013 Timothy Edmund Crosley + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +""" +from __future__ import absolute_import, division, print_function, unicode_literals + +import fnmatch +import io +import os +import posixpath +import re +import sys +import warnings +from collections import namedtuple +from distutils.util import strtobool + +from .pie_slice import lru_cache +from .utils import difference, union + +try: + import configparser +except ImportError: + import ConfigParser as configparser + +try: + import toml +except ImportError: + toml = False + +try: + import appdirs + if appdirs.system == 'darwin': + appdirs.system = 'linux2' +except ImportError: + appdirs = None + +MAX_CONFIG_SEARCH_DEPTH = 25 # The number of parent directories isort will look for a config file within +DEFAULT_SECTIONS = ('FUTURE', 'STDLIB', 'THIRDPARTY', 'FIRSTPARTY', 'LOCALFOLDER') + +safety_exclude_re = re.compile( + r"/(\.eggs|\.git|\.hg|\.mypy_cache|\.nox|\.tox|\.venv|_build|buck-out|build|dist|\.pants\.d" + r"|lib/python[0-9].[0-9]+)/" +) + +WrapModes = ('GRID', 'VERTICAL', 'HANGING_INDENT', 'VERTICAL_HANGING_INDENT', 'VERTICAL_GRID', 'VERTICAL_GRID_GROUPED', + 'VERTICAL_GRID_GROUPED_NO_COMMA', 'NOQA') +WrapModes = namedtuple('WrapModes', WrapModes)(*range(len(WrapModes))) + +# Note that none of these lists must be complete as they are simply fallbacks for when included auto-detection fails. +default = {'force_to_top': [], + 'skip': [], + 'skip_glob': [], + 'line_length': 79, + 'wrap_length': 0, + 'line_ending': None, + 'sections': DEFAULT_SECTIONS, + 'no_sections': False, + 'known_future_library': ['__future__'], + 'known_standard_library': ['AL', 'BaseHTTPServer', 'Bastion', 'CGIHTTPServer', 'Carbon', 'ColorPicker', + 'ConfigParser', 'Cookie', 'DEVICE', 'DocXMLRPCServer', 'EasyDialogs', 'FL', + 'FrameWork', 'GL', 'HTMLParser', 'MacOS', 'MimeWriter', 'MiniAEFrame', 'Nav', + 'PixMapWrapper', 'Queue', 'SUNAUDIODEV', 'ScrolledText', 'SimpleHTTPServer', + 'SimpleXMLRPCServer', 'SocketServer', 'StringIO', 'Tix', 'Tkinter', 'UserDict', + 'UserList', 'UserString', 'W', '__builtin__', 'abc', 'aepack', 'aetools', + 'aetypes', 'aifc', 'al', 'anydbm', 'applesingle', 'argparse', 'array', 'ast', + 'asynchat', 'asyncio', 'asyncore', 'atexit', 'audioop', 'autoGIL', 'base64', + 'bdb', 'binascii', 'binhex', 'bisect', 'bsddb', 'buildtools', 'builtins', + 'bz2', 'cPickle', 'cProfile', 'cStringIO', 'calendar', 'cd', 'cfmfile', 'cgi', + 'cgitb', 'chunk', 'cmath', 'cmd', 'code', 'codecs', 'codeop', 'collections', + 'colorsys', 'commands', 'compileall', 'compiler', 'concurrent', 'configparser', + 'contextlib', 'contextvars', 'cookielib', 'copy', 'copy_reg', 'copyreg', 'crypt', 'csv', + 'ctypes', 'curses', 'dataclasses', 'datetime', 'dbhash', 'dbm', 'decimal', 'difflib', + 'dircache', 'dis', 'distutils', 'dl', 'doctest', 'dumbdbm', 'dummy_thread', + 'dummy_threading', 'email', 'encodings', 'ensurepip', 'enum', 'errno', + 'exceptions', 'faulthandler', 'fcntl', 'filecmp', 'fileinput', 'findertools', + 'fl', 'flp', 'fm', 'fnmatch', 'formatter', 'fpectl', 'fpformat', 'fractions', + 'ftplib', 'functools', 'future_builtins', 'gc', 'gdbm', 'gensuitemodule', + 'getopt', 'getpass', 'gettext', 'gl', 'glob', 'grp', 'gzip', 'hashlib', + 'heapq', 'hmac', 'hotshot', 'html', 'htmlentitydefs', 'htmllib', 'http', + 'httplib', 'ic', 'icopen', 'imageop', 'imaplib', 'imgfile', 'imghdr', 'imp', + 'importlib', 'imputil', 'inspect', 'io', 'ipaddress', 'itertools', 'jpeg', + 'json', 'keyword', 'lib2to3', 'linecache', 'locale', 'logging', 'lzma', + 'macerrors', 'macostools', 'macpath', 'macresource', 'mailbox', 'mailcap', + 'marshal', 'math', 'md5', 'mhlib', 'mimetools', 'mimetypes', 'mimify', 'mmap', + 'modulefinder', 'msilib', 'msvcrt', 'multifile', 'multiprocessing', 'mutex', + 'netrc', 'new', 'nis', 'nntplib', 'numbers', 'operator', 'optparse', 'os', + 'ossaudiodev', 'parser', 'pathlib', 'pdb', 'pickle', 'pickletools', 'pipes', + 'pkgutil', 'platform', 'plistlib', 'popen2', 'poplib', 'posix', 'posixfile', + 'pprint', 'profile', 'pstats', 'pty', 'pwd', 'py_compile', 'pyclbr', 'pydoc', + 'queue', 'quopri', 'random', 're', 'readline', 'reprlib', 'resource', 'rexec', + 'rfc822', 'rlcompleter', 'robotparser', 'runpy', 'sched', 'secrets', 'select', + 'selectors', 'sets', 'sgmllib', 'sha', 'shelve', 'shlex', 'shutil', 'signal', + 'site', 'sitecustomize', 'smtpd', 'smtplib', 'sndhdr', 'socket', 'socketserver', + 'spwd', 'sqlite3', 'ssl', 'stat', 'statistics', 'statvfs', 'string', 'stringprep', + 'struct', 'subprocess', 'sunau', 'sunaudiodev', 'symbol', 'symtable', 'sys', + 'sysconfig', 'syslog', 'tabnanny', 'tarfile', 'telnetlib', 'tempfile', 'termios', + 'test', 'textwrap', 'this', 'thread', 'threading', 'time', 'timeit', 'tkinter', + 'token', 'tokenize', 'trace', 'traceback', 'tracemalloc', 'ttk', 'tty', 'turtle', + 'turtledemo', 'types', 'typing', 'unicodedata', 'unittest', 'urllib', 'urllib2', + 'urlparse', 'usercustomize', 'uu', 'uuid', 'venv', 'videoreader', + 'warnings', 'wave', 'weakref', 'webbrowser', 'whichdb', 'winreg', 'winsound', + 'wsgiref', 'xdrlib', 'xml', 'xmlrpc', 'xmlrpclib', 'zipapp', 'zipfile', + 'zipimport', 'zlib'], + 'known_third_party': ['google.appengine.api'], + 'known_first_party': [], + 'multi_line_output': WrapModes.GRID, + 'forced_separate': [], + 'indent': ' ' * 4, + 'comment_prefix': ' #', + 'length_sort': False, + 'add_imports': [], + 'remove_imports': [], + 'reverse_relative': False, + 'force_single_line': False, + 'default_section': 'FIRSTPARTY', + 'import_heading_future': '', + 'import_heading_stdlib': '', + 'import_heading_thirdparty': '', + 'import_heading_firstparty': '', + 'import_heading_localfolder': '', + 'balanced_wrapping': False, + 'use_parentheses': False, + 'order_by_type': True, + 'atomic': False, + 'lines_after_imports': -1, + 'lines_between_sections': 1, + 'lines_between_types': 0, + 'combine_as_imports': False, + 'combine_star': False, + 'keep_direct_and_as_imports': False, + 'include_trailing_comma': False, + 'from_first': False, + 'verbose': False, + 'quiet': False, + 'force_adds': False, + 'force_alphabetical_sort_within_sections': False, + 'force_alphabetical_sort': False, + 'force_grid_wrap': 0, + 'force_sort_within_sections': False, + 'show_diff': False, + 'ignore_whitespace': False, + 'no_lines_before': [], + 'no_inline_sort': False, + 'ignore_comments': False, + 'safety_excludes': True, + 'case_sensitive': False} + + +@lru_cache() +def from_path(path): + computed_settings = default.copy() + isort_defaults = ['~/.isort.cfg'] + if appdirs: + isort_defaults = [appdirs.user_config_dir('isort.cfg')] + isort_defaults + + _update_settings_with_config(path, '.editorconfig', ['~/.editorconfig'], ('*', '*.py', '**.py'), computed_settings) + _update_settings_with_config(path, 'pyproject.toml', [], ('tool.isort', ), computed_settings) + _update_settings_with_config(path, '.isort.cfg', isort_defaults, ('settings', 'isort'), computed_settings) + _update_settings_with_config(path, 'setup.cfg', [], ('isort', 'tool:isort'), computed_settings) + _update_settings_with_config(path, 'tox.ini', [], ('isort', 'tool:isort'), computed_settings) + return computed_settings + + +def _update_settings_with_config(path, name, default, sections, computed_settings): + editor_config_file = None + for potential_settings_path in default: + expanded = os.path.expanduser(potential_settings_path) + if os.path.exists(expanded): + editor_config_file = expanded + break + + tries = 0 + current_directory = path + while current_directory and tries < MAX_CONFIG_SEARCH_DEPTH: + potential_path = os.path.join(current_directory, str(name)) + if os.path.exists(potential_path): + editor_config_file = potential_path + break + + new_directory = os.path.split(current_directory)[0] + if current_directory == new_directory: + break + current_directory = new_directory + tries += 1 + + if editor_config_file and os.path.exists(editor_config_file): + _update_with_config_file(editor_config_file, sections, computed_settings) + + +def _update_with_config_file(file_path, sections, computed_settings): + cwd = os.path.dirname(file_path) + settings = _get_config_data(file_path, sections).copy() + if not settings: + return + + if file_path.endswith('.editorconfig'): + indent_style = settings.pop('indent_style', '').strip() + indent_size = settings.pop('indent_size', '').strip() + if indent_size == "tab": + indent_size = settings.pop('tab_width', '').strip() + + if indent_style == 'space': + computed_settings['indent'] = ' ' * (indent_size and int(indent_size) or 4) + elif indent_style == 'tab': + computed_settings['indent'] = '\t' * (indent_size and int(indent_size) or 1) + + max_line_length = settings.pop('max_line_length', '').strip() + if max_line_length: + computed_settings['line_length'] = float('inf') if max_line_length == 'off' else int(max_line_length) + + for key, value in settings.items(): + access_key = key.replace('not_', '').lower() + existing_value_type = type(default.get(access_key, '')) + if existing_value_type in (list, tuple): + # sections has fixed order values; no adding or substraction from any set + if access_key == 'sections': + computed_settings[access_key] = tuple(_as_list(value)) + else: + existing_data = set(computed_settings.get(access_key, default.get(access_key))) + if key.startswith('not_'): + computed_settings[access_key] = difference(existing_data, _as_list(value)) + elif key.startswith('known_'): + computed_settings[access_key] = union(existing_data, _abspaths(cwd, _as_list(value))) + else: + computed_settings[access_key] = union(existing_data, _as_list(value)) + elif existing_value_type == bool: + # Only some configuration formats support native boolean values. + if not isinstance(value, bool): + value = bool(strtobool(value)) + computed_settings[access_key] = value + elif key.startswith('known_'): + computed_settings[access_key] = list(_abspaths(cwd, _as_list(value))) + elif key == 'force_grid_wrap': + try: + result = existing_value_type(value) + except ValueError: + # backwards compat + result = default.get(access_key) if value.lower().strip() == 'false' else 2 + computed_settings[access_key] = result + else: + computed_settings[access_key] = existing_value_type(value) + + +def _as_list(value): + if not isinstance(value, list): + value = value.replace('\n', ',').split(',') + + return filter(bool, [item.strip() for item in value]) + + +def _abspaths(cwd, values): + paths = [ + os.path.join(cwd, value) + if not value.startswith(os.path.sep) and value.endswith(os.path.sep) + else value + for value in values + ] + return paths + + +@lru_cache() +def _get_config_data(file_path, sections): + settings = {} + + with io.open(file_path) as config_file: + if file_path.endswith('.toml'): + if toml: + config = toml.load(config_file) + for section in sections: + config_section = config + for key in section.split('.'): + config_section = config_section.get(key, {}) + settings.update(config_section) + else: + if '[tool.isort]' in config_file.read(): + warnings.warn("Found {} with [tool.isort] section, but toml package is not installed. " + "To configure isort with {}, install with 'isort[pyproject]'.".format(file_path, + file_path)) + else: + if file_path.endswith('.editorconfig'): + line = '\n' + last_position = config_file.tell() + while line: + line = config_file.readline() + if '[' in line: + config_file.seek(last_position) + break + last_position = config_file.tell() + + if sys.version_info >= (3, 2): + config = configparser.ConfigParser(strict=False) + config.read_file(config_file) + else: + config = configparser.SafeConfigParser() + config.readfp(config_file) + + for section in sections: + if config.has_section(section): + settings.update(config.items(section)) + + return settings + + +def should_skip(filename, config, path=''): + """Returns True if the file and/or folder should be skipped based on the passed in settings.""" + os_path = os.path.join(path, filename) + + normalized_path = os_path.replace('\\', '/') + if normalized_path[1:2] == ':': + normalized_path = normalized_path[2:] + + if path and config['safety_excludes']: + check_exclude = '/' + filename.replace('\\', '/') + '/' + if path and os.path.basename(path) in ('lib', ): + check_exclude = '/' + os.path.basename(path) + check_exclude + if safety_exclude_re.search(check_exclude): + return True + + for skip_path in config['skip']: + if posixpath.abspath(normalized_path) == posixpath.abspath(skip_path.replace('\\', '/')): + return True + + position = os.path.split(filename) + while position[1]: + if position[1] in config['skip']: + return True + position = os.path.split(position[0]) + + for glob in config['skip_glob']: + if fnmatch.fnmatch(filename, glob) or fnmatch.fnmatch('/' + filename, glob): + return True + + if not (os.path.isfile(os_path) or os.path.isdir(os_path) or os.path.islink(os_path)): + return True + + return False diff --git a/py3/lib/python3.6/site-packages/isort/utils.py b/py3/lib/python3.6/site-packages/isort/utils.py new file mode 100644 index 0000000..ce4e588 --- /dev/null +++ b/py3/lib/python3.6/site-packages/isort/utils.py @@ -0,0 +1,53 @@ +import os +import sys +from contextlib import contextmanager + + +def exists_case_sensitive(path): + """ + Returns if the given path exists and also matches the case on Windows. + + When finding files that can be imported, it is important for the cases to match because while + file os.path.exists("module.py") and os.path.exists("MODULE.py") both return True on Windows, Python + can only import using the case of the real file. + """ + result = os.path.exists(path) + if (sys.platform.startswith('win') or sys.platform == 'darwin') and result: + directory, basename = os.path.split(path) + result = basename in os.listdir(directory) + return result + + +@contextmanager +def chdir(path): + """Context manager for changing dir and restoring previous workdir after exit. + """ + curdir = os.getcwd() + os.chdir(path) + try: + yield + finally: + os.chdir(curdir) + + +def union(a, b): + """ Return a list of items that are in `a` or `b` + """ + u = [] + for item in a: + if item not in u: + u.append(item) + for item in b: + if item not in u: + u.append(item) + return u + + +def difference(a, b): + """ Return a list of items from `a` that are not in `b`. + """ + d = [] + for item in a: + if item not in b: + d.append(item) + return d diff --git a/py3/lib/python3.6/site-packages/python_socketio-4.3.1.dist-info/INSTALLER b/py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/INSTALLER similarity index 100% rename from py3/lib/python3.6/site-packages/python_socketio-4.3.1.dist-info/INSTALLER rename to py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/INSTALLER diff --git a/py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/METADATA b/py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/METADATA new file mode 100644 index 0000000..6b4b830 --- /dev/null +++ b/py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/METADATA @@ -0,0 +1,166 @@ +Metadata-Version: 2.1 +Name: lazy-object-proxy +Version: 1.4.3 +Summary: A fast and thorough lazy object proxy. +Home-page: https://github.com/ionelmc/python-lazy-object-proxy +Author: Ionel Cristian Mărieș +Author-email: contact@ionelmc.ro +License: BSD-2-Clause +Project-URL: Documentation, https://python-lazy-object-proxy.readthedocs.io/ +Project-URL: Changelog, https://python-lazy-object-proxy.readthedocs.io/en/latest/changelog.html +Project-URL: Issue Tracker, https://github.com/ionelmc/python-lazy-object-proxy/issues +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: Unix +Classifier: Operating System :: POSIX +Classifier: Operating System :: Microsoft :: Windows +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Utilities +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* + +======== +Overview +======== + + + +A fast and thorough lazy object proxy. + +* Free software: BSD 2-Clause License + +Note that this is based on `wrapt`_'s ObjectProxy with one big change: it calls a function the first time the proxy object is +used, while `wrapt.ObjectProxy` just forwards the method calls to the target object. + +In other words, you use `lazy-object-proxy` when you only have the object way later and you use `wrapt.ObjectProxy` when you +want to override few methods (by subclassing) and forward everything else to the target object. + +Example:: + + import lazy_object_proxy + + def expensive_func(): + from time import sleep + print('starting calculation') + # just as example for a very slow computation + sleep(2) + print('finished calculation') + # return the result of the calculation + return 10 + + obj = lazy_object_proxy.Proxy(expensive_func) + # function is called only when object is actually used + print(obj) # now expensive_func is called + + print(obj) # the result without calling the expensive_func + +Installation +============ + +:: + + pip install lazy-object-proxy + +Documentation +============= + +https://python-lazy-object-proxy.readthedocs.io/ + +Development +=========== + +To run the all tests run:: + + tox + +Acknowledgements +================ + +This project is based on some code from `wrapt`_ as you can see in the git history. + +.. _wrapt: https://github.com/GrahamDumpleton/wrapt + + +Changelog +========= + +1.4.3 (2019-10-26) +------------------ + +* Added binary wheels for Python 3.8. +* Fixed license metadata. + +1.4.2 (2019-08-22) +------------------ + +* Included a ``pyproject.toml`` to allow users install the sdist with old python/setuptools, as the + setuptools-scm dep will be fetched by pip instead of setuptools. + Fixes `#30 `_. + +1.4.1 (2019-05-10) +------------------ + +* Fixed wheels being built with ``-coverage`` cflags. No more issues about bogus ``cext.gcda`` files. +* Removed useless C file from wheels. +* Changed ``setup.py`` to use setuptools-scm. + +1.4.0 (2019-05-05) +------------------ + +* Fixed ``__mod__`` for the slots backend. Contributed by Ran Benita in + `#28 `_. +* Dropped support for Python 2.6 and 3.3. Contributed by "hugovk" in + `#24 `_. + +1.3.1 (2017-05-05) +------------------ + +* Fix broken release (``sdist`` had a broken ``MANIFEST.in``). + +1.3.0 (2017-05-02) +------------------ + +* Speed up arithmetic operations involving ``cext.Proxy`` subclasses. + +1.2.2 (2016-04-14) +------------------ + +* Added `manylinux `_ wheels. +* Minor cleanup in readme. + +1.2.1 (2015-08-18) +------------------ + +* Fix a memory leak (the wrapped object would get bogus references). Contributed by Astrum Kuo in + `#10 `_. + +1.2.0 (2015-07-06) +------------------ + +* Don't instantiate the object when __repr__ is called. This aids with debugging (allows one to see exactly in + what state the proxy is). + +1.1.0 (2015-07-05) +------------------ + +* Added support for pickling. The pickled value is going to be the wrapped object *without* any Proxy container. +* Fixed a memory management issue in the C extension (reference cycles weren't garbage collected due to improper + handling in the C extension). Contributed by Alvin Chow in + `#8 `_. + +1.0.2 (2015-04-11) +----------------------------------------- + +* First release on PyPI. + + diff --git a/py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/RECORD b/py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/RECORD new file mode 100644 index 0000000..20e7bbe --- /dev/null +++ b/py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/RECORD @@ -0,0 +1,18 @@ +lazy_object_proxy/_version.py,sha256=ALahZZsa-Z4ZoXe2iDIs4ajidCOW695W5leOWijWYEc,116 +lazy_object_proxy/simple.py,sha256=guacy8_QbJeBs7vXpPPVoDVkDNXOZ86xyS1dtAeKvOs,8216 +lazy_object_proxy/utils.py,sha256=x4XTrtlp_mDTWO_EOq_ILIOv2Qol8RLMnRm5M8l3OfU,291 +lazy_object_proxy/compat.py,sha256=DY3HbKwbrbeKY6tkXRNRLJ1go6HJb8HUwWqyw3T5g_g,196 +lazy_object_proxy/cext.cpython-36m-x86_64-linux-gnu.so,sha256=BeY6RSDLFKKRnlbx25ZwobTkjkdu5AAsyu0KepzAcsA,160608 +lazy_object_proxy/__init__.py,sha256=pMqxzToF24DuzOltm-Q8nZ3jNDXOaSQcJmiNArdUrlU,410 +lazy_object_proxy/slots.py,sha256=9DilWUINScpZN26NwmRtscTtaqaEwtCfIoriLq5Nz24,11359 +lazy_object_proxy-1.4.3.dist-info/top_level.txt,sha256=UNH-FQB-j_8bYqPz3gD90kHvaC42TQqY0thHSnbaa0k,18 +lazy_object_proxy-1.4.3.dist-info/RECORD,, +lazy_object_proxy-1.4.3.dist-info/METADATA,sha256=Y2X63wcFbQT4yI3zKpRFwfpA_TCpB6U79MPmRGCMJT0,5088 +lazy_object_proxy-1.4.3.dist-info/WHEEL,sha256=d2ILPScH-y2UwGxsW1PeA2TT-KW0Git4AJ6LeOK8sQo,109 +lazy_object_proxy-1.4.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +lazy_object_proxy/__pycache__/_version.cpython-36.pyc,, +lazy_object_proxy/__pycache__/simple.cpython-36.pyc,, +lazy_object_proxy/__pycache__/__init__.cpython-36.pyc,, +lazy_object_proxy/__pycache__/slots.cpython-36.pyc,, +lazy_object_proxy/__pycache__/utils.cpython-36.pyc,, +lazy_object_proxy/__pycache__/compat.cpython-36.pyc,, diff --git a/py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/WHEEL b/py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/WHEEL new file mode 100644 index 0000000..92946fe --- /dev/null +++ b/py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.31.1) +Root-Is-Purelib: false +Tag: cp36-cp36m-manylinux1_x86_64 + diff --git a/py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/top_level.txt b/py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/top_level.txt new file mode 100644 index 0000000..bdf032e --- /dev/null +++ b/py3/lib/python3.6/site-packages/lazy_object_proxy-1.4.3.dist-info/top_level.txt @@ -0,0 +1 @@ +lazy_object_proxy diff --git a/py3/lib/python3.6/site-packages/lazy_object_proxy/__init__.py b/py3/lib/python3.6/site-packages/lazy_object_proxy/__init__.py new file mode 100644 index 0000000..e9a9a76 --- /dev/null +++ b/py3/lib/python3.6/site-packages/lazy_object_proxy/__init__.py @@ -0,0 +1,23 @@ +try: + import copy_reg as copyreg +except ImportError: + import copyreg + +from .utils import identity + +copyreg.constructor(identity) + +try: + from .cext import Proxy + from .cext import identity +except ImportError: + from .slots import Proxy +else: + copyreg.constructor(identity) + +try: + from ._version import version as __version__ +except ImportError: + __version__ = '1.4.3' + +__all__ = "Proxy", diff --git a/py3/lib/python3.6/site-packages/lazy_object_proxy/_version.py b/py3/lib/python3.6/site-packages/lazy_object_proxy/_version.py new file mode 100644 index 0000000..3136771 --- /dev/null +++ b/py3/lib/python3.6/site-packages/lazy_object_proxy/_version.py @@ -0,0 +1,4 @@ +# coding: utf-8 +# file generated by setuptools_scm +# don't change, don't track in version control +version = '1.4.3' diff --git a/py3/lib/python3.6/site-packages/lazy_object_proxy/cext.cpython-36m-x86_64-linux-gnu.so b/py3/lib/python3.6/site-packages/lazy_object_proxy/cext.cpython-36m-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..66c6ce99466efe7eb28f443cdfc114f4c4dac46b GIT binary patch literal 160608 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

h1ci<%A|J_3VpakDYq=585qJvh_? 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

mkg!f1Q!pAhiT~qE70##^7DL|r^KZ? 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 E19~$9$N&HU literal 0 HcmV?d00001 diff --git a/py3/lib/python3.6/site-packages/lazy_object_proxy/compat.py b/py3/lib/python3.6/site-packages/lazy_object_proxy/compat.py new file mode 100644 index 0000000..dc6edfa --- /dev/null +++ b/py3/lib/python3.6/site-packages/lazy_object_proxy/compat.py @@ -0,0 +1,9 @@ +import sys + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + return meta("NewBase", bases, {}) diff --git a/py3/lib/python3.6/site-packages/lazy_object_proxy/simple.py b/py3/lib/python3.6/site-packages/lazy_object_proxy/simple.py new file mode 100644 index 0000000..24b1339 --- /dev/null +++ b/py3/lib/python3.6/site-packages/lazy_object_proxy/simple.py @@ -0,0 +1,246 @@ +import operator + +from .compat import PY2 +from .compat import PY3 +from .compat import with_metaclass +from .utils import cached_property +from .utils import identity + + +def make_proxy_method(code): + def proxy_wrapper(self, *args): + return code(self.__wrapped__, *args) + + return proxy_wrapper + + +class _ProxyMethods(object): + # We use properties to override the values of __module__ and + # __doc__. If we add these in ObjectProxy, the derived class + # __dict__ will still be setup to have string variants of these + # attributes and the rules of descriptors means that they appear to + # take precedence over the properties in the base class. To avoid + # that, we copy the properties into the derived class type itself + # via a meta class. In that way the properties will always take + # precedence. + + @property + def __module__(self): + return self.__wrapped__.__module__ + + @__module__.setter + def __module__(self, value): + self.__wrapped__.__module__ = value + + @property + def __doc__(self): + return self.__wrapped__.__doc__ + + @__doc__.setter + def __doc__(self, value): + self.__wrapped__.__doc__ = value + + # Need to also propagate the special __weakref__ attribute for case + # where decorating classes which will define this. If do not define + # it and use a function like inspect.getmembers() on a decorator + # class it will fail. This can't be in the derived classes. + + @property + def __weakref__(self): + return self.__wrapped__.__weakref__ + + +class _ProxyMetaType(type): + def __new__(cls, name, bases, dictionary): + # Copy our special properties into the class so that they + # always take precedence over attributes of the same name added + # during construction of a derived class. This is to save + # duplicating the implementation for them in all derived classes. + + dictionary.update(vars(_ProxyMethods)) + dictionary.pop('__dict__') + + return type.__new__(cls, name, bases, dictionary) + + +class Proxy(with_metaclass(_ProxyMetaType)): + __factory__ = None + + def __init__(self, factory): + self.__dict__['__factory__'] = factory + + @cached_property + def __wrapped__(self): + self = self.__dict__ + if '__factory__' in self: + factory = self['__factory__'] + return factory() + else: + raise ValueError("Proxy hasn't been initiated: __factory__ is missing.") + + __name__ = property(make_proxy_method(operator.attrgetter('__name__'))) + __class__ = property(make_proxy_method(operator.attrgetter('__class__'))) + __annotations__ = property(make_proxy_method(operator.attrgetter('__anotations__'))) + __dir__ = make_proxy_method(dir) + __str__ = make_proxy_method(str) + + if PY3: + __bytes__ = make_proxy_method(bytes) + + def __repr__(self, __getattr__=object.__getattribute__): + if '__wrapped__' in self.__dict__: + return '<{} at 0x{:x} wrapping {!r} at 0x{:x} with factory {!r}>'.format( + type(self).__name__, id(self), + self.__wrapped__, id(self.__wrapped__), + self.__factory__ + ) + else: + return '<{} at 0x{:x} with factory {!r}>'.format( + type(self).__name__, id(self), + self.__factory__ + ) + + __reversed__ = make_proxy_method(reversed) + + if PY3: + __round__ = make_proxy_method(round) + + __lt__ = make_proxy_method(operator.lt) + __le__ = make_proxy_method(operator.le) + __eq__ = make_proxy_method(operator.eq) + __ne__ = make_proxy_method(operator.ne) + __gt__ = make_proxy_method(operator.gt) + __ge__ = make_proxy_method(operator.ge) + __hash__ = make_proxy_method(hash) + __nonzero__ = make_proxy_method(bool) + __bool__ = make_proxy_method(bool) + + def __setattr__(self, name, value): + if hasattr(type(self), name): + self.__dict__[name] = value + else: + setattr(self.__wrapped__, name, value) + + def __getattr__(self, name): + if name in ('__wrapped__', '__factory__'): + raise AttributeError(name) + else: + return getattr(self.__wrapped__, name) + + def __delattr__(self, name): + if hasattr(type(self), name): + del self.__dict__[name] + else: + delattr(self.__wrapped__, name) + + __add__ = make_proxy_method(operator.add) + __sub__ = make_proxy_method(operator.sub) + __mul__ = make_proxy_method(operator.mul) + __div__ = make_proxy_method(operator.div if PY2 else operator.truediv) + __truediv__ = make_proxy_method(operator.truediv) + __floordiv__ = make_proxy_method(operator.floordiv) + __mod__ = make_proxy_method(operator.mod) + __divmod__ = make_proxy_method(divmod) + __pow__ = make_proxy_method(pow) + __lshift__ = make_proxy_method(operator.lshift) + __rshift__ = make_proxy_method(operator.rshift) + __and__ = make_proxy_method(operator.and_) + __xor__ = make_proxy_method(operator.xor) + __or__ = make_proxy_method(operator.or_) + + def __radd__(self, other): + return other + self.__wrapped__ + + def __rsub__(self, other): + return other - self.__wrapped__ + + def __rmul__(self, other): + return other * self.__wrapped__ + + def __rdiv__(self, other): + return operator.div(other, self.__wrapped__) + + def __rtruediv__(self, other): + return operator.truediv(other, self.__wrapped__) + + def __rfloordiv__(self, other): + return other // self.__wrapped__ + + def __rmod__(self, other): + return other % self.__wrapped__ + + def __rdivmod__(self, other): + return divmod(other, self.__wrapped__) + + def __rpow__(self, other, *args): + return pow(other, self.__wrapped__, *args) + + def __rlshift__(self, other): + return other << self.__wrapped__ + + def __rrshift__(self, other): + return other >> self.__wrapped__ + + def __rand__(self, other): + return other & self.__wrapped__ + + def __rxor__(self, other): + return other ^ self.__wrapped__ + + def __ror__(self, other): + return other | self.__wrapped__ + + __iadd__ = make_proxy_method(operator.iadd) + __isub__ = make_proxy_method(operator.isub) + __imul__ = make_proxy_method(operator.imul) + __idiv__ = make_proxy_method(operator.idiv if PY2 else operator.itruediv) + __itruediv__ = make_proxy_method(operator.itruediv) + __ifloordiv__ = make_proxy_method(operator.ifloordiv) + __imod__ = make_proxy_method(operator.imod) + __ipow__ = make_proxy_method(operator.ipow) + __ilshift__ = make_proxy_method(operator.ilshift) + __irshift__ = make_proxy_method(operator.irshift) + __iand__ = make_proxy_method(operator.iand) + __ixor__ = make_proxy_method(operator.ixor) + __ior__ = make_proxy_method(operator.ior) + __neg__ = make_proxy_method(operator.neg) + __pos__ = make_proxy_method(operator.pos) + __abs__ = make_proxy_method(operator.abs) + __invert__ = make_proxy_method(operator.invert) + + __int__ = make_proxy_method(int) + + if PY2: + __long__ = make_proxy_method(long) # noqa + + __float__ = make_proxy_method(float) + __oct__ = make_proxy_method(oct) + __hex__ = make_proxy_method(hex) + __index__ = make_proxy_method(operator.index) + __len__ = make_proxy_method(len) + __contains__ = make_proxy_method(operator.contains) + __getitem__ = make_proxy_method(operator.getitem) + __setitem__ = make_proxy_method(operator.setitem) + __delitem__ = make_proxy_method(operator.delitem) + + if PY2: + __getslice__ = make_proxy_method(operator.getslice) + __setslice__ = make_proxy_method(operator.setslice) + __delslice__ = make_proxy_method(operator.delslice) + + def __enter__(self): + return self.__wrapped__.__enter__() + + def __exit__(self, *args, **kwargs): + return self.__wrapped__.__exit__(*args, **kwargs) + + __iter__ = make_proxy_method(iter) + + def __call__(self, *args, **kwargs): + return self.__wrapped__(*args, **kwargs) + + def __reduce__(self): + return identity, (self.__wrapped__,) + + def __reduce_ex__(self, protocol): + return identity, (self.__wrapped__,) diff --git a/py3/lib/python3.6/site-packages/lazy_object_proxy/slots.py b/py3/lib/python3.6/site-packages/lazy_object_proxy/slots.py new file mode 100644 index 0000000..efb08db --- /dev/null +++ b/py3/lib/python3.6/site-packages/lazy_object_proxy/slots.py @@ -0,0 +1,414 @@ +import operator + +from .compat import PY2 +from .compat import PY3 +from .compat import with_metaclass +from .utils import identity + + +class _ProxyMethods(object): + # We use properties to override the values of __module__ and + # __doc__. If we add these in ObjectProxy, the derived class + # __dict__ will still be setup to have string variants of these + # attributes and the rules of descriptors means that they appear to + # take precedence over the properties in the base class. To avoid + # that, we copy the properties into the derived class type itself + # via a meta class. In that way the properties will always take + # precedence. + + @property + def __module__(self): + return self.__wrapped__.__module__ + + @__module__.setter + def __module__(self, value): + self.__wrapped__.__module__ = value + + @property + def __doc__(self): + return self.__wrapped__.__doc__ + + @__doc__.setter + def __doc__(self, value): + self.__wrapped__.__doc__ = value + + # We similar use a property for __dict__. We need __dict__ to be + # explicit to ensure that vars() works as expected. + + @property + def __dict__(self): + return self.__wrapped__.__dict__ + + # Need to also propagate the special __weakref__ attribute for case + # where decorating classes which will define this. If do not define + # it and use a function like inspect.getmembers() on a decorator + # class it will fail. This can't be in the derived classes. + + @property + def __weakref__(self): + return self.__wrapped__.__weakref__ + + +class _ProxyMetaType(type): + def __new__(cls, name, bases, dictionary): + # Copy our special properties into the class so that they + # always take precedence over attributes of the same name added + # during construction of a derived class. This is to save + # duplicating the implementation for them in all derived classes. + + dictionary.update(vars(_ProxyMethods)) + + return type.__new__(cls, name, bases, dictionary) + + +class Proxy(with_metaclass(_ProxyMetaType)): + """ + A proxy implementation in pure Python, using slots. You can subclass this to add + local methods or attributes, or enable __dict__. + + The most important internals: + + * ``__factory__`` is the callback that "materializes" the object we proxy to. + * ``__target__`` will contain the object we proxy to, once it's "materialized". + * ``__wrapped__`` is a property that does either: + + * return ``__target__`` if it's set. + * calls ``__factory__``, saves result to ``__target__`` and returns said result. + """ + + __slots__ = '__target__', '__factory__' + + def __init__(self, factory): + object.__setattr__(self, '__factory__', factory) + + @property + def __wrapped__(self, __getattr__=object.__getattribute__, __setattr__=object.__setattr__, + __delattr__=object.__delattr__): + try: + return __getattr__(self, '__target__') + except AttributeError: + try: + factory = __getattr__(self, '__factory__') + except AttributeError: + raise ValueError("Proxy hasn't been initiated: __factory__ is missing.") + target = factory() + __setattr__(self, '__target__', target) + return target + + @__wrapped__.deleter + def __wrapped__(self, __delattr__=object.__delattr__): + __delattr__(self, '__target__') + + @__wrapped__.setter + def __wrapped__(self, target, __setattr__=object.__setattr__): + __setattr__(self, '__target__', target) + + @property + def __name__(self): + return self.__wrapped__.__name__ + + @__name__.setter + def __name__(self, value): + self.__wrapped__.__name__ = value + + @property + def __class__(self): + return self.__wrapped__.__class__ + + @__class__.setter # noqa + def __class__(self, value): + self.__wrapped__.__class__ = value + + @property + def __annotations__(self): + return self.__wrapped__.__anotations__ + + @__annotations__.setter + def __annotations__(self, value): + self.__wrapped__.__annotations__ = value + + def __dir__(self): + return dir(self.__wrapped__) + + def __str__(self): + return str(self.__wrapped__) + + if PY3: + def __bytes__(self): + return bytes(self.__wrapped__) + + def __repr__(self, __getattr__=object.__getattribute__): + try: + target = __getattr__(self, '__target__') + except AttributeError: + return '<{} at 0x{:x} with factory {!r}>'.format( + type(self).__name__, id(self), + self.__factory__ + ) + else: + return '<{} at 0x{:x} wrapping {!r} at 0x{:x} with factory {!r}>'.format( + type(self).__name__, id(self), + target, id(target), + self.__factory__ + ) + + def __reversed__(self): + return reversed(self.__wrapped__) + + if PY3: + def __round__(self): + return round(self.__wrapped__) + + def __lt__(self, other): + return self.__wrapped__ < other + + def __le__(self, other): + return self.__wrapped__ <= other + + def __eq__(self, other): + return self.__wrapped__ == other + + def __ne__(self, other): + return self.__wrapped__ != other + + def __gt__(self, other): + return self.__wrapped__ > other + + def __ge__(self, other): + return self.__wrapped__ >= other + + def __hash__(self): + return hash(self.__wrapped__) + + def __nonzero__(self): + return bool(self.__wrapped__) + + def __bool__(self): + return bool(self.__wrapped__) + + def __setattr__(self, name, value, __setattr__=object.__setattr__): + if hasattr(type(self), name): + __setattr__(self, name, value) + else: + setattr(self.__wrapped__, name, value) + + def __getattr__(self, name): + if name in ('__wrapped__', '__factory__'): + raise AttributeError(name) + else: + return getattr(self.__wrapped__, name) + + def __delattr__(self, name, __delattr__=object.__delattr__): + if hasattr(type(self), name): + __delattr__(self, name) + else: + delattr(self.__wrapped__, name) + + def __add__(self, other): + return self.__wrapped__ + other + + def __sub__(self, other): + return self.__wrapped__ - other + + def __mul__(self, other): + return self.__wrapped__ * other + + def __div__(self, other): + return operator.div(self.__wrapped__, other) + + def __truediv__(self, other): + return operator.truediv(self.__wrapped__, other) + + def __floordiv__(self, other): + return self.__wrapped__ // other + + def __mod__(self, other): + return self.__wrapped__ % other + + def __divmod__(self, other): + return divmod(self.__wrapped__, other) + + def __pow__(self, other, *args): + return pow(self.__wrapped__, other, *args) + + def __lshift__(self, other): + return self.__wrapped__ << other + + def __rshift__(self, other): + return self.__wrapped__ >> other + + def __and__(self, other): + return self.__wrapped__ & other + + def __xor__(self, other): + return self.__wrapped__ ^ other + + def __or__(self, other): + return self.__wrapped__ | other + + def __radd__(self, other): + return other + self.__wrapped__ + + def __rsub__(self, other): + return other - self.__wrapped__ + + def __rmul__(self, other): + return other * self.__wrapped__ + + def __rdiv__(self, other): + return operator.div(other, self.__wrapped__) + + def __rtruediv__(self, other): + return operator.truediv(other, self.__wrapped__) + + def __rfloordiv__(self, other): + return other // self.__wrapped__ + + def __rmod__(self, other): + return other % self.__wrapped__ + + def __rdivmod__(self, other): + return divmod(other, self.__wrapped__) + + def __rpow__(self, other, *args): + return pow(other, self.__wrapped__, *args) + + def __rlshift__(self, other): + return other << self.__wrapped__ + + def __rrshift__(self, other): + return other >> self.__wrapped__ + + def __rand__(self, other): + return other & self.__wrapped__ + + def __rxor__(self, other): + return other ^ self.__wrapped__ + + def __ror__(self, other): + return other | self.__wrapped__ + + def __iadd__(self, other): + self.__wrapped__ += other + return self + + def __isub__(self, other): + self.__wrapped__ -= other + return self + + def __imul__(self, other): + self.__wrapped__ *= other + return self + + def __idiv__(self, other): + self.__wrapped__ = operator.idiv(self.__wrapped__, other) + return self + + def __itruediv__(self, other): + self.__wrapped__ = operator.itruediv(self.__wrapped__, other) + return self + + def __ifloordiv__(self, other): + self.__wrapped__ //= other + return self + + def __imod__(self, other): + self.__wrapped__ %= other + return self + + def __ipow__(self, other): + self.__wrapped__ **= other + return self + + def __ilshift__(self, other): + self.__wrapped__ <<= other + return self + + def __irshift__(self, other): + self.__wrapped__ >>= other + return self + + def __iand__(self, other): + self.__wrapped__ &= other + return self + + def __ixor__(self, other): + self.__wrapped__ ^= other + return self + + def __ior__(self, other): + self.__wrapped__ |= other + return self + + def __neg__(self): + return -self.__wrapped__ + + def __pos__(self): + return +self.__wrapped__ + + def __abs__(self): + return abs(self.__wrapped__) + + def __invert__(self): + return ~self.__wrapped__ + + def __int__(self): + return int(self.__wrapped__) + + if PY2: + def __long__(self): + return long(self.__wrapped__) # noqa + + def __float__(self): + return float(self.__wrapped__) + + def __oct__(self): + return oct(self.__wrapped__) + + def __hex__(self): + return hex(self.__wrapped__) + + def __index__(self): + return operator.index(self.__wrapped__) + + def __len__(self): + return len(self.__wrapped__) + + def __contains__(self, value): + return value in self.__wrapped__ + + def __getitem__(self, key): + return self.__wrapped__[key] + + def __setitem__(self, key, value): + self.__wrapped__[key] = value + + def __delitem__(self, key): + del self.__wrapped__[key] + + def __getslice__(self, i, j): + return self.__wrapped__[i:j] + + def __setslice__(self, i, j, value): + self.__wrapped__[i:j] = value + + def __delslice__(self, i, j): + del self.__wrapped__[i:j] + + def __enter__(self): + return self.__wrapped__.__enter__() + + def __exit__(self, *args, **kwargs): + return self.__wrapped__.__exit__(*args, **kwargs) + + def __iter__(self): + return iter(self.__wrapped__) + + def __call__(self, *args, **kwargs): + return self.__wrapped__(*args, **kwargs) + + def __reduce__(self): + return identity, (self.__wrapped__,) + + def __reduce_ex__(self, protocol): + return identity, (self.__wrapped__,) diff --git a/py3/lib/python3.6/site-packages/lazy_object_proxy/utils.py b/py3/lib/python3.6/site-packages/lazy_object_proxy/utils.py new file mode 100644 index 0000000..ceb3050 --- /dev/null +++ b/py3/lib/python3.6/site-packages/lazy_object_proxy/utils.py @@ -0,0 +1,13 @@ +def identity(obj): + return obj + + +class cached_property(object): + def __init__(self, func): + self.func = func + + def __get__(self, obj, cls): + if obj is None: + return self + value = obj.__dict__[self.func.__name__] = self.func(obj) + return value diff --git a/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/DESCRIPTION.rst b/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..de61068 --- /dev/null +++ b/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/DESCRIPTION.rst @@ -0,0 +1,152 @@ +McCabe complexity checker +========================= + +Ned's script to check McCabe complexity. + +This module provides a plugin for ``flake8``, the Python code checker. + + +Installation +------------ + +You can install, upgrade, uninstall ``mccabe`` with these commands:: + + $ pip install mccabe + $ pip install --upgrade mccabe + $ pip uninstall mccabe + + +Standalone script +----------------- + +The complexity checker can be used directly:: + + $ python -m mccabe --min 5 mccabe.py + ("185:1: 'PathGraphingAstVisitor.visitIf'", 5) + ("71:1: 'PathGraph.to_dot'", 5) + ("245:1: 'McCabeChecker.run'", 5) + ("283:1: 'main'", 7) + ("203:1: 'PathGraphingAstVisitor.visitTryExcept'", 5) + ("257:1: 'get_code_complexity'", 5) + + +Plugin for Flake8 +----------------- + +When both ``flake8 2.0`` and ``mccabe`` are installed, the plugin is +available in ``flake8``:: + + $ flake8 --version + 2.0 (pep8: 1.4.2, pyflakes: 0.6.1, mccabe: 0.2) + +By default the plugin is disabled. Use the ``--max-complexity`` switch to +enable it. It will emit a warning if the McCabe complexity of a function is +higher that the value:: + + $ flake8 --max-complexity 10 coolproject + ... + coolproject/mod.py:1204:1: C901 'CoolFactory.prepare' is too complex (14) + +This feature is quite useful to detect over-complex code. According to McCabe, +anything that goes beyond 10 is too complex. + + +Links +----- + +* Feedback and ideas: http://mail.python.org/mailman/listinfo/code-quality + +* Cyclomatic complexity: http://en.wikipedia.org/wiki/Cyclomatic_complexity. + +* Ned Batchelder's script: + http://nedbatchelder.com/blog/200803/python_code_complexity_microtool.html + + +Changes +------- + +0.6.1 - 2017-01-26 +`````````````````` + +* Fix signature for ``PathGraphingAstVisitor.default`` to match the signature + for ``ASTVisitor`` + +0.6.0 - 2017-01-23 +`````````````````` + +* Add support for Python 3.6 + +* Fix handling for missing statement types + +0.5.3 - 2016-12-14 +`````````````````` + +* Report actual column number of violation instead of the start of the line + +0.5.2 - 2016-07-31 +`````````````````` + +* When opening files ourselves, make sure we always name the file variable + +0.5.1 - 2016-07-28 +`````````````````` + +* Set default maximum complexity to -1 on the class itself + +0.5.0 - 2016-05-30 +`````````````````` + +* PyCon 2016 PDX release + +* Add support for Flake8 3.0 + +0.4.0 - 2016-01-27 +`````````````````` + +* Stop testing on Python 3.2 + +* Add support for async/await keywords on Python 3.5 from PEP 0492 + +0.3.1 - 2015-06-14 +`````````````````` + +* Include ``test_mccabe.py`` in releases. + +* Always coerce the ``max_complexity`` value from Flake8's entry-point to an + integer. + +0.3 - 2014-12-17 +```````````````` + +* Computation was wrong: the mccabe complexity starts at 1, not 2. + +* The ``max-complexity`` value is now inclusive. E.g.: if the + value is 10 and the reported complexity is 10, then it passes. + +* Add tests. + + +0.2.1 - 2013-04-03 +`````````````````` + +* Do not require ``setuptools`` in setup.py. It works around an issue + with ``pip`` and Python 3. + + +0.2 - 2013-02-22 +```````````````` + +* Rename project to ``mccabe``. + +* Provide ``flake8.extension`` setuptools entry point. + +* Read ``max-complexity`` from the configuration file. + +* Rename argument ``min_complexity`` to ``threshold``. + + +0.1 - 2013-02-11 +```````````````` +* First release + + diff --git a/py3/lib/python3.6/site-packages/setuptools-3.3.dist-info/INSTALLER b/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/INSTALLER similarity index 100% rename from py3/lib/python3.6/site-packages/setuptools-3.3.dist-info/INSTALLER rename to py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/INSTALLER diff --git a/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/METADATA b/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/METADATA new file mode 100644 index 0000000..f22645f --- /dev/null +++ b/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/METADATA @@ -0,0 +1,178 @@ +Metadata-Version: 2.0 +Name: mccabe +Version: 0.6.1 +Summary: McCabe checker, plugin for flake8 +Home-page: https://github.com/pycqa/mccabe +Author: Ian Cordasco +Author-email: graffatcolmingov@gmail.com +License: Expat license +Keywords: flake8 mccabe +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Software Development :: Quality Assurance + +McCabe complexity checker +========================= + +Ned's script to check McCabe complexity. + +This module provides a plugin for ``flake8``, the Python code checker. + + +Installation +------------ + +You can install, upgrade, uninstall ``mccabe`` with these commands:: + + $ pip install mccabe + $ pip install --upgrade mccabe + $ pip uninstall mccabe + + +Standalone script +----------------- + +The complexity checker can be used directly:: + + $ python -m mccabe --min 5 mccabe.py + ("185:1: 'PathGraphingAstVisitor.visitIf'", 5) + ("71:1: 'PathGraph.to_dot'", 5) + ("245:1: 'McCabeChecker.run'", 5) + ("283:1: 'main'", 7) + ("203:1: 'PathGraphingAstVisitor.visitTryExcept'", 5) + ("257:1: 'get_code_complexity'", 5) + + +Plugin for Flake8 +----------------- + +When both ``flake8 2.0`` and ``mccabe`` are installed, the plugin is +available in ``flake8``:: + + $ flake8 --version + 2.0 (pep8: 1.4.2, pyflakes: 0.6.1, mccabe: 0.2) + +By default the plugin is disabled. Use the ``--max-complexity`` switch to +enable it. It will emit a warning if the McCabe complexity of a function is +higher that the value:: + + $ flake8 --max-complexity 10 coolproject + ... + coolproject/mod.py:1204:1: C901 'CoolFactory.prepare' is too complex (14) + +This feature is quite useful to detect over-complex code. According to McCabe, +anything that goes beyond 10 is too complex. + + +Links +----- + +* Feedback and ideas: http://mail.python.org/mailman/listinfo/code-quality + +* Cyclomatic complexity: http://en.wikipedia.org/wiki/Cyclomatic_complexity. + +* Ned Batchelder's script: + http://nedbatchelder.com/blog/200803/python_code_complexity_microtool.html + + +Changes +------- + +0.6.1 - 2017-01-26 +`````````````````` + +* Fix signature for ``PathGraphingAstVisitor.default`` to match the signature + for ``ASTVisitor`` + +0.6.0 - 2017-01-23 +`````````````````` + +* Add support for Python 3.6 + +* Fix handling for missing statement types + +0.5.3 - 2016-12-14 +`````````````````` + +* Report actual column number of violation instead of the start of the line + +0.5.2 - 2016-07-31 +`````````````````` + +* When opening files ourselves, make sure we always name the file variable + +0.5.1 - 2016-07-28 +`````````````````` + +* Set default maximum complexity to -1 on the class itself + +0.5.0 - 2016-05-30 +`````````````````` + +* PyCon 2016 PDX release + +* Add support for Flake8 3.0 + +0.4.0 - 2016-01-27 +`````````````````` + +* Stop testing on Python 3.2 + +* Add support for async/await keywords on Python 3.5 from PEP 0492 + +0.3.1 - 2015-06-14 +`````````````````` + +* Include ``test_mccabe.py`` in releases. + +* Always coerce the ``max_complexity`` value from Flake8's entry-point to an + integer. + +0.3 - 2014-12-17 +```````````````` + +* Computation was wrong: the mccabe complexity starts at 1, not 2. + +* The ``max-complexity`` value is now inclusive. E.g.: if the + value is 10 and the reported complexity is 10, then it passes. + +* Add tests. + + +0.2.1 - 2013-04-03 +`````````````````` + +* Do not require ``setuptools`` in setup.py. It works around an issue + with ``pip`` and Python 3. + + +0.2 - 2013-02-22 +```````````````` + +* Rename project to ``mccabe``. + +* Provide ``flake8.extension`` setuptools entry point. + +* Read ``max-complexity`` from the configuration file. + +* Rename argument ``min_complexity`` to ``threshold``. + + +0.1 - 2013-02-11 +```````````````` +* First release + + diff --git a/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/RECORD b/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/RECORD new file mode 100644 index 0000000..2b614a0 --- /dev/null +++ b/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/RECORD @@ -0,0 +1,10 @@ +mccabe.py,sha256=XPMywdQshG_5nSjckb-OzNqnCQuXQvy3FTClspKwGQA,10693 +mccabe-0.6.1.dist-info/DESCRIPTION.rst,sha256=lGHJ-Y3IviuP3DRqLL_TXPUr3wJ2GZ8XJkAV6ve3O58,3302 +mccabe-0.6.1.dist-info/METADATA,sha256=jawnTfTVrlzBSmeI-cTXSRIwIlijODtZdj-padBqIv0,4324 +mccabe-0.6.1.dist-info/RECORD,, +mccabe-0.6.1.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34,110 +mccabe-0.6.1.dist-info/entry_points.txt,sha256=N2NH182GXTUyTm8r8XMgadb9C-CRa5dUr1k8OC91uGE,47 +mccabe-0.6.1.dist-info/metadata.json,sha256=e508OR4t6_G7h7eO2C6NHlHQqVpPZZH1_DlAPrVECYM,1218 +mccabe-0.6.1.dist-info/top_level.txt,sha256=21cXuqZE-lpcfAqqANvX9EjI1ED1p8zcViv064u3RKA,7 +mccabe-0.6.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +__pycache__/mccabe.cpython-36.pyc,, diff --git a/py3/lib/python3.6/site-packages/python_socketio-4.3.1.dist-info/WHEEL b/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/WHEEL similarity index 70% rename from py3/lib/python3.6/site-packages/python_socketio-4.3.1.dist-info/WHEEL rename to py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/WHEEL index 78e6f69..8b6dd1b 100644 --- a/py3/lib/python3.6/site-packages/python_socketio-4.3.1.dist-info/WHEEL +++ b/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/WHEEL @@ -1,5 +1,5 @@ Wheel-Version: 1.0 -Generator: bdist_wheel (0.33.4) +Generator: bdist_wheel (0.29.0) Root-Is-Purelib: true Tag: py2-none-any Tag: py3-none-any diff --git a/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/entry_points.txt b/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/entry_points.txt new file mode 100644 index 0000000..cc6645b --- /dev/null +++ b/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[flake8.extension] +C90 = mccabe:McCabeChecker + diff --git a/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/metadata.json b/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/metadata.json new file mode 100644 index 0000000..ae04d8f --- /dev/null +++ b/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Quality Assurance"], "extensions": {"python.details": {"contacts": [{"email": "graffatcolmingov@gmail.com", "name": "Ian Cordasco", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/pycqa/mccabe"}}, "python.exports": {"flake8.extension": {"C90": "mccabe:McCabeChecker"}}}, "generator": "bdist_wheel (0.29.0)", "keywords": ["flake8", "mccabe"], "license": "Expat license", "metadata_version": "2.0", "name": "mccabe", "summary": "McCabe checker, plugin for flake8", "test_requires": [{"requires": ["pytest"]}], "version": "0.6.1"} \ No newline at end of file diff --git a/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/top_level.txt b/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/top_level.txt new file mode 100644 index 0000000..8831b36 --- /dev/null +++ b/py3/lib/python3.6/site-packages/mccabe-0.6.1.dist-info/top_level.txt @@ -0,0 +1 @@ +mccabe diff --git a/py3/lib/python3.6/site-packages/mccabe.py b/py3/lib/python3.6/site-packages/mccabe.py new file mode 100644 index 0000000..c0cda75 --- /dev/null +++ b/py3/lib/python3.6/site-packages/mccabe.py @@ -0,0 +1,347 @@ +""" Meager code path measurement tool. + Ned Batchelder + http://nedbatchelder.com/blog/200803/python_code_complexity_microtool.html + MIT License. +""" +from __future__ import with_statement + +import optparse +import sys +import tokenize + +from collections import defaultdict +try: + import ast + from ast import iter_child_nodes +except ImportError: # Python 2.5 + from flake8.util import ast, iter_child_nodes + +__version__ = '0.6.1' + + +class ASTVisitor(object): + """Performs a depth-first walk of the AST.""" + + def __init__(self): + self.node = None + self._cache = {} + + def default(self, node, *args): + for child in iter_child_nodes(node): + self.dispatch(child, *args) + + def dispatch(self, node, *args): + self.node = node + klass = node.__class__ + meth = self._cache.get(klass) + if meth is None: + className = klass.__name__ + meth = getattr(self.visitor, 'visit' + className, self.default) + self._cache[klass] = meth + return meth(node, *args) + + def preorder(self, tree, visitor, *args): + """Do preorder walk of tree using visitor""" + self.visitor = visitor + visitor.visit = self.dispatch + self.dispatch(tree, *args) # XXX *args make sense? + + +class PathNode(object): + def __init__(self, name, look="circle"): + self.name = name + self.look = look + + def to_dot(self): + print('node [shape=%s,label="%s"] %d;' % ( + self.look, self.name, self.dot_id())) + + def dot_id(self): + return id(self) + + +class PathGraph(object): + def __init__(self, name, entity, lineno, column=0): + self.name = name + self.entity = entity + self.lineno = lineno + self.column = column + self.nodes = defaultdict(list) + + def connect(self, n1, n2): + self.nodes[n1].append(n2) + # Ensure that the destination node is always counted. + self.nodes[n2] = [] + + def to_dot(self): + print('subgraph {') + for node in self.nodes: + node.to_dot() + for node, nexts in self.nodes.items(): + for next in nexts: + print('%s -- %s;' % (node.dot_id(), next.dot_id())) + print('}') + + def complexity(self): + """ Return the McCabe complexity for the graph. + V-E+2 + """ + num_edges = sum([len(n) for n in self.nodes.values()]) + num_nodes = len(self.nodes) + return num_edges - num_nodes + 2 + + +class PathGraphingAstVisitor(ASTVisitor): + """ A visitor for a parsed Abstract Syntax Tree which finds executable + statements. + """ + + def __init__(self): + super(PathGraphingAstVisitor, self).__init__() + self.classname = "" + self.graphs = {} + self.reset() + + def reset(self): + self.graph = None + self.tail = None + + def dispatch_list(self, node_list): + for node in node_list: + self.dispatch(node) + + def visitFunctionDef(self, node): + + if self.classname: + entity = '%s%s' % (self.classname, node.name) + else: + entity = node.name + + name = '%d:%d: %r' % (node.lineno, node.col_offset, entity) + + if self.graph is not None: + # closure + pathnode = self.appendPathNode(name) + self.tail = pathnode + self.dispatch_list(node.body) + bottom = PathNode("", look='point') + self.graph.connect(self.tail, bottom) + self.graph.connect(pathnode, bottom) + self.tail = bottom + else: + self.graph = PathGraph(name, entity, node.lineno, node.col_offset) + pathnode = PathNode(name) + self.tail = pathnode + self.dispatch_list(node.body) + self.graphs["%s%s" % (self.classname, node.name)] = self.graph + self.reset() + + visitAsyncFunctionDef = visitFunctionDef + + def visitClassDef(self, node): + old_classname = self.classname + self.classname += node.name + "." + self.dispatch_list(node.body) + self.classname = old_classname + + def appendPathNode(self, name): + if not self.tail: + return + pathnode = PathNode(name) + self.graph.connect(self.tail, pathnode) + self.tail = pathnode + return pathnode + + def visitSimpleStatement(self, node): + if node.lineno is None: + lineno = 0 + else: + lineno = node.lineno + name = "Stmt %d" % lineno + self.appendPathNode(name) + + def default(self, node, *args): + if isinstance(node, ast.stmt): + self.visitSimpleStatement(node) + else: + super(PathGraphingAstVisitor, self).default(node, *args) + + def visitLoop(self, node): + name = "Loop %d" % node.lineno + self._subgraph(node, name) + + visitAsyncFor = visitFor = visitWhile = visitLoop + + def visitIf(self, node): + name = "If %d" % node.lineno + self._subgraph(node, name) + + def _subgraph(self, node, name, extra_blocks=()): + """create the subgraphs representing any `if` and `for` statements""" + if self.graph is None: + # global loop + self.graph = PathGraph(name, name, node.lineno, node.col_offset) + pathnode = PathNode(name) + self._subgraph_parse(node, pathnode, extra_blocks) + self.graphs["%s%s" % (self.classname, name)] = self.graph + self.reset() + else: + pathnode = self.appendPathNode(name) + self._subgraph_parse(node, pathnode, extra_blocks) + + def _subgraph_parse(self, node, pathnode, extra_blocks): + """parse the body and any `else` block of `if` and `for` statements""" + loose_ends = [] + self.tail = pathnode + self.dispatch_list(node.body) + loose_ends.append(self.tail) + for extra in extra_blocks: + self.tail = pathnode + self.dispatch_list(extra.body) + loose_ends.append(self.tail) + if node.orelse: + self.tail = pathnode + self.dispatch_list(node.orelse) + loose_ends.append(self.tail) + else: + loose_ends.append(pathnode) + if pathnode: + bottom = PathNode("", look='point') + for le in loose_ends: + self.graph.connect(le, bottom) + self.tail = bottom + + def visitTryExcept(self, node): + name = "TryExcept %d" % node.lineno + self._subgraph(node, name, extra_blocks=node.handlers) + + visitTry = visitTryExcept + + def visitWith(self, node): + name = "With %d" % node.lineno + self.appendPathNode(name) + self.dispatch_list(node.body) + + visitAsyncWith = visitWith + + +class McCabeChecker(object): + """McCabe cyclomatic complexity checker.""" + name = 'mccabe' + version = __version__ + _code = 'C901' + _error_tmpl = "C901 %r is too complex (%d)" + max_complexity = -1 + + def __init__(self, tree, filename): + self.tree = tree + + @classmethod + def add_options(cls, parser): + flag = '--max-complexity' + kwargs = { + 'default': -1, + 'action': 'store', + 'type': 'int', + 'help': 'McCabe complexity threshold', + 'parse_from_config': 'True', + } + config_opts = getattr(parser, 'config_options', None) + if isinstance(config_opts, list): + # Flake8 2.x + kwargs.pop('parse_from_config') + parser.add_option(flag, **kwargs) + parser.config_options.append('max-complexity') + else: + parser.add_option(flag, **kwargs) + + @classmethod + def parse_options(cls, options): + cls.max_complexity = int(options.max_complexity) + + def run(self): + if self.max_complexity < 0: + return + visitor = PathGraphingAstVisitor() + visitor.preorder(self.tree, visitor) + for graph in visitor.graphs.values(): + if graph.complexity() > self.max_complexity: + text = self._error_tmpl % (graph.entity, graph.complexity()) + yield graph.lineno, graph.column, text, type(self) + + +def get_code_complexity(code, threshold=7, filename='stdin'): + try: + tree = compile(code, filename, "exec", ast.PyCF_ONLY_AST) + except SyntaxError: + e = sys.exc_info()[1] + sys.stderr.write("Unable to parse %s: %s\n" % (filename, e)) + return 0 + + complx = [] + McCabeChecker.max_complexity = threshold + for lineno, offset, text, check in McCabeChecker(tree, filename).run(): + complx.append('%s:%d:1: %s' % (filename, lineno, text)) + + if len(complx) == 0: + return 0 + print('\n'.join(complx)) + return len(complx) + + +def get_module_complexity(module_path, threshold=7): + """Returns the complexity of a module""" + with open(module_path, "rU") as mod: + code = mod.read() + return get_code_complexity(code, threshold, filename=module_path) + + +def _read(filename): + if (2, 5) < sys.version_info < (3, 0): + with open(filename, 'rU') as f: + return f.read() + elif (3, 0) <= sys.version_info < (4, 0): + """Read the source code.""" + try: + with open(filename, 'rb') as f: + (encoding, _) = tokenize.detect_encoding(f.readline) + except (LookupError, SyntaxError, UnicodeError): + # Fall back if file encoding is improperly declared + with open(filename, encoding='latin-1') as f: + return f.read() + with open(filename, 'r', encoding=encoding) as f: + return f.read() + + +def main(argv=None): + if argv is None: + argv = sys.argv[1:] + opar = optparse.OptionParser() + opar.add_option("-d", "--dot", dest="dot", + help="output a graphviz dot file", action="store_true") + opar.add_option("-m", "--min", dest="threshold", + help="minimum complexity for output", type="int", + default=1) + + options, args = opar.parse_args(argv) + + code = _read(args[0]) + tree = compile(code, args[0], "exec", ast.PyCF_ONLY_AST) + visitor = PathGraphingAstVisitor() + visitor.preorder(tree, visitor) + + if options.dot: + print('graph {') + for graph in visitor.graphs.values(): + if (not options.threshold or + graph.complexity() >= options.threshold): + graph.to_dot() + print('}') + else: + for graph in visitor.graphs.values(): + if graph.complexity() >= options.threshold: + print(graph.name, graph.complexity()) + + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/PKG-INFO b/py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/PKG-INFO deleted file mode 100644 index 6ee58e8..0000000 --- a/py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/PKG-INFO +++ /dev/null @@ -1,217 +0,0 @@ -Metadata-Version: 1.1 -Name: netifaces -Version: 0.10.6 -Summary: Portable network interface information. -Home-page: https://bitbucket.org/al45tair/netifaces -Author: Alastair Houghton -Author-email: alastair@alastairs-place.net -License: MIT License -Description: netifaces 0.10.6 - ================ - - .. image:: https://drone.io/bitbucket.org/al45tair/netifaces/status.png - :target: https://drone.io/bitbucket.org/al45tair/netifaces/latest - :alt: Build Status - - 1. What is this? - ---------------- - - It's been annoying me for some time that there's no easy way to get the - address(es) of the machine's network interfaces from Python. There is - a good reason for this difficulty, which is that it is virtually impossible - to do so in a portable manner. However, it seems to me that there should - be a package you can easy_install that will take care of working out the - details of doing so on the machine you're using, then you can get on with - writing Python code without concerning yourself with the nitty gritty of - system-dependent low-level networking APIs. - - This package attempts to solve that problem. - - 2. How do I use it? - ------------------- - - First you need to install it, which you can do by typing:: - - tar xvzf netifaces-0.10.6.tar.gz - cd netifaces-0.10.6 - python setup.py install - - **Note that you will need the relevant developer tools for your platform**, - as netifaces is written in C and installing this way will compile the extension. - - Once that's done, you'll need to start Python and do something like the - following:: - - >>> import netifaces - - Then if you enter - - >>> netifaces.interfaces() - ['lo0', 'gif0', 'stf0', 'en0', 'en1', 'fw0'] - - you'll see the list of interface identifiers for your machine. - - You can ask for the addresses of a particular interface by doing - - >>> netifaces.ifaddresses('lo0') - {18: [{'addr': ''}], 2: [{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}], 30: [{'peer': '::1', 'netmask': 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', 'addr': '::1'}, {'peer': '', 'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::1%lo0'}]} - - Hmmmm. That result looks a bit cryptic; let's break it apart and explain - what each piece means. It returned a dictionary, so let's look there first:: - - { 18: [...], 2: [...], 30: [...] } - - Each of the numbers refers to a particular address family. In this case, we - have three address families listed; on my system, 18 is ``AF_LINK`` (which means - the link layer interface, e.g. Ethernet), 2 is ``AF_INET`` (normal Internet - addresses), and 30 is ``AF_INET6`` (IPv6). - - But wait! Don't use these numbers in your code. The numeric values here are - system dependent; fortunately, I thought of that when writing netifaces, so - the module declares a range of values that you might need. e.g. - - >>> netifaces.AF_LINK - 18 - - Again, on your system, the number may be different. - - So, what we've established is that the dictionary that's returned has one - entry for each address family for which this interface has an address. Let's - take a look at the ``AF_INET`` addresses now: - - >>> addrs = netifaces.ifaddresses('lo0') - >>> addrs[netifaces.AF_INET] - [{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}] - - You might be wondering why this value is a list. The reason is that it's - possible for an interface to have more than one address, even within the - same family. I'll say that again: *you can have more than one address of - the same type associated with each interface*. - - *Asking for "the" address of a particular interface doesn't make sense.* - - Right, so, we can see that this particular interface only has one address, - and, because it's a loopback interface, it's point-to-point and therefore - has a *peer* address rather than a broadcast address. - - Let's look at a more interesting interface. - - >>> addrs = netifaces.ifaddresses('en0') - >>> addrs[netifaces.AF_INET] - [{'broadcast': '10.15.255.255', 'netmask': '255.240.0.0', 'addr': '10.0.1.4'}, {'broadcast': '192.168.0.255', 'addr': '192.168.0.47'}] - - This interface has two addresses (see, I told you...) Both of them are - regular IPv4 addresses, although in one case the netmask has been changed - from its default. The netmask *may not* appear on your system if it's set - to the default for the address range. - - Because this interface isn't point-to-point, it also has broadcast addresses. - - Now, say we want, instead of the IP addresses, to get the MAC address; that - is, the hardware address of the Ethernet adapter running this interface. We - can do - - >>> addrs[netifaces.AF_LINK] - [{'addr': '00:12:34:56:78:9a'}] - - Note that this may not be available on platforms without getifaddrs(), unless - they happen to implement ``SIOCGIFHWADDR``. Note also that you just get the - address; it's unlikely that you'll see anything else with an ``AF_LINK`` address. - Oh, and don't assume that all ``AF_LINK`` addresses are Ethernet; you might, for - instance, be on a Mac, in which case: - - >>> addrs = netifaces.ifaddresses('fw0') - >>> addrs[netifaces.AF_LINK] - [{'addr': '00:12:34:56:78:9a:bc:de'}] - - No, that isn't an exceptionally long Ethernet MAC address---it's a FireWire - address. - - As of version 0.10.0, you can also obtain a list of gateways on your - machine: - - >>> netifaces.gateways() - {2: [('10.0.1.1', 'en0', True), ('10.2.1.1', 'en1', False)], 30: [('fe80::1', 'en0', True)], 'default': { 2: ('10.0.1.1', 'en0'), 30: ('fe80::1', 'en0') }} - - This dictionary is keyed on address family---in this case, ``AF_INET``---and - each entry is a list of gateways as ``(address, interface, is_default)`` tuples. - Notice that here we have two separate gateways for IPv4 (``AF_INET``); some - operating systems support configurations like this and can either route packets - based on their source, or based on administratively configured routing tables. - - For convenience, we also allow you to index the dictionary with the special - value ``'default'``, which returns a dictionary mapping address families to the - default gateway in each case. Thus you can get the default IPv4 gateway with - - >>> gws = netifaces.gateways() - >>> gws['default'][netifaces.AF_INET] - ('10.0.1.1', 'en0') - - Do note that there may be no default gateway for any given address family; - this is currently very common for IPv6 and much less common for IPv4 but it - can happen even for ``AF_INET``. - - BTW, if you're trying to configure your machine to have multiple gateways for - the same address family, it's a very good idea to check the documentation for - your operating system *very* carefully, as some systems become extremely - confused or route packets in a non-obvious manner. - - I'm very interested in hearing from anyone (on any platform) for whom the - ``gateways()`` method doesn't produce the expected results. It's quite - complicated extracting this information from the operating system (whichever - operating system we're talking about), and so I expect there's at least one - system out there where this just won't work. - - 3. This is great! What platforms does it work on? - -------------------------------------------------- - - It gets regular testing on OS X, Linux and Windows. It has also been used - successfully on Solaris, and it's expected to work properly on other UNIX-like - systems as well. If you are running something that is not supported, and - wish to contribute a patch, please use BitBucket to send a pull request. - - 4. What license is this under? - ------------------------------ - - It's an MIT-style license. Here goes: - - Copyright (c) 2007-2017 Alastair Houghton - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - 5. Why the jump to 0.10.0? - -------------------------- - - Because someone released a fork of netifaces with the version 0.9.0. - Hopefully skipping the version number should remove any confusion. In - addition starting with 0.10.0 Python 3 is now supported and other - features/bugfixes have been included as well. See the CHANGELOG for a - more complete list of changes. - -Platform: UNKNOWN -Classifier: Development Status :: 4 - Beta -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Topic :: System :: Networking -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.5 -Classifier: Programming Language :: Python :: 2.6 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 diff --git a/py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/SOURCES.txt b/py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/SOURCES.txt deleted file mode 100644 index a382c6c..0000000 --- a/py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/SOURCES.txt +++ /dev/null @@ -1,9 +0,0 @@ -README.rst -netifaces.c -setup.cfg -setup.py -netifaces.egg-info/PKG-INFO -netifaces.egg-info/SOURCES.txt -netifaces.egg-info/dependency_links.txt -netifaces.egg-info/top_level.txt -netifaces.egg-info/zip-safe \ No newline at end of file diff --git a/py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/installed-files.txt b/py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/installed-files.txt deleted file mode 100644 index 960face..0000000 --- a/py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/installed-files.txt +++ /dev/null @@ -1,6 +0,0 @@ -../netifaces.cpython-36m-x86_64-linux-gnu.so -SOURCES.txt -PKG-INFO -dependency_links.txt -zip-safe -top_level.txt diff --git a/py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/top_level.txt b/py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/top_level.txt deleted file mode 100644 index 3f008fd..0000000 --- a/py3/lib/python3.6/site-packages/netifaces-0.10.6.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -netifaces diff --git a/py3/lib/python3.6/site-packages/netifaces.cpython-36m-x86_64-linux-gnu.so b/py3/lib/python3.6/site-packages/netifaces.cpython-36m-x86_64-linux-gnu.so deleted file mode 100755 index 3b8c7434519a036c8052669ce2bbe5018fd3a037..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73704 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 MnhdtfwJXp2zhCSqb^rhX diff --git a/py3/lib/python3.6/site-packages/pip-9.0.1.dist-info/RECORD b/py3/lib/python3.6/site-packages/pip-9.0.1.dist-info/RECORD index b864e63..e44045a 100644 --- a/py3/lib/python3.6/site-packages/pip-9.0.1.dist-info/RECORD +++ b/py3/lib/python3.6/site-packages/pip-9.0.1.dist-info/RECORD @@ -61,9 +61,9 @@ pip-9.0.1.dist-info/WHEEL,sha256=kdsN-5OJAZIiHN-iO4Rhl82KyS0bDWf4uBwMbkNafr8,110 pip-9.0.1.dist-info/entry_points.txt,sha256=Q-fR2tcp9DRdeXoGn1wR67Xecy32o5EyQEnzDghwqqk,68 pip-9.0.1.dist-info/metadata.json,sha256=eAfMY0s5HjwtLLjIZ9LYDxWocl2her-knzH7qTJ38CU,1565 pip-9.0.1.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -../../../bin/pip,sha256=AoPR6znoO-HsOeujc73U5AkjZgpGowQ7q8wXtSD8aHY,244 -../../../bin/pip3,sha256=AoPR6znoO-HsOeujc73U5AkjZgpGowQ7q8wXtSD8aHY,244 -../../../bin/pip3.6,sha256=AoPR6znoO-HsOeujc73U5AkjZgpGowQ7q8wXtSD8aHY,244 +../../../bin/pip,sha256=8Mc-lL9u8HMSiBUhu3oRfyygl5hH-d1EYpyGrUsRfUM,229 +../../../bin/pip3,sha256=8Mc-lL9u8HMSiBUhu3oRfyygl5hH-d1EYpyGrUsRfUM,229 +../../../bin/pip3.6,sha256=8Mc-lL9u8HMSiBUhu3oRfyygl5hH-d1EYpyGrUsRfUM,229 pip-9.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 pip/_vendor/__pycache__/__init__.cpython-36.pyc,, pip/commands/__pycache__/search.cpython-36.pyc,, diff --git a/py3/lib/python3.6/site-packages/pkg_resources.py b/py3/lib/python3.6/site-packages/pkg_resources.py deleted file mode 100644 index 2d656f1..0000000 --- a/py3/lib/python3.6/site-packages/pkg_resources.py +++ /dev/null @@ -1,2762 +0,0 @@ -""" -Package resource API --------------------- - -A resource is a logical file contained within a package, or a logical -subdirectory thereof. The package resource API expects resource names -to have their path parts separated with ``/``, *not* whatever the local -path separator is. Do not use os.path operations to manipulate resource -names being passed into the API. - -The package resource API is designed to work with normal filesystem packages, -.egg files, and unpacked .egg files. It can also work in a limited way with -.zip files and with custom PEP 302 loaders that support the ``get_data()`` -method. -""" - -import sys -import os -import time -import re -import imp -import zipfile -import zipimport -import warnings -import stat -import functools -import pkgutil -import token -import symbol -import operator -import platform -from pkgutil import get_importer - -try: - from urlparse import urlparse, urlunparse -except ImportError: - from urllib.parse import urlparse, urlunparse - -try: - frozenset -except NameError: - from sets import ImmutableSet as frozenset -try: - basestring - next = lambda o: o.next() - from cStringIO import StringIO as BytesIO -except NameError: - basestring = str - from io import BytesIO - def execfile(fn, globs=None, locs=None): - if globs is None: - globs = globals() - if locs is None: - locs = globs - exec(compile(open(fn).read(), fn, 'exec'), globs, locs) - -# capture these to bypass sandboxing -from os import utime -try: - from os import mkdir, rename, unlink - WRITE_SUPPORT = True -except ImportError: - # no write support, probably under GAE - WRITE_SUPPORT = False - -from os import open as os_open -from os.path import isdir, split - -# Avoid try/except due to potential problems with delayed import mechanisms. -if sys.version_info >= (3, 3) and sys.implementation.name == "cpython": - import importlib._bootstrap as importlib_bootstrap -else: - importlib_bootstrap = None - -try: - import parser -except ImportError: - pass - -def _bypass_ensure_directory(name, mode=0x1FF): # 0777 - # Sandbox-bypassing version of ensure_directory() - if not WRITE_SUPPORT: - raise IOError('"os.mkdir" not supported on this platform.') - dirname, filename = split(name) - if dirname and filename and not isdir(dirname): - _bypass_ensure_directory(dirname) - mkdir(dirname, mode) - - -_state_vars = {} - -def _declare_state(vartype, **kw): - globals().update(kw) - _state_vars.update(dict.fromkeys(kw, vartype)) - -def __getstate__(): - state = {} - g = globals() - for k, v in _state_vars.items(): - state[k] = g['_sget_'+v](g[k]) - return state - -def __setstate__(state): - g = globals() - for k, v in state.items(): - g['_sset_'+_state_vars[k]](k, g[k], v) - return state - -def _sget_dict(val): - return val.copy() - -def _sset_dict(key, ob, state): - ob.clear() - ob.update(state) - -def _sget_object(val): - return val.__getstate__() - -def _sset_object(key, ob, state): - ob.__setstate__(state) - -_sget_none = _sset_none = lambda *args: None - - -def get_supported_platform(): - """Return this platform's maximum compatible version. - - distutils.util.get_platform() normally reports the minimum version - of Mac OS X that would be required to *use* extensions produced by - distutils. But what we want when checking compatibility is to know the - version of Mac OS X that we are *running*. To allow usage of packages that - explicitly require a newer version of Mac OS X, we must also know the - current version of the OS. - - If this condition occurs for any other platform with a version in its - platform strings, this function should be extended accordingly. - """ - plat = get_build_platform() - m = macosVersionString.match(plat) - if m is not None and sys.platform == "darwin": - try: - plat = 'macosx-%s-%s' % ('.'.join(_macosx_vers()[:2]), m.group(3)) - except ValueError: - pass # not Mac OS X - return plat - -__all__ = [ - # Basic resource access and distribution/entry point discovery - 'require', 'run_script', 'get_provider', 'get_distribution', - 'load_entry_point', 'get_entry_map', 'get_entry_info', 'iter_entry_points', - 'resource_string', 'resource_stream', 'resource_filename', - 'resource_listdir', 'resource_exists', 'resource_isdir', - - # Environmental control - 'declare_namespace', 'working_set', 'add_activation_listener', - 'find_distributions', 'set_extraction_path', 'cleanup_resources', - 'get_default_cache', - - # Primary implementation classes - 'Environment', 'WorkingSet', 'ResourceManager', - 'Distribution', 'Requirement', 'EntryPoint', - - # Exceptions - 'ResolutionError','VersionConflict','DistributionNotFound','UnknownExtra', - 'ExtractionError', - - # Parsing functions and string utilities - 'parse_requirements', 'parse_version', 'safe_name', 'safe_version', - 'get_platform', 'compatible_platforms', 'yield_lines', 'split_sections', - 'safe_extra', 'to_filename', 'invalid_marker', 'evaluate_marker', - - # filesystem utilities - 'ensure_directory', 'normalize_path', - - # Distribution "precedence" constants - 'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'DEVELOP_DIST', - - # "Provider" interfaces, implementations, and registration/lookup APIs - 'IMetadataProvider', 'IResourceProvider', 'FileMetadata', - 'PathMetadata', 'EggMetadata', 'EmptyProvider', 'empty_provider', - 'NullProvider', 'EggProvider', 'DefaultProvider', 'ZipProvider', - 'register_finder', 'register_namespace_handler', 'register_loader_type', - 'fixup_namespace_packages', 'get_importer', - - # Deprecated/backward compatibility only - 'run_main', 'AvailableDistributions', -] - -class ResolutionError(Exception): - """Abstract base for dependency resolution errors""" - def __repr__(self): - return self.__class__.__name__+repr(self.args) - -class VersionConflict(ResolutionError): - """An already-installed version conflicts with the requested version""" - -class DistributionNotFound(ResolutionError): - """A requested distribution was not found""" - -class UnknownExtra(ResolutionError): - """Distribution doesn't have an "extra feature" of the given name""" -_provider_factories = {} - -PY_MAJOR = sys.version[:3] -EGG_DIST = 3 -BINARY_DIST = 2 -SOURCE_DIST = 1 -CHECKOUT_DIST = 0 -DEVELOP_DIST = -1 - -def register_loader_type(loader_type, provider_factory): - """Register `provider_factory` to make providers for `loader_type` - - `loader_type` is the type or class of a PEP 302 ``module.__loader__``, - and `provider_factory` is a function that, passed a *module* object, - returns an ``IResourceProvider`` for that module. - """ - _provider_factories[loader_type] = provider_factory - -def get_provider(moduleOrReq): - """Return an IResourceProvider for the named module or requirement""" - if isinstance(moduleOrReq,Requirement): - return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0] - try: - module = sys.modules[moduleOrReq] - except KeyError: - __import__(moduleOrReq) - module = sys.modules[moduleOrReq] - loader = getattr(module, '__loader__', None) - return _find_adapter(_provider_factories, loader)(module) - -def _macosx_vers(_cache=[]): - if not _cache: - import platform - version = platform.mac_ver()[0] - # fallback for MacPorts - if version == '': - import plistlib - plist = '/System/Library/CoreServices/SystemVersion.plist' - if os.path.exists(plist): - if hasattr(plistlib, 'readPlist'): - plist_content = plistlib.readPlist(plist) - if 'ProductVersion' in plist_content: - version = plist_content['ProductVersion'] - - _cache.append(version.split('.')) - return _cache[0] - -def _macosx_arch(machine): - return {'PowerPC':'ppc', 'Power_Macintosh':'ppc'}.get(machine,machine) - -def get_build_platform(): - """Return this platform's string for platform-specific distributions - - XXX Currently this is the same as ``distutils.util.get_platform()``, but it - needs some hacks for Linux and Mac OS X. - """ - try: - # Python 2.7 or >=3.2 - from sysconfig import get_platform - except ImportError: - from distutils.util import get_platform - - plat = get_platform() - if sys.platform == "darwin" and not plat.startswith('macosx-'): - try: - version = _macosx_vers() - machine = os.uname()[4].replace(" ", "_") - return "macosx-%d.%d-%s" % (int(version[0]), int(version[1]), - _macosx_arch(machine)) - except ValueError: - # if someone is running a non-Mac darwin system, this will fall - # through to the default implementation - pass - return plat - -macosVersionString = re.compile(r"macosx-(\d+)\.(\d+)-(.*)") -darwinVersionString = re.compile(r"darwin-(\d+)\.(\d+)\.(\d+)-(.*)") -get_platform = get_build_platform # XXX backward compat - - -def compatible_platforms(provided,required): - """Can code for the `provided` platform run on the `required` platform? - - Returns true if either platform is ``None``, or the platforms are equal. - - XXX Needs compatibility checks for Linux and other unixy OSes. - """ - if provided is None or required is None or provided==required: - return True # easy case - - # Mac OS X special cases - reqMac = macosVersionString.match(required) - if reqMac: - provMac = macosVersionString.match(provided) - - # is this a Mac package? - if not provMac: - # this is backwards compatibility for packages built before - # setuptools 0.6. All packages built after this point will - # use the new macosx designation. - provDarwin = darwinVersionString.match(provided) - if provDarwin: - dversion = int(provDarwin.group(1)) - macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2)) - if dversion == 7 and macosversion >= "10.3" or \ - dversion == 8 and macosversion >= "10.4": - - #import warnings - #warnings.warn("Mac eggs should be rebuilt to " - # "use the macosx designation instead of darwin.", - # category=DeprecationWarning) - return True - return False # egg isn't macosx or legacy darwin - - # are they the same major version and machine type? - if provMac.group(1) != reqMac.group(1) or \ - provMac.group(3) != reqMac.group(3): - return False - - # is the required OS major update >= the provided one? - if int(provMac.group(2)) > int(reqMac.group(2)): - return False - - return True - - # XXX Linux and other platforms' special cases should go here - return False - - -def run_script(dist_spec, script_name): - """Locate distribution `dist_spec` and run its `script_name` script""" - ns = sys._getframe(1).f_globals - name = ns['__name__'] - ns.clear() - ns['__name__'] = name - require(dist_spec)[0].run_script(script_name, ns) - -run_main = run_script # backward compatibility - -def get_distribution(dist): - """Return a current distribution object for a Requirement or string""" - if isinstance(dist,basestring): dist = Requirement.parse(dist) - if isinstance(dist,Requirement): dist = get_provider(dist) - if not isinstance(dist,Distribution): - raise TypeError("Expected string, Requirement, or Distribution", dist) - return dist - -def load_entry_point(dist, group, name): - """Return `name` entry point of `group` for `dist` or raise ImportError""" - return get_distribution(dist).load_entry_point(group, name) - -def get_entry_map(dist, group=None): - """Return the entry point map for `group`, or the full entry map""" - return get_distribution(dist).get_entry_map(group) - -def get_entry_info(dist, group, name): - """Return the EntryPoint object for `group`+`name`, or ``None``""" - return get_distribution(dist).get_entry_info(group, name) - - -class IMetadataProvider: - - def has_metadata(name): - """Does the package's distribution contain the named metadata?""" - - def get_metadata(name): - """The named metadata resource as a string""" - - def get_metadata_lines(name): - """Yield named metadata resource as list of non-blank non-comment lines - - Leading and trailing whitespace is stripped from each line, and lines - with ``#`` as the first non-blank character are omitted.""" - - def metadata_isdir(name): - """Is the named metadata a directory? (like ``os.path.isdir()``)""" - - def metadata_listdir(name): - """List of metadata names in the directory (like ``os.listdir()``)""" - - def run_script(script_name, namespace): - """Execute the named script in the supplied namespace dictionary""" - - -class IResourceProvider(IMetadataProvider): - """An object that provides access to package resources""" - - def get_resource_filename(manager, resource_name): - """Return a true filesystem path for `resource_name` - - `manager` must be an ``IResourceManager``""" - - def get_resource_stream(manager, resource_name): - """Return a readable file-like object for `resource_name` - - `manager` must be an ``IResourceManager``""" - - def get_resource_string(manager, resource_name): - """Return a string containing the contents of `resource_name` - - `manager` must be an ``IResourceManager``""" - - def has_resource(resource_name): - """Does the package contain the named resource?""" - - def resource_isdir(resource_name): - """Is the named resource a directory? (like ``os.path.isdir()``)""" - - def resource_listdir(resource_name): - """List of resource names in the directory (like ``os.listdir()``)""" - - -class WorkingSet(object): - """A collection of active distributions on sys.path (or a similar list)""" - - def __init__(self, entries=None): - """Create working set from list of path entries (default=sys.path)""" - self.entries = [] - self.entry_keys = {} - self.by_key = {} - self.callbacks = [] - - if entries is None: - entries = sys.path - - for entry in entries: - self.add_entry(entry) - - @classmethod - def _build_master(cls): - """ - Prepare the master working set. - """ - ws = cls() - try: - from __main__ import __requires__ - except ImportError: - # The main program does not list any requirements - return ws - - # ensure the requirements are met - try: - ws.require(__requires__) - except VersionConflict: - return cls._build_from_requirements(__requires__) - - return ws - - @classmethod - def _build_from_requirements(cls, req_spec): - """ - Build a working set from a requirement spec. Rewrites sys.path. - """ - # try it without defaults already on sys.path - # by starting with an empty path - ws = cls([]) - reqs = parse_requirements(req_spec) - dists = ws.resolve(reqs, Environment()) - for dist in dists: - ws.add(dist) - - # add any missing entries from sys.path - for entry in sys.path: - if entry not in ws.entries: - ws.add_entry(entry) - - # then copy back to sys.path - sys.path[:] = ws.entries - return ws - - def add_entry(self, entry): - """Add a path item to ``.entries``, finding any distributions on it - - ``find_distributions(entry, True)`` is used to find distributions - corresponding to the path entry, and they are added. `entry` is - always appended to ``.entries``, even if it is already present. - (This is because ``sys.path`` can contain the same value more than - once, and the ``.entries`` of the ``sys.path`` WorkingSet should always - equal ``sys.path``.) - """ - self.entry_keys.setdefault(entry, []) - self.entries.append(entry) - for dist in find_distributions(entry, True): - self.add(dist, entry, False) - - def __contains__(self,dist): - """True if `dist` is the active distribution for its project""" - return self.by_key.get(dist.key) == dist - - def find(self, req): - """Find a distribution matching requirement `req` - - If there is an active distribution for the requested project, this - returns it as long as it meets the version requirement specified by - `req`. But, if there is an active distribution for the project and it - does *not* meet the `req` requirement, ``VersionConflict`` is raised. - If there is no active distribution for the requested project, ``None`` - is returned. - """ - dist = self.by_key.get(req.key) - if dist is not None and dist not in req: - raise VersionConflict(dist,req) # XXX add more info - else: - return dist - - def iter_entry_points(self, group, name=None): - """Yield entry point objects from `group` matching `name` - - If `name` is None, yields all entry points in `group` from all - distributions in the working set, otherwise only ones matching - both `group` and `name` are yielded (in distribution order). - """ - for dist in self: - entries = dist.get_entry_map(group) - if name is None: - for ep in entries.values(): - yield ep - elif name in entries: - yield entries[name] - - def run_script(self, requires, script_name): - """Locate distribution for `requires` and run `script_name` script""" - ns = sys._getframe(1).f_globals - name = ns['__name__'] - ns.clear() - ns['__name__'] = name - self.require(requires)[0].run_script(script_name, ns) - - def __iter__(self): - """Yield distributions for non-duplicate projects in the working set - - The yield order is the order in which the items' path entries were - added to the working set. - """ - seen = {} - for item in self.entries: - if item not in self.entry_keys: - # workaround a cache issue - continue - - for key in self.entry_keys[item]: - if key not in seen: - seen[key]=1 - yield self.by_key[key] - - def add(self, dist, entry=None, insert=True, replace=False): - """Add `dist` to working set, associated with `entry` - - If `entry` is unspecified, it defaults to the ``.location`` of `dist`. - On exit from this routine, `entry` is added to the end of the working - set's ``.entries`` (if it wasn't already present). - - `dist` is only added to the working set if it's for a project that - doesn't already have a distribution in the set, unless `replace=True`. - If it's added, any callbacks registered with the ``subscribe()`` method - will be called. - """ - if insert: - dist.insert_on(self.entries, entry) - - if entry is None: - entry = dist.location - keys = self.entry_keys.setdefault(entry,[]) - keys2 = self.entry_keys.setdefault(dist.location,[]) - if not replace and dist.key in self.by_key: - return # ignore hidden distros - - self.by_key[dist.key] = dist - if dist.key not in keys: - keys.append(dist.key) - if dist.key not in keys2: - keys2.append(dist.key) - self._added_new(dist) - - def resolve(self, requirements, env=None, installer=None, - replace_conflicting=False): - """List all distributions needed to (recursively) meet `requirements` - - `requirements` must be a sequence of ``Requirement`` objects. `env`, - if supplied, should be an ``Environment`` instance. If - not supplied, it defaults to all distributions available within any - entry or distribution in the working set. `installer`, if supplied, - will be invoked with each requirement that cannot be met by an - already-installed distribution; it should return a ``Distribution`` or - ``None``. - - Unless `replace_conflicting=True`, raises a VersionConflict exception if - any requirements are found on the path that have the correct name but - the wrong version. Otherwise, if an `installer` is supplied it will be - invoked to obtain the correct version of the requirement and activate - it. - """ - - requirements = list(requirements)[::-1] # set up the stack - processed = {} # set of processed requirements - best = {} # key -> dist - to_activate = [] - - while requirements: - req = requirements.pop(0) # process dependencies breadth-first - if req in processed: - # Ignore cyclic or redundant dependencies - continue - dist = best.get(req.key) - if dist is None: - # Find the best distribution and add it to the map - dist = self.by_key.get(req.key) - if dist is None or (dist not in req and replace_conflicting): - ws = self - if env is None: - if dist is None: - env = Environment(self.entries) - else: - # Use an empty environment and workingset to avoid - # any further conflicts with the conflicting - # distribution - env = Environment([]) - ws = WorkingSet([]) - dist = best[req.key] = env.best_match(req, ws, installer) - if dist is None: - #msg = ("The '%s' distribution was not found on this " - # "system, and is required by this application.") - #raise DistributionNotFound(msg % req) - - # unfortunately, zc.buildout uses a str(err) - # to get the name of the distribution here.. - raise DistributionNotFound(req) - to_activate.append(dist) - if dist not in req: - # Oops, the "best" so far conflicts with a dependency - raise VersionConflict(dist,req) # XXX put more info here - requirements.extend(dist.requires(req.extras)[::-1]) - processed[req] = True - - return to_activate # return list of distros to activate - - def find_plugins(self, plugin_env, full_env=None, installer=None, - fallback=True): - """Find all activatable distributions in `plugin_env` - - Example usage:: - - distributions, errors = working_set.find_plugins( - Environment(plugin_dirlist) - ) - map(working_set.add, distributions) # add plugins+libs to sys.path - print 'Could not load', errors # display errors - - The `plugin_env` should be an ``Environment`` instance that contains - only distributions that are in the project's "plugin directory" or - directories. The `full_env`, if supplied, should be an ``Environment`` - contains all currently-available distributions. If `full_env` is not - supplied, one is created automatically from the ``WorkingSet`` this - method is called on, which will typically mean that every directory on - ``sys.path`` will be scanned for distributions. - - `installer` is a standard installer callback as used by the - ``resolve()`` method. The `fallback` flag indicates whether we should - attempt to resolve older versions of a plugin if the newest version - cannot be resolved. - - This method returns a 2-tuple: (`distributions`, `error_info`), where - `distributions` is a list of the distributions found in `plugin_env` - that were loadable, along with any other distributions that are needed - to resolve their dependencies. `error_info` is a dictionary mapping - unloadable plugin distributions to an exception instance describing the - error that occurred. Usually this will be a ``DistributionNotFound`` or - ``VersionConflict`` instance. - """ - - plugin_projects = list(plugin_env) - plugin_projects.sort() # scan project names in alphabetic order - - error_info = {} - distributions = {} - - if full_env is None: - env = Environment(self.entries) - env += plugin_env - else: - env = full_env + plugin_env - - shadow_set = self.__class__([]) - list(map(shadow_set.add, self)) # put all our entries in shadow_set - - for project_name in plugin_projects: - - for dist in plugin_env[project_name]: - - req = [dist.as_requirement()] - - try: - resolvees = shadow_set.resolve(req, env, installer) - - except ResolutionError: - v = sys.exc_info()[1] - error_info[dist] = v # save error info - if fallback: - continue # try the next older version of project - else: - break # give up on this project, keep going - - else: - list(map(shadow_set.add, resolvees)) - distributions.update(dict.fromkeys(resolvees)) - - # success, no need to try any more versions of this project - break - - distributions = list(distributions) - distributions.sort() - - return distributions, error_info - - def require(self, *requirements): - """Ensure that distributions matching `requirements` are activated - - `requirements` must be a string or a (possibly-nested) sequence - thereof, specifying the distributions and versions required. The - return value is a sequence of the distributions that needed to be - activated to fulfill the requirements; all relevant distributions are - included, even if they were already activated in this working set. - """ - needed = self.resolve(parse_requirements(requirements)) - - for dist in needed: - self.add(dist) - - return needed - - def subscribe(self, callback): - """Invoke `callback` for all distributions (including existing ones)""" - if callback in self.callbacks: - return - self.callbacks.append(callback) - for dist in self: - callback(dist) - - def _added_new(self, dist): - for callback in self.callbacks: - callback(dist) - - def __getstate__(self): - return ( - self.entries[:], self.entry_keys.copy(), self.by_key.copy(), - self.callbacks[:] - ) - - def __setstate__(self, e_k_b_c): - entries, keys, by_key, callbacks = e_k_b_c - self.entries = entries[:] - self.entry_keys = keys.copy() - self.by_key = by_key.copy() - self.callbacks = callbacks[:] - - -class Environment(object): - """Searchable snapshot of distributions on a search path""" - - def __init__(self, search_path=None, platform=get_supported_platform(), python=PY_MAJOR): - """Snapshot distributions available on a search path - - Any distributions found on `search_path` are added to the environment. - `search_path` should be a sequence of ``sys.path`` items. If not - supplied, ``sys.path`` is used. - - `platform` is an optional string specifying the name of the platform - that platform-specific distributions must be compatible with. If - unspecified, it defaults to the current platform. `python` is an - optional string naming the desired version of Python (e.g. ``'3.3'``); - it defaults to the current version. - - You may explicitly set `platform` (and/or `python`) to ``None`` if you - wish to map *all* distributions, not just those compatible with the - running platform or Python version. - """ - self._distmap = {} - self._cache = {} - self.platform = platform - self.python = python - self.scan(search_path) - - def can_add(self, dist): - """Is distribution `dist` acceptable for this environment? - - The distribution must match the platform and python version - requirements specified when this environment was created, or False - is returned. - """ - return (self.python is None or dist.py_version is None - or dist.py_version==self.python) \ - and compatible_platforms(dist.platform,self.platform) - - def remove(self, dist): - """Remove `dist` from the environment""" - self._distmap[dist.key].remove(dist) - - def scan(self, search_path=None): - """Scan `search_path` for distributions usable in this environment - - Any distributions found are added to the environment. - `search_path` should be a sequence of ``sys.path`` items. If not - supplied, ``sys.path`` is used. Only distributions conforming to - the platform/python version defined at initialization are added. - """ - if search_path is None: - search_path = sys.path - - for item in search_path: - for dist in find_distributions(item): - self.add(dist) - - def __getitem__(self,project_name): - """Return a newest-to-oldest list of distributions for `project_name` - """ - try: - return self._cache[project_name] - except KeyError: - project_name = project_name.lower() - if project_name not in self._distmap: - return [] - - if project_name not in self._cache: - dists = self._cache[project_name] = self._distmap[project_name] - _sort_dists(dists) - - return self._cache[project_name] - - def add(self,dist): - """Add `dist` if we ``can_add()`` it and it isn't already added""" - if self.can_add(dist) and dist.has_version(): - dists = self._distmap.setdefault(dist.key,[]) - if dist not in dists: - dists.append(dist) - if dist.key in self._cache: - _sort_dists(self._cache[dist.key]) - - def best_match(self, req, working_set, installer=None): - """Find distribution best matching `req` and usable on `working_set` - - This calls the ``find(req)`` method of the `working_set` to see if a - suitable distribution is already active. (This may raise - ``VersionConflict`` if an unsuitable version of the project is already - active in the specified `working_set`.) If a suitable distribution - isn't active, this method returns the newest distribution in the - environment that meets the ``Requirement`` in `req`. If no suitable - distribution is found, and `installer` is supplied, then the result of - calling the environment's ``obtain(req, installer)`` method will be - returned. - """ - dist = working_set.find(req) - if dist is not None: - return dist - for dist in self[req.key]: - if dist in req: - return dist - return self.obtain(req, installer) # try and download/install - - def obtain(self, requirement, installer=None): - """Obtain a distribution matching `requirement` (e.g. via download) - - Obtain a distro that matches requirement (e.g. via download). In the - base ``Environment`` class, this routine just returns - ``installer(requirement)``, unless `installer` is None, in which case - None is returned instead. This method is a hook that allows subclasses - to attempt other ways of obtaining a distribution before falling back - to the `installer` argument.""" - if installer is not None: - return installer(requirement) - - def __iter__(self): - """Yield the unique project names of the available distributions""" - for key in self._distmap.keys(): - if self[key]: yield key - - def __iadd__(self, other): - """In-place addition of a distribution or environment""" - if isinstance(other,Distribution): - self.add(other) - elif isinstance(other,Environment): - for project in other: - for dist in other[project]: - self.add(dist) - else: - raise TypeError("Can't add %r to environment" % (other,)) - return self - - def __add__(self, other): - """Add an environment or distribution to an environment""" - new = self.__class__([], platform=None, python=None) - for env in self, other: - new += env - return new - - -AvailableDistributions = Environment # XXX backward compatibility - - -class ExtractionError(RuntimeError): - """An error occurred extracting a resource - - The following attributes are available from instances of this exception: - - manager - The resource manager that raised this exception - - cache_path - The base directory for resource extraction - - original_error - The exception instance that caused extraction to fail - """ - - -class ResourceManager: - """Manage resource extraction and packages""" - extraction_path = None - - def __init__(self): - self.cached_files = {} - - def resource_exists(self, package_or_requirement, resource_name): - """Does the named resource exist?""" - return get_provider(package_or_requirement).has_resource(resource_name) - - def resource_isdir(self, package_or_requirement, resource_name): - """Is the named resource an existing directory?""" - return get_provider(package_or_requirement).resource_isdir( - resource_name - ) - - def resource_filename(self, package_or_requirement, resource_name): - """Return a true filesystem path for specified resource""" - return get_provider(package_or_requirement).get_resource_filename( - self, resource_name - ) - - def resource_stream(self, package_or_requirement, resource_name): - """Return a readable file-like object for specified resource""" - return get_provider(package_or_requirement).get_resource_stream( - self, resource_name - ) - - def resource_string(self, package_or_requirement, resource_name): - """Return specified resource as a string""" - return get_provider(package_or_requirement).get_resource_string( - self, resource_name - ) - - def resource_listdir(self, package_or_requirement, resource_name): - """List the contents of the named resource directory""" - return get_provider(package_or_requirement).resource_listdir( - resource_name - ) - - def extraction_error(self): - """Give an error message for problems extracting file(s)""" - - old_exc = sys.exc_info()[1] - cache_path = self.extraction_path or get_default_cache() - - err = ExtractionError("""Can't extract file(s) to egg cache - -The following error occurred while trying to extract file(s) to the Python egg -cache: - - %s - -The Python egg cache directory is currently set to: - - %s - -Perhaps your account does not have write access to this directory? You can -change the cache directory by setting the PYTHON_EGG_CACHE environment -variable to point to an accessible directory. -""" % (old_exc, cache_path) - ) - err.manager = self - err.cache_path = cache_path - err.original_error = old_exc - raise err - - def get_cache_path(self, archive_name, names=()): - """Return absolute location in cache for `archive_name` and `names` - - The parent directory of the resulting path will be created if it does - not already exist. `archive_name` should be the base filename of the - enclosing egg (which may not be the name of the enclosing zipfile!), - including its ".egg" extension. `names`, if provided, should be a - sequence of path name parts "under" the egg's extraction location. - - This method should only be called by resource providers that need to - obtain an extraction location, and only for names they intend to - extract, as it tracks the generated names for possible cleanup later. - """ - extract_path = self.extraction_path or get_default_cache() - target_path = os.path.join(extract_path, archive_name+'-tmp', *names) - try: - _bypass_ensure_directory(target_path) - except: - self.extraction_error() - - self._warn_unsafe_extraction_path(extract_path) - - self.cached_files[target_path] = 1 - return target_path - - @staticmethod - def _warn_unsafe_extraction_path(path): - """ - If the default extraction path is overridden and set to an insecure - location, such as /tmp, it opens up an opportunity for an attacker to - replace an extracted file with an unauthorized payload. Warn the user - if a known insecure location is used. - - See Distribute #375 for more details. - """ - if os.name == 'nt' and not path.startswith(os.environ['windir']): - # On Windows, permissions are generally restrictive by default - # and temp directories are not writable by other users, so - # bypass the warning. - return - mode = os.stat(path).st_mode - if mode & stat.S_IWOTH or mode & stat.S_IWGRP: - msg = ("%s is writable by group/others and vulnerable to attack " - "when " - "used with get_resource_filename. Consider a more secure " - "location (set with .set_extraction_path or the " - "PYTHON_EGG_CACHE environment variable)." % path) - warnings.warn(msg, UserWarning) - - def postprocess(self, tempname, filename): - """Perform any platform-specific postprocessing of `tempname` - - This is where Mac header rewrites should be done; other platforms don't - have anything special they should do. - - Resource providers should call this method ONLY after successfully - extracting a compressed resource. They must NOT call it on resources - that are already in the filesystem. - - `tempname` is the current (temporary) name of the file, and `filename` - is the name it will be renamed to by the caller after this routine - returns. - """ - - if os.name == 'posix': - # Make the resource executable - mode = ((os.stat(tempname).st_mode) | 0x16D) & 0xFFF # 0555, 07777 - os.chmod(tempname, mode) - - def set_extraction_path(self, path): - """Set the base path where resources will be extracted to, if needed. - - If you do not call this routine before any extractions take place, the - path defaults to the return value of ``get_default_cache()``. (Which - is based on the ``PYTHON_EGG_CACHE`` environment variable, with various - platform-specific fallbacks. See that routine's documentation for more - details.) - - Resources are extracted to subdirectories of this path based upon - information given by the ``IResourceProvider``. You may set this to a - temporary directory, but then you must call ``cleanup_resources()`` to - delete the extracted files when done. There is no guarantee that - ``cleanup_resources()`` will be able to remove all extracted files. - - (Note: you may not change the extraction path for a given resource - manager once resources have been extracted, unless you first call - ``cleanup_resources()``.) - """ - if self.cached_files: - raise ValueError( - "Can't change extraction path, files already extracted" - ) - - self.extraction_path = path - - def cleanup_resources(self, force=False): - """ - Delete all extracted resource files and directories, returning a list - of the file and directory names that could not be successfully removed. - This function does not have any concurrency protection, so it should - generally only be called when the extraction path is a temporary - directory exclusive to a single process. This method is not - automatically called; you must call it explicitly or register it as an - ``atexit`` function if you wish to ensure cleanup of a temporary - directory used for extractions. - """ - # XXX - -def get_default_cache(): - """Determine the default cache location - - This returns the ``PYTHON_EGG_CACHE`` environment variable, if set. - Otherwise, on Windows, it returns a "Python-Eggs" subdirectory of the - "Application Data" directory. On all other systems, it's "~/.python-eggs". - """ - try: - return os.environ['PYTHON_EGG_CACHE'] - except KeyError: - pass - - if os.name!='nt': - return os.path.expanduser('~/.python-eggs') - - app_data = 'Application Data' # XXX this may be locale-specific! - app_homes = [ - (('APPDATA',), None), # best option, should be locale-safe - (('USERPROFILE',), app_data), - (('HOMEDRIVE','HOMEPATH'), app_data), - (('HOMEPATH',), app_data), - (('HOME',), None), - (('WINDIR',), app_data), # 95/98/ME - ] - - for keys, subdir in app_homes: - dirname = '' - for key in keys: - if key in os.environ: - dirname = os.path.join(dirname, os.environ[key]) - else: - break - else: - if subdir: - dirname = os.path.join(dirname,subdir) - return os.path.join(dirname, 'Python-Eggs') - else: - raise RuntimeError( - "Please set the PYTHON_EGG_CACHE enviroment variable" - ) - -def safe_name(name): - """Convert an arbitrary string to a standard distribution name - - Any runs of non-alphanumeric/. characters are replaced with a single '-'. - """ - return re.sub('[^A-Za-z0-9.]+', '-', name) - - -def safe_version(version): - """Convert an arbitrary string to a standard version string - - Spaces become dots, and all other non-alphanumeric characters become - dashes, with runs of multiple dashes condensed to a single dash. - """ - version = version.replace(' ','.') - return re.sub('[^A-Za-z0-9.]+', '-', version) - - -def safe_extra(extra): - """Convert an arbitrary string to a standard 'extra' name - - Any runs of non-alphanumeric characters are replaced with a single '_', - and the result is always lowercased. - """ - return re.sub('[^A-Za-z0-9.]+', '_', extra).lower() - - -def to_filename(name): - """Convert a project or version name to its filename-escaped form - - Any '-' characters are currently replaced with '_'. - """ - return name.replace('-','_') - - -class MarkerEvaluation(object): - values = { - 'os_name': lambda: os.name, - 'sys_platform': lambda: sys.platform, - 'python_full_version': lambda: sys.version.split()[0], - 'python_version': lambda:'%s.%s' % (sys.version_info[0], sys.version_info[1]), - 'platform_version': platform.version, - 'platform_machine': platform.machine, - 'python_implementation': platform.python_implementation, - } - - @classmethod - def is_invalid_marker(cls, text): - """ - Validate text as a PEP 426 environment marker; return an exception - if invalid or False otherwise. - """ - try: - cls.evaluate_marker(text) - except SyntaxError: - return cls.normalize_exception(sys.exc_info()[1]) - return False - - @staticmethod - def normalize_exception(exc): - """ - Given a SyntaxError from a marker evaluation, normalize the error message: - - Remove indications of filename and line number. - - Replace platform-specific error messages with standard error messages. - """ - subs = { - 'unexpected EOF while parsing': 'invalid syntax', - 'parenthesis is never closed': 'invalid syntax', - } - exc.filename = None - exc.lineno = None - exc.msg = subs.get(exc.msg, exc.msg) - return exc - - @classmethod - def and_test(cls, nodelist): - # MUST NOT short-circuit evaluation, or invalid syntax can be skipped! - return functools.reduce(operator.and_, [cls.interpret(nodelist[i]) for i in range(1,len(nodelist),2)]) - - @classmethod - def test(cls, nodelist): - # MUST NOT short-circuit evaluation, or invalid syntax can be skipped! - return functools.reduce(operator.or_, [cls.interpret(nodelist[i]) for i in range(1,len(nodelist),2)]) - - @classmethod - def atom(cls, nodelist): - t = nodelist[1][0] - if t == token.LPAR: - if nodelist[2][0] == token.RPAR: - raise SyntaxError("Empty parentheses") - return cls.interpret(nodelist[2]) - raise SyntaxError("Language feature not supported in environment markers") - - @classmethod - def comparison(cls, nodelist): - if len(nodelist)>4: - raise SyntaxError("Chained comparison not allowed in environment markers") - comp = nodelist[2][1] - cop = comp[1] - if comp[0] == token.NAME: - if len(nodelist[2]) == 3: - if cop == 'not': - cop = 'not in' - else: - cop = 'is not' - try: - cop = cls.get_op(cop) - except KeyError: - raise SyntaxError(repr(cop)+" operator not allowed in environment markers") - return cop(cls.evaluate(nodelist[1]), cls.evaluate(nodelist[3])) - - @classmethod - def get_op(cls, op): - ops = { - symbol.test: cls.test, - symbol.and_test: cls.and_test, - symbol.atom: cls.atom, - symbol.comparison: cls.comparison, - 'not in': lambda x, y: x not in y, - 'in': lambda x, y: x in y, - '==': operator.eq, - '!=': operator.ne, - } - if hasattr(symbol, 'or_test'): - ops[symbol.or_test] = cls.test - return ops[op] - - @classmethod - def evaluate_marker(cls, text, extra=None): - """ - Evaluate a PEP 426 environment marker on CPython 2.4+. - Return a boolean indicating the marker result in this environment. - Raise SyntaxError if marker is invalid. - - This implementation uses the 'parser' module, which is not implemented on - Jython and has been superseded by the 'ast' module in Python 2.6 and - later. - """ - return cls.interpret(parser.expr(text).totuple(1)[1]) - - @classmethod - def _markerlib_evaluate(cls, text): - """ - Evaluate a PEP 426 environment marker using markerlib. - Return a boolean indicating the marker result in this environment. - Raise SyntaxError if marker is invalid. - """ - import _markerlib - # markerlib implements Metadata 1.2 (PEP 345) environment markers. - # Translate the variables to Metadata 2.0 (PEP 426). - env = _markerlib.default_environment() - for key in env.keys(): - new_key = key.replace('.', '_') - env[new_key] = env.pop(key) - try: - result = _markerlib.interpret(text, env) - except NameError: - e = sys.exc_info()[1] - raise SyntaxError(e.args[0]) - return result - - if 'parser' not in globals(): - # Fall back to less-complete _markerlib implementation if 'parser' module - # is not available. - evaluate_marker = _markerlib_evaluate - - @classmethod - def interpret(cls, nodelist): - while len(nodelist)==2: nodelist = nodelist[1] - try: - op = cls.get_op(nodelist[0]) - except KeyError: - raise SyntaxError("Comparison or logical expression expected") - return op(nodelist) - - @classmethod - def evaluate(cls, nodelist): - while len(nodelist)==2: nodelist = nodelist[1] - kind = nodelist[0] - name = nodelist[1] - if kind==token.NAME: - try: - op = cls.values[name] - except KeyError: - raise SyntaxError("Unknown name %r" % name) - return op() - if kind==token.STRING: - s = nodelist[1] - if s[:1] not in "'\"" or s.startswith('"""') or s.startswith("'''") \ - or '\\' in s: - raise SyntaxError( - "Only plain strings allowed in environment markers") - return s[1:-1] - raise SyntaxError("Language feature not supported in environment markers") - -invalid_marker = MarkerEvaluation.is_invalid_marker -evaluate_marker = MarkerEvaluation.evaluate_marker - -class NullProvider: - """Try to implement resources and metadata for arbitrary PEP 302 loaders""" - - egg_name = None - egg_info = None - loader = None - - def __init__(self, module): - self.loader = getattr(module, '__loader__', None) - self.module_path = os.path.dirname(getattr(module, '__file__', '')) - - def get_resource_filename(self, manager, resource_name): - return self._fn(self.module_path, resource_name) - - def get_resource_stream(self, manager, resource_name): - return BytesIO(self.get_resource_string(manager, resource_name)) - - def get_resource_string(self, manager, resource_name): - return self._get(self._fn(self.module_path, resource_name)) - - def has_resource(self, resource_name): - return self._has(self._fn(self.module_path, resource_name)) - - def has_metadata(self, name): - return self.egg_info and self._has(self._fn(self.egg_info,name)) - - if sys.version_info <= (3,): - def get_metadata(self, name): - if not self.egg_info: - return "" - return self._get(self._fn(self.egg_info,name)) - else: - def get_metadata(self, name): - if not self.egg_info: - return "" - return self._get(self._fn(self.egg_info,name)).decode("utf-8") - - def get_metadata_lines(self, name): - return yield_lines(self.get_metadata(name)) - - def resource_isdir(self,resource_name): - return self._isdir(self._fn(self.module_path, resource_name)) - - def metadata_isdir(self,name): - return self.egg_info and self._isdir(self._fn(self.egg_info,name)) - - def resource_listdir(self,resource_name): - return self._listdir(self._fn(self.module_path,resource_name)) - - def metadata_listdir(self,name): - if self.egg_info: - return self._listdir(self._fn(self.egg_info,name)) - return [] - - def run_script(self,script_name,namespace): - script = 'scripts/'+script_name - if not self.has_metadata(script): - raise ResolutionError("No script named %r" % script_name) - script_text = self.get_metadata(script).replace('\r\n','\n') - script_text = script_text.replace('\r','\n') - script_filename = self._fn(self.egg_info,script) - namespace['__file__'] = script_filename - if os.path.exists(script_filename): - execfile(script_filename, namespace, namespace) - else: - from linecache import cache - cache[script_filename] = ( - len(script_text), 0, script_text.split('\n'), script_filename - ) - script_code = compile(script_text,script_filename,'exec') - exec(script_code, namespace, namespace) - - def _has(self, path): - raise NotImplementedError( - "Can't perform this operation for unregistered loader type" - ) - - def _isdir(self, path): - raise NotImplementedError( - "Can't perform this operation for unregistered loader type" - ) - - def _listdir(self, path): - raise NotImplementedError( - "Can't perform this operation for unregistered loader type" - ) - - def _fn(self, base, resource_name): - if resource_name: - return os.path.join(base, *resource_name.split('/')) - return base - - def _get(self, path): - if hasattr(self.loader, 'get_data'): - return self.loader.get_data(path) - raise NotImplementedError( - "Can't perform this operation for loaders without 'get_data()'" - ) - -register_loader_type(object, NullProvider) - - -class EggProvider(NullProvider): - """Provider based on a virtual filesystem""" - - def __init__(self,module): - NullProvider.__init__(self,module) - self._setup_prefix() - - def _setup_prefix(self): - # we assume here that our metadata may be nested inside a "basket" - # of multiple eggs; that's why we use module_path instead of .archive - path = self.module_path - old = None - while path!=old: - if path.lower().endswith('.egg'): - self.egg_name = os.path.basename(path) - self.egg_info = os.path.join(path, 'EGG-INFO') - self.egg_root = path - break - old = path - path, base = os.path.split(path) - -class DefaultProvider(EggProvider): - """Provides access to package resources in the filesystem""" - - def _has(self, path): - return os.path.exists(path) - - def _isdir(self,path): - return os.path.isdir(path) - - def _listdir(self,path): - return os.listdir(path) - - def get_resource_stream(self, manager, resource_name): - return open(self._fn(self.module_path, resource_name), 'rb') - - def _get(self, path): - stream = open(path, 'rb') - try: - return stream.read() - finally: - stream.close() - -register_loader_type(type(None), DefaultProvider) - -if importlib_bootstrap is not None: - register_loader_type(importlib_bootstrap.SourceFileLoader, DefaultProvider) - - -class EmptyProvider(NullProvider): - """Provider that returns nothing for all requests""" - - _isdir = _has = lambda self,path: False - _get = lambda self,path: '' - _listdir = lambda self,path: [] - module_path = None - - def __init__(self): - pass - -empty_provider = EmptyProvider() - - -def build_zipmanifest(path): - """ - This builds a similar dictionary to the zipimport directory - caches. However instead of tuples, ZipInfo objects are stored. - - The translation of the tuple is as follows: - * [0] - zipinfo.filename on stock pythons this needs "/" --> os.sep - on pypy it is the same (one reason why distribute did work - in some cases on pypy and win32). - * [1] - zipinfo.compress_type - * [2] - zipinfo.compress_size - * [3] - zipinfo.file_size - * [4] - len(utf-8 encoding of filename) if zipinfo & 0x800 - len(ascii encoding of filename) otherwise - * [5] - (zipinfo.date_time[0] - 1980) << 9 | - zipinfo.date_time[1] << 5 | zipinfo.date_time[2] - * [6] - (zipinfo.date_time[3] - 1980) << 11 | - zipinfo.date_time[4] << 5 | (zipinfo.date_time[5] // 2) - * [7] - zipinfo.CRC - """ - zipinfo = dict() - zfile = zipfile.ZipFile(path) - #Got ZipFile has not __exit__ on python 3.1 - try: - for zitem in zfile.namelist(): - zpath = zitem.replace('/', os.sep) - zipinfo[zpath] = zfile.getinfo(zitem) - assert zipinfo[zpath] is not None - finally: - zfile.close() - return zipinfo - - -class ZipProvider(EggProvider): - """Resource support for zips and eggs""" - - eagers = None - - def __init__(self, module): - EggProvider.__init__(self,module) - self.zipinfo = build_zipmanifest(self.loader.archive) - self.zip_pre = self.loader.archive+os.sep - - def _zipinfo_name(self, fspath): - # Convert a virtual filename (full path to file) into a zipfile subpath - # usable with the zipimport directory cache for our target archive - if fspath.startswith(self.zip_pre): - return fspath[len(self.zip_pre):] - raise AssertionError( - "%s is not a subpath of %s" % (fspath,self.zip_pre) - ) - - def _parts(self,zip_path): - # Convert a zipfile subpath into an egg-relative path part list - fspath = self.zip_pre+zip_path # pseudo-fs path - if fspath.startswith(self.egg_root+os.sep): - return fspath[len(self.egg_root)+1:].split(os.sep) - raise AssertionError( - "%s is not a subpath of %s" % (fspath,self.egg_root) - ) - - def get_resource_filename(self, manager, resource_name): - if not self.egg_name: - raise NotImplementedError( - "resource_filename() only supported for .egg, not .zip" - ) - # no need to lock for extraction, since we use temp names - zip_path = self._resource_to_zip(resource_name) - eagers = self._get_eager_resources() - if '/'.join(self._parts(zip_path)) in eagers: - for name in eagers: - self._extract_resource(manager, self._eager_to_zip(name)) - return self._extract_resource(manager, zip_path) - - @staticmethod - def _get_date_and_size(zip_stat): - size = zip_stat.file_size - date_time = zip_stat.date_time + (0, 0, -1) # ymdhms+wday, yday, dst - #1980 offset already done - timestamp = time.mktime(date_time) - return timestamp, size - - def _extract_resource(self, manager, zip_path): - - if zip_path in self._index(): - for name in self._index()[zip_path]: - last = self._extract_resource( - manager, os.path.join(zip_path, name) - ) - return os.path.dirname(last) # return the extracted directory name - - timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) - - if not WRITE_SUPPORT: - raise IOError('"os.rename" and "os.unlink" are not supported ' - 'on this platform') - try: - - real_path = manager.get_cache_path( - self.egg_name, self._parts(zip_path) - ) - - if self._is_current(real_path, zip_path): - return real_path - - outf, tmpnam = _mkstemp(".$extract", dir=os.path.dirname(real_path)) - os.write(outf, self.loader.get_data(zip_path)) - os.close(outf) - utime(tmpnam, (timestamp,timestamp)) - manager.postprocess(tmpnam, real_path) - - try: - rename(tmpnam, real_path) - - except os.error: - if os.path.isfile(real_path): - if self._is_current(real_path, zip_path): - # the file became current since it was checked above, - # so proceed. - return real_path - elif os.name=='nt': # Windows, del old file and retry - unlink(real_path) - rename(tmpnam, real_path) - return real_path - raise - - except os.error: - manager.extraction_error() # report a user-friendly error - - return real_path - - def _is_current(self, file_path, zip_path): - """ - Return True if the file_path is current for this zip_path - """ - timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) - if not os.path.isfile(file_path): - return False - stat = os.stat(file_path) - if stat.st_size!=size or stat.st_mtime!=timestamp: - return False - # check that the contents match - zip_contents = self.loader.get_data(zip_path) - f = open(file_path, 'rb') - file_contents = f.read() - f.close() - return zip_contents == file_contents - - def _get_eager_resources(self): - if self.eagers is None: - eagers = [] - for name in ('native_libs.txt', 'eager_resources.txt'): - if self.has_metadata(name): - eagers.extend(self.get_metadata_lines(name)) - self.eagers = eagers - return self.eagers - - def _index(self): - try: - return self._dirindex - except AttributeError: - ind = {} - for path in self.zipinfo: - parts = path.split(os.sep) - while parts: - parent = os.sep.join(parts[:-1]) - if parent in ind: - ind[parent].append(parts[-1]) - break - else: - ind[parent] = [parts.pop()] - self._dirindex = ind - return ind - - def _has(self, fspath): - zip_path = self._zipinfo_name(fspath) - return zip_path in self.zipinfo or zip_path in self._index() - - def _isdir(self,fspath): - return self._zipinfo_name(fspath) in self._index() - - def _listdir(self,fspath): - return list(self._index().get(self._zipinfo_name(fspath), ())) - - def _eager_to_zip(self,resource_name): - return self._zipinfo_name(self._fn(self.egg_root,resource_name)) - - def _resource_to_zip(self,resource_name): - return self._zipinfo_name(self._fn(self.module_path,resource_name)) - -register_loader_type(zipimport.zipimporter, ZipProvider) - - -class FileMetadata(EmptyProvider): - """Metadata handler for standalone PKG-INFO files - - Usage:: - - metadata = FileMetadata("/path/to/PKG-INFO") - - This provider rejects all data and metadata requests except for PKG-INFO, - which is treated as existing, and will be the contents of the file at - the provided location. - """ - - def __init__(self,path): - self.path = path - - def has_metadata(self,name): - return name=='PKG-INFO' - - def get_metadata(self,name): - if name=='PKG-INFO': - f = open(self.path,'rU') - metadata = f.read() - f.close() - return metadata - raise KeyError("No metadata except PKG-INFO is available") - - def get_metadata_lines(self,name): - return yield_lines(self.get_metadata(name)) - - -class PathMetadata(DefaultProvider): - """Metadata provider for egg directories - - Usage:: - - # Development eggs: - - egg_info = "/path/to/PackageName.egg-info" - base_dir = os.path.dirname(egg_info) - metadata = PathMetadata(base_dir, egg_info) - dist_name = os.path.splitext(os.path.basename(egg_info))[0] - dist = Distribution(basedir,project_name=dist_name,metadata=metadata) - - # Unpacked egg directories: - - egg_path = "/path/to/PackageName-ver-pyver-etc.egg" - metadata = PathMetadata(egg_path, os.path.join(egg_path,'EGG-INFO')) - dist = Distribution.from_filename(egg_path, metadata=metadata) - """ - - def __init__(self, path, egg_info): - self.module_path = path - self.egg_info = egg_info - - -class EggMetadata(ZipProvider): - """Metadata provider for .egg files""" - - def __init__(self, importer): - """Create a metadata provider from a zipimporter""" - - self.zipinfo = build_zipmanifest(importer.archive) - self.zip_pre = importer.archive+os.sep - self.loader = importer - if importer.prefix: - self.module_path = os.path.join(importer.archive, importer.prefix) - else: - self.module_path = importer.archive - self._setup_prefix() - -_declare_state('dict', _distribution_finders = {}) - -def register_finder(importer_type, distribution_finder): - """Register `distribution_finder` to find distributions in sys.path items - - `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item - handler), and `distribution_finder` is a callable that, passed a path - item and the importer instance, yields ``Distribution`` instances found on - that path item. See ``pkg_resources.find_on_path`` for an example.""" - _distribution_finders[importer_type] = distribution_finder - - -def find_distributions(path_item, only=False): - """Yield distributions accessible via `path_item`""" - importer = get_importer(path_item) - finder = _find_adapter(_distribution_finders, importer) - return finder(importer, path_item, only) - -def find_eggs_in_zip(importer, path_item, only=False): - """ - Find eggs in zip files; possibly multiple nested eggs. - """ - if importer.archive.endswith('.whl'): - # wheels are not supported with this finder - # they don't have PKG-INFO metadata, and won't ever contain eggs - return - metadata = EggMetadata(importer) - if metadata.has_metadata('PKG-INFO'): - yield Distribution.from_filename(path_item, metadata=metadata) - if only: - return # don't yield nested distros - for subitem in metadata.resource_listdir('/'): - if subitem.endswith('.egg'): - subpath = os.path.join(path_item, subitem) - for dist in find_eggs_in_zip(zipimport.zipimporter(subpath), subpath): - yield dist - -register_finder(zipimport.zipimporter, find_eggs_in_zip) - -def find_nothing(importer, path_item, only=False): - return () -register_finder(object,find_nothing) - -def find_on_path(importer, path_item, only=False): - """Yield distributions accessible on a sys.path directory""" - path_item = _normalize_cached(path_item) - - if os.path.isdir(path_item) and os.access(path_item, os.R_OK): - if path_item.lower().endswith('.egg'): - # unpacked egg - yield Distribution.from_filename( - path_item, metadata=PathMetadata( - path_item, os.path.join(path_item,'EGG-INFO') - ) - ) - else: - # scan for .egg and .egg-info in directory - for entry in os.listdir(path_item): - lower = entry.lower() - if lower.endswith('.egg-info') or lower.endswith('.dist-info'): - fullpath = os.path.join(path_item, entry) - if os.path.isdir(fullpath): - # egg-info directory, allow getting metadata - metadata = PathMetadata(path_item, fullpath) - else: - metadata = FileMetadata(fullpath) - yield Distribution.from_location( - path_item,entry,metadata,precedence=DEVELOP_DIST - ) - elif not only and lower.endswith('.egg'): - for dist in find_distributions(os.path.join(path_item, entry)): - yield dist - elif not only and lower.endswith('.egg-link'): - entry_file = open(os.path.join(path_item, entry)) - try: - entry_lines = entry_file.readlines() - finally: - entry_file.close() - for line in entry_lines: - if not line.strip(): continue - for item in find_distributions(os.path.join(path_item,line.rstrip())): - yield item - break -register_finder(pkgutil.ImpImporter,find_on_path) - -if importlib_bootstrap is not None: - register_finder(importlib_bootstrap.FileFinder, find_on_path) - -_declare_state('dict', _namespace_handlers={}) -_declare_state('dict', _namespace_packages={}) - - -def register_namespace_handler(importer_type, namespace_handler): - """Register `namespace_handler` to declare namespace packages - - `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item - handler), and `namespace_handler` is a callable like this:: - - def namespace_handler(importer,path_entry,moduleName,module): - # return a path_entry to use for child packages - - Namespace handlers are only called if the importer object has already - agreed that it can handle the relevant path item, and they should only - return a subpath if the module __path__ does not already contain an - equivalent subpath. For an example namespace handler, see - ``pkg_resources.file_ns_handler``. - """ - _namespace_handlers[importer_type] = namespace_handler - -def _handle_ns(packageName, path_item): - """Ensure that named package includes a subpath of path_item (if needed)""" - - importer = get_importer(path_item) - if importer is None: - return None - loader = importer.find_module(packageName) - if loader is None: - return None - module = sys.modules.get(packageName) - if module is None: - module = sys.modules[packageName] = imp.new_module(packageName) - module.__path__ = [] - _set_parent_ns(packageName) - elif not hasattr(module,'__path__'): - raise TypeError("Not a package:", packageName) - handler = _find_adapter(_namespace_handlers, importer) - subpath = handler(importer, path_item, packageName, module) - if subpath is not None: - path = module.__path__ - path.append(subpath) - loader.load_module(packageName) - for path_item in path: - if path_item not in module.__path__: - module.__path__.append(path_item) - return subpath - -def declare_namespace(packageName): - """Declare that package 'packageName' is a namespace package""" - - imp.acquire_lock() - try: - if packageName in _namespace_packages: - return - - path, parent = sys.path, None - if '.' in packageName: - parent = '.'.join(packageName.split('.')[:-1]) - declare_namespace(parent) - if parent not in _namespace_packages: - __import__(parent) - try: - path = sys.modules[parent].__path__ - except AttributeError: - raise TypeError("Not a package:", parent) - - # Track what packages are namespaces, so when new path items are added, - # they can be updated - _namespace_packages.setdefault(parent,[]).append(packageName) - _namespace_packages.setdefault(packageName,[]) - - for path_item in path: - # Ensure all the parent's path items are reflected in the child, - # if they apply - _handle_ns(packageName, path_item) - - finally: - imp.release_lock() - -def fixup_namespace_packages(path_item, parent=None): - """Ensure that previously-declared namespace packages include path_item""" - imp.acquire_lock() - try: - for package in _namespace_packages.get(parent,()): - subpath = _handle_ns(package, path_item) - if subpath: fixup_namespace_packages(subpath,package) - finally: - imp.release_lock() - -def file_ns_handler(importer, path_item, packageName, module): - """Compute an ns-package subpath for a filesystem or zipfile importer""" - - subpath = os.path.join(path_item, packageName.split('.')[-1]) - normalized = _normalize_cached(subpath) - for item in module.__path__: - if _normalize_cached(item)==normalized: - break - else: - # Only return the path if it's not already there - return subpath - -register_namespace_handler(pkgutil.ImpImporter,file_ns_handler) -register_namespace_handler(zipimport.zipimporter,file_ns_handler) - -if importlib_bootstrap is not None: - register_namespace_handler(importlib_bootstrap.FileFinder, file_ns_handler) - - -def null_ns_handler(importer, path_item, packageName, module): - return None - -register_namespace_handler(object,null_ns_handler) - - -def normalize_path(filename): - """Normalize a file/dir name for comparison purposes""" - return os.path.normcase(os.path.realpath(filename)) - -def _normalize_cached(filename,_cache={}): - try: - return _cache[filename] - except KeyError: - _cache[filename] = result = normalize_path(filename) - return result - -def _set_parent_ns(packageName): - parts = packageName.split('.') - name = parts.pop() - if parts: - parent = '.'.join(parts) - setattr(sys.modules[parent], name, sys.modules[packageName]) - - -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() - if s and not s.startswith('#'): # skip blank lines/comments - yield s - else: - for ss in strs: - for s in yield_lines(ss): - yield s - -LINE_END = re.compile(r"\s*(#.*)?$").match # whitespace and comment -CONTINUE = re.compile(r"\s*\\\s*(#.*)?$").match # line continuation -DISTRO = re.compile(r"\s*((\w|[-.])+)").match # Distribution or extra -VERSION = re.compile(r"\s*(<=?|>=?|==|!=)\s*((\w|[-.])+)").match # ver. info -COMMA = re.compile(r"\s*,").match # comma between items -OBRACKET = re.compile(r"\s*\[").match -CBRACKET = re.compile(r"\s*\]").match -MODULE = re.compile(r"\w+(\.\w+)*$").match -EGG_NAME = re.compile( - r"(?P[^-]+)" - r"( -(?P[^-]+) (-py(?P[^-]+) (-(?P.+))? )? )?", - re.VERBOSE | re.IGNORECASE -).match - -component_re = re.compile(r'(\d+ | [a-z]+ | \.| -)', re.VERBOSE) -replace = {'pre':'c', 'preview':'c','-':'final-','rc':'c','dev':'@'}.get - -def _parse_version_parts(s): - for part in component_re.split(s): - part = replace(part,part) - if not part or part=='.': - continue - if part[:1] in '0123456789': - yield part.zfill(8) # pad for numeric comparison - else: - yield '*'+part - - yield '*final' # ensure that alpha/beta/candidate are before final - -def parse_version(s): - """Convert a version string to a chronologically-sortable key - - This is a rough cross between distutils' StrictVersion and LooseVersion; - if you give it versions that would work with StrictVersion, then it behaves - the same; otherwise it acts like a slightly-smarter LooseVersion. It is - *possible* to create pathological version coding schemes that will fool - this parser, but they should be very rare in practice. - - The returned value will be a tuple of strings. Numeric portions of the - version are padded to 8 digits so they will compare numerically, but - without relying on how numbers compare relative to strings. Dots are - dropped, but dashes are retained. Trailing zeros between alpha segments - or dashes are suppressed, so that e.g. "2.4.0" is considered the same as - "2.4". Alphanumeric parts are lower-cased. - - The algorithm assumes that strings like "-" and any alpha string that - alphabetically follows "final" represents a "patch level". So, "2.4-1" - is assumed to be a branch or patch of "2.4", and therefore "2.4.1" is - considered newer than "2.4-1", which in turn is newer than "2.4". - - Strings like "a", "b", "c", "alpha", "beta", "candidate" and so on (that - come before "final" alphabetically) are assumed to be pre-release versions, - so that the version "2.4" is considered newer than "2.4a1". - - Finally, to handle miscellaneous cases, the strings "pre", "preview", and - "rc" are treated as if they were "c", i.e. as though they were release - candidates, and therefore are not as new as a version string that does not - contain them, and "dev" is replaced with an '@' so that it sorts lower than - than any other pre-release tag. - """ - parts = [] - for part in _parse_version_parts(s.lower()): - if part.startswith('*'): - if part<'*final': # remove '-' before a prerelease tag - while parts and parts[-1]=='*final-': parts.pop() - # remove trailing zeros from each series of numeric parts - while parts and parts[-1]=='00000000': - parts.pop() - parts.append(part) - return tuple(parts) -class EntryPoint(object): - """Object representing an advertised importable object""" - - def __init__(self, name, module_name, attrs=(), extras=(), dist=None): - if not MODULE(module_name): - raise ValueError("Invalid module name", module_name) - self.name = name - self.module_name = module_name - self.attrs = tuple(attrs) - self.extras = Requirement.parse(("x[%s]" % ','.join(extras))).extras - self.dist = dist - - def __str__(self): - s = "%s = %s" % (self.name, self.module_name) - if self.attrs: - s += ':' + '.'.join(self.attrs) - if self.extras: - s += ' [%s]' % ','.join(self.extras) - return s - - def __repr__(self): - return "EntryPoint.parse(%r)" % str(self) - - def load(self, require=True, env=None, installer=None): - if require: self.require(env, installer) - entry = __import__(self.module_name, globals(),globals(), ['__name__']) - for attr in self.attrs: - try: - entry = getattr(entry,attr) - except AttributeError: - raise ImportError("%r has no %r attribute" % (entry,attr)) - return entry - - def require(self, env=None, installer=None): - if self.extras and not self.dist: - raise UnknownExtra("Can't require() without a distribution", self) - list(map(working_set.add, - working_set.resolve(self.dist.requires(self.extras),env,installer))) - - @classmethod - def parse(cls, src, dist=None): - """Parse a single entry point from string `src` - - Entry point syntax follows the form:: - - name = some.module:some.attr [extra1,extra2] - - The entry name and module name are required, but the ``:attrs`` and - ``[extras]`` parts are optional - """ - try: - attrs = extras = () - name,value = src.split('=',1) - if '[' in value: - value,extras = value.split('[',1) - req = Requirement.parse("x["+extras) - if req.specs: raise ValueError - extras = req.extras - if ':' in value: - value,attrs = value.split(':',1) - if not MODULE(attrs.rstrip()): - raise ValueError - attrs = attrs.rstrip().split('.') - except ValueError: - raise ValueError( - "EntryPoint must be in 'name=module:attrs [extras]' format", - src - ) - else: - return cls(name.strip(), value.strip(), attrs, extras, dist) - - @classmethod - def parse_group(cls, group, lines, dist=None): - """Parse an entry point group""" - if not MODULE(group): - raise ValueError("Invalid group name", group) - this = {} - for line in yield_lines(lines): - ep = cls.parse(line, dist) - if ep.name in this: - raise ValueError("Duplicate entry point", group, ep.name) - this[ep.name]=ep - return this - - @classmethod - def parse_map(cls, data, dist=None): - """Parse a map of entry point groups""" - if isinstance(data,dict): - data = data.items() - else: - data = split_sections(data) - maps = {} - for group, lines in data: - if group is None: - if not lines: - continue - raise ValueError("Entry points must be listed in groups") - group = group.strip() - if group in maps: - raise ValueError("Duplicate group name", group) - maps[group] = cls.parse_group(group, lines, dist) - return maps - - -def _remove_md5_fragment(location): - if not location: - return '' - parsed = urlparse(location) - if parsed[-1].startswith('md5='): - return urlunparse(parsed[:-1] + ('',)) - return location - - -class Distribution(object): - """Wrap an actual or potential sys.path entry w/metadata""" - PKG_INFO = 'PKG-INFO' - - def __init__(self, location=None, metadata=None, project_name=None, - version=None, py_version=PY_MAJOR, platform=None, - precedence=EGG_DIST): - self.project_name = safe_name(project_name or 'Unknown') - if version is not None: - self._version = safe_version(version) - self.py_version = py_version - self.platform = platform - self.location = location - self.precedence = precedence - self._provider = metadata or empty_provider - - @classmethod - def from_location(cls,location,basename,metadata=None,**kw): - project_name, version, py_version, platform = [None]*4 - basename, ext = os.path.splitext(basename) - if ext.lower() in _distributionImpl: - # .dist-info gets much metadata differently - match = EGG_NAME(basename) - if match: - project_name, version, py_version, platform = match.group( - 'name','ver','pyver','plat' - ) - cls = _distributionImpl[ext.lower()] - return cls( - location, metadata, project_name=project_name, version=version, - py_version=py_version, platform=platform, **kw - ) - - hashcmp = property( - lambda self: ( - getattr(self,'parsed_version',()), - self.precedence, - self.key, - _remove_md5_fragment(self.location), - self.py_version, - self.platform - ) - ) - def __hash__(self): return hash(self.hashcmp) - def __lt__(self, other): - return self.hashcmp < other.hashcmp - def __le__(self, other): - return self.hashcmp <= other.hashcmp - def __gt__(self, other): - return self.hashcmp > other.hashcmp - def __ge__(self, other): - return self.hashcmp >= other.hashcmp - def __eq__(self, other): - if not isinstance(other, self.__class__): - # It's not a Distribution, so they are not equal - return False - return self.hashcmp == other.hashcmp - def __ne__(self, other): - return not self == other - - # These properties have to be lazy so that we don't have to load any - # metadata until/unless it's actually needed. (i.e., some distributions - # may not know their name or version without loading PKG-INFO) - - @property - def key(self): - try: - return self._key - except AttributeError: - self._key = key = self.project_name.lower() - return key - - @property - def parsed_version(self): - try: - return self._parsed_version - except AttributeError: - self._parsed_version = pv = parse_version(self.version) - return pv - - @property - def version(self): - try: - return self._version - except AttributeError: - for line in self._get_metadata(self.PKG_INFO): - if line.lower().startswith('version:'): - self._version = safe_version(line.split(':',1)[1].strip()) - return self._version - else: - raise ValueError( - "Missing 'Version:' header and/or %s file" % self.PKG_INFO, self - ) - - @property - def _dep_map(self): - try: - return self.__dep_map - except AttributeError: - dm = self.__dep_map = {None: []} - for name in 'requires.txt', 'depends.txt': - for extra,reqs in split_sections(self._get_metadata(name)): - if extra: - if ':' in extra: - extra, marker = extra.split(':',1) - if invalid_marker(marker): - reqs=[] # XXX warn - elif not evaluate_marker(marker): - reqs=[] - extra = safe_extra(extra) or None - dm.setdefault(extra,[]).extend(parse_requirements(reqs)) - return dm - - def requires(self,extras=()): - """List of Requirements needed for this distro if `extras` are used""" - dm = self._dep_map - deps = [] - deps.extend(dm.get(None,())) - for ext in extras: - try: - deps.extend(dm[safe_extra(ext)]) - except KeyError: - raise UnknownExtra( - "%s has no such extra feature %r" % (self, ext) - ) - return deps - - def _get_metadata(self,name): - if self.has_metadata(name): - for line in self.get_metadata_lines(name): - yield line - - def activate(self,path=None): - """Ensure distribution is importable on `path` (default=sys.path)""" - if path is None: path = sys.path - self.insert_on(path) - if path is sys.path: - fixup_namespace_packages(self.location) - for pkg in self._get_metadata('namespace_packages.txt'): - if pkg in sys.modules: - declare_namespace(pkg) - - def egg_name(self): - """Return what this distribution's standard .egg filename should be""" - filename = "%s-%s-py%s" % ( - to_filename(self.project_name), to_filename(self.version), - self.py_version or PY_MAJOR - ) - - if self.platform: - filename += '-'+self.platform - return filename - - def __repr__(self): - if self.location: - return "%s (%s)" % (self,self.location) - else: - return str(self) - - def __str__(self): - try: version = getattr(self,'version',None) - except ValueError: version = None - version = version or "[unknown version]" - return "%s %s" % (self.project_name,version) - - def __getattr__(self,attr): - """Delegate all unrecognized public attributes to .metadata provider""" - if attr.startswith('_'): - raise AttributeError(attr) - return getattr(self._provider, attr) - - @classmethod - def from_filename(cls,filename,metadata=None, **kw): - return cls.from_location( - _normalize_cached(filename), os.path.basename(filename), metadata, - **kw - ) - - def as_requirement(self): - """Return a ``Requirement`` that matches this distribution exactly""" - return Requirement.parse('%s==%s' % (self.project_name, self.version)) - - def load_entry_point(self, group, name): - """Return the `name` entry point of `group` or raise ImportError""" - ep = self.get_entry_info(group,name) - if ep is None: - raise ImportError("Entry point %r not found" % ((group,name),)) - return ep.load() - - def get_entry_map(self, group=None): - """Return the entry point map for `group`, or the full entry map""" - try: - ep_map = self._ep_map - except AttributeError: - ep_map = self._ep_map = EntryPoint.parse_map( - self._get_metadata('entry_points.txt'), self - ) - if group is not None: - return ep_map.get(group,{}) - return ep_map - - def get_entry_info(self, group, name): - """Return the EntryPoint object for `group`+`name`, or ``None``""" - return self.get_entry_map(group).get(name) - - def insert_on(self, path, loc = None): - """Insert self.location in path before its nearest parent directory""" - - loc = loc or self.location - if not loc: - return - - nloc = _normalize_cached(loc) - bdir = os.path.dirname(nloc) - npath= [(p and _normalize_cached(p) or p) for p in path] - - for p, item in enumerate(npath): - if item==nloc: - break - elif item==bdir and self.precedence==EGG_DIST: - # if it's an .egg, give it precedence over its directory - if path is sys.path: - self.check_version_conflict() - path.insert(p, loc) - npath.insert(p, nloc) - break - else: - if path is sys.path: - self.check_version_conflict() - path.append(loc) - return - - # p is the spot where we found or inserted loc; now remove duplicates - while 1: - try: - np = npath.index(nloc, p+1) - except ValueError: - break - else: - del npath[np], path[np] - p = np # ha! - - return - - def check_version_conflict(self): - if self.key=='setuptools': - return # ignore the inevitable setuptools self-conflicts :( - - nsp = dict.fromkeys(self._get_metadata('namespace_packages.txt')) - loc = normalize_path(self.location) - for modname in self._get_metadata('top_level.txt'): - if (modname not in sys.modules or modname in nsp - or modname in _namespace_packages): - continue - if modname in ('pkg_resources', 'setuptools', 'site'): - continue - fn = getattr(sys.modules[modname], '__file__', None) - if fn and (normalize_path(fn).startswith(loc) or - fn.startswith(self.location)): - continue - issue_warning( - "Module %s was already imported from %s, but %s is being added" - " to sys.path" % (modname, fn, self.location), - ) - - def has_version(self): - try: - self.version - except ValueError: - issue_warning("Unbuilt egg for "+repr(self)) - return False - return True - - def clone(self,**kw): - """Copy this distribution, substituting in any changed keyword args""" - for attr in ( - 'project_name', 'version', 'py_version', 'platform', 'location', - 'precedence' - ): - kw.setdefault(attr, getattr(self,attr,None)) - kw.setdefault('metadata', self._provider) - return self.__class__(**kw) - - @property - def extras(self): - return [dep for dep in self._dep_map if dep] - - -class DistInfoDistribution(Distribution): - """Wrap an actual or potential sys.path entry w/metadata, .dist-info style""" - PKG_INFO = 'METADATA' - EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])") - - @property - def _parsed_pkg_info(self): - """Parse and cache metadata""" - try: - return self._pkg_info - except AttributeError: - from email.parser import Parser - self._pkg_info = Parser().parsestr(self.get_metadata(self.PKG_INFO)) - return self._pkg_info - - @property - def _dep_map(self): - try: - return self.__dep_map - except AttributeError: - self.__dep_map = self._compute_dependencies() - return self.__dep_map - - def _preparse_requirement(self, requires_dist): - """Convert 'Foobar (1); baz' to ('Foobar ==1', 'baz') - Split environment marker, add == prefix to version specifiers as - necessary, and remove parenthesis. - """ - parts = requires_dist.split(';', 1) + [''] - distvers = parts[0].strip() - mark = parts[1].strip() - distvers = re.sub(self.EQEQ, r"\1==\2\3", distvers) - distvers = distvers.replace('(', '').replace(')', '') - return (distvers, mark) - - def _compute_dependencies(self): - """Recompute this distribution's dependencies.""" - from _markerlib import compile as compile_marker - dm = self.__dep_map = {None: []} - - reqs = [] - # Including any condition expressions - for req in self._parsed_pkg_info.get_all('Requires-Dist') or []: - distvers, mark = self._preparse_requirement(req) - parsed = next(parse_requirements(distvers)) - parsed.marker_fn = compile_marker(mark) - reqs.append(parsed) - - def reqs_for_extra(extra): - for req in reqs: - if req.marker_fn(override={'extra':extra}): - yield req - - common = frozenset(reqs_for_extra(None)) - dm[None].extend(common) - - for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []: - extra = safe_extra(extra.strip()) - dm[extra] = list(frozenset(reqs_for_extra(extra)) - common) - - return dm - - -_distributionImpl = { - '.egg': Distribution, - '.egg-info': Distribution, - '.dist-info': DistInfoDistribution, - } - - -def issue_warning(*args,**kw): - level = 1 - g = globals() - try: - # find the first stack frame that is *not* code in - # the pkg_resources module, to use for the warning - while sys._getframe(level).f_globals is g: - level += 1 - except ValueError: - pass - from warnings import warn - warn(stacklevel = level+1, *args, **kw) - - -def parse_requirements(strs): - """Yield ``Requirement`` objects for each specification in `strs` - - `strs` must be an instance of ``basestring``, or a (possibly-nested) - iterable thereof. - """ - # create a steppable iterator, so we can handle \-continuations - lines = iter(yield_lines(strs)) - - def scan_list(ITEM,TERMINATOR,line,p,groups,item_name): - - items = [] - - while not TERMINATOR(line,p): - if CONTINUE(line,p): - try: - line = next(lines) - p = 0 - except StopIteration: - raise ValueError( - "\\ must not appear on the last nonblank line" - ) - - match = ITEM(line,p) - if not match: - raise ValueError("Expected "+item_name+" in",line,"at",line[p:]) - - items.append(match.group(*groups)) - p = match.end() - - match = COMMA(line,p) - if match: - p = match.end() # skip the comma - elif not TERMINATOR(line,p): - raise ValueError( - "Expected ',' or end-of-list in",line,"at",line[p:] - ) - - match = TERMINATOR(line,p) - if match: p = match.end() # skip the terminator, if any - return line, p, items - - for line in lines: - match = DISTRO(line) - if not match: - raise ValueError("Missing distribution spec", line) - project_name = match.group(1) - p = match.end() - extras = [] - - match = OBRACKET(line,p) - if match: - p = match.end() - line, p, extras = scan_list( - DISTRO, CBRACKET, line, p, (1,), "'extra' name" - ) - - line, p, specs = scan_list(VERSION,LINE_END,line,p,(1,2),"version spec") - specs = [(op,safe_version(val)) for op,val in specs] - yield Requirement(project_name, specs, extras) - - -def _sort_dists(dists): - tmp = [(dist.hashcmp,dist) for dist in dists] - tmp.sort() - dists[::-1] = [d for hc,d in tmp] - - -class Requirement: - def __init__(self, project_name, specs, extras): - """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!""" - self.unsafe_name, project_name = project_name, safe_name(project_name) - self.project_name, self.key = project_name, project_name.lower() - index = [(parse_version(v),state_machine[op],op,v) for op,v in specs] - index.sort() - self.specs = [(op,ver) for parsed,trans,op,ver in index] - self.index, self.extras = index, tuple(map(safe_extra,extras)) - self.hashCmp = ( - self.key, tuple([(op,parsed) for parsed,trans,op,ver in index]), - frozenset(self.extras) - ) - self.__hash = hash(self.hashCmp) - - def __str__(self): - specs = ','.join([''.join(s) for s in self.specs]) - extras = ','.join(self.extras) - if extras: extras = '[%s]' % extras - return '%s%s%s' % (self.project_name, extras, specs) - - def __eq__(self,other): - return isinstance(other,Requirement) and self.hashCmp==other.hashCmp - - def __contains__(self,item): - if isinstance(item,Distribution): - if item.key != self.key: return False - if self.index: item = item.parsed_version # only get if we need it - elif isinstance(item,basestring): - item = parse_version(item) - last = None - compare = lambda a, b: (a > b) - (a < b) # -1, 0, 1 - for parsed,trans,op,ver in self.index: - action = trans[compare(item,parsed)] # Indexing: 0, 1, -1 - if action=='F': - return False - elif action=='T': - return True - elif action=='+': - last = True - elif action=='-' or last is None: last = False - if last is None: last = True # no rules encountered - return last - - def __hash__(self): - return self.__hash - - def __repr__(self): return "Requirement.parse(%r)" % str(self) - - @staticmethod - def parse(s): - reqs = list(parse_requirements(s)) - if reqs: - if len(reqs)==1: - return reqs[0] - raise ValueError("Expected only one requirement", s) - raise ValueError("No requirements found", s) - -state_machine = { - # =>< - '<': '--T', - '<=': 'T-T', - '>': 'F+F', - '>=': 'T+F', - '==': 'T..', - '!=': 'F++', -} - - -def _get_mro(cls): - """Get an mro for a type or classic class""" - if not isinstance(cls,type): - class cls(cls,object): pass - return cls.__mro__[1:] - return cls.__mro__ - -def _find_adapter(registry, ob): - """Return an adapter factory for `ob` from `registry`""" - for t in _get_mro(getattr(ob, '__class__', type(ob))): - if t in registry: - return registry[t] - - -def ensure_directory(path): - """Ensure that the parent directory of `path` exists""" - dirname = os.path.dirname(path) - if not os.path.isdir(dirname): - os.makedirs(dirname) - -def split_sections(s): - """Split a string or iterable thereof into (section,content) pairs - - Each ``section`` is a stripped version of the section header ("[section]") - and each ``content`` is a list of stripped lines excluding blank lines and - comment-only lines. If there are any such lines before the first section - header, they're returned in a first ``section`` of ``None``. - """ - section = None - content = [] - for line in yield_lines(s): - if line.startswith("["): - if line.endswith("]"): - if section or content: - yield section, content - section = line[1:-1].strip() - content = [] - else: - raise ValueError("Invalid section heading", line) - else: - content.append(line) - - # wrap up last segment - yield section, content - -def _mkstemp(*args,**kw): - from tempfile import mkstemp - old_open = os.open - try: - os.open = os_open # temporarily bypass sandboxing - return mkstemp(*args,**kw) - finally: - os.open = old_open # and then put it back - - -# Set up global resource manager (deliberately not state-saved) -_manager = ResourceManager() -def _initialize(g): - for name in dir(_manager): - if not name.startswith('_'): - g[name] = getattr(_manager, name) -_initialize(globals()) - -# Prepare the master working set and make the ``require()`` API available -working_set = WorkingSet._build_master() -_declare_state('object', working_set=working_set) - -require = working_set.require -iter_entry_points = working_set.iter_entry_points -add_activation_listener = working_set.subscribe -run_script = working_set.run_script -run_main = run_script # backward compatibility -# Activate all distributions already on sys.path, and ensure that -# all distributions added to the working set in the future (e.g. by -# calling ``require()``) will get activated as well. -add_activation_listener(lambda dist: dist.activate()) -working_set.entries=[] -list(map(working_set.add_entry,sys.path)) # match order diff --git a/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/COPYING b/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/COPYING new file mode 100644 index 0000000..b7b5f53 --- /dev/null +++ b/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/py3/lib/python3.6/site-packages/six-1.12.0.dist-info/INSTALLER b/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/INSTALLER similarity index 100% rename from py3/lib/python3.6/site-packages/six-1.12.0.dist-info/INSTALLER rename to py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/INSTALLER diff --git a/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/METADATA b/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/METADATA new file mode 100644 index 0000000..993f92b --- /dev/null +++ b/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/METADATA @@ -0,0 +1,202 @@ +Metadata-Version: 2.1 +Name: pylint +Version: 2.4.4 +Summary: python code static checker +Home-page: https://github.com/PyCQA/pylint +Author: Python Code Quality Authority +Author-email: code-quality@python.org +License: GPL +Platform: UNKNOWN +Classifier: Development Status :: 6 - Mature +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: GNU General Public License (GPL) +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Debuggers +Classifier: Topic :: Software Development :: Quality Assurance +Classifier: Topic :: Software Development :: Testing +Requires-Python: >=3.5.* +Requires-Dist: astroid (<2.4,>=2.3.0) +Requires-Dist: isort (<5,>=4.2.5) +Requires-Dist: mccabe (<0.7,>=0.6) +Requires-Dist: colorama ; sys_platform=="win32" + + +README for Pylint - http://pylint.pycqa.org/ +============================================ + +.. image:: https://travis-ci.org/PyCQA/pylint.svg?branch=master + :target: https://travis-ci.org/PyCQA/pylint + +.. image:: https://ci.appveyor.com/api/projects/status/rbvwhakyj1y09atb/branch/master?svg=true + :alt: AppVeyor Build Status + :target: https://ci.appveyor.com/project/PCManticore/pylint + +.. image:: https://coveralls.io/repos/github/PyCQA/pylint/badge.svg?branch=master + :target: https://coveralls.io/github/PyCQA/pylint?branch=master + + +.. image:: https://img.shields.io/pypi/v/pylint.svg + :alt: Pypi Package version + :target: https://pypi.python.org/pypi/pylint + +.. image:: https://readthedocs.org/projects/pylint/badge/?version=latest + :target: http://pylint.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/ambv/black + +.. |tideliftlogo| image:: doc/media/Tidelift_Logos_RGB_Tidelift_Shorthand_On-White_small.png + :width: 75 + :height: 60 + :alt: Tidelift + +.. list-table:: + :widths: 10 100 + + * - |tideliftlogo| + - Professional support for pylint is available as part of the `Tidelift + Subscription`_. Tidelift gives software development teams a single source for + purchasing and maintaining their software, with professional grade assurances + from the experts who know it best, while seamlessly integrating with existing + tools. + +.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-pylint?utm_source=pypi-pylint&utm_medium=referral&utm_campaign=readme + + +====== +Pylint +====== + +**It's not just a linter that annoys you!** + +Pylint is a Python static code analysis tool which looks for programming errors, +helps enforcing a coding standard, sniffs for code smells and offers simple refactoring +suggestions. + +It's highly configurable, having special pragmas to control its errors and warnings +from within your code, as well as from an extensive configuration file. +It is also possible to write your own plugins for adding your own checks or for +extending pylint in one way or another. + +It's a free software distributed under the GNU General Public Licence unless +otherwise specified. + +Development is hosted on GitHub: https://github.com/PyCQA/pylint/ + +You can use the code-quality@python.org mailing list to discuss about +Pylint. Subscribe at https://mail.python.org/mailman/listinfo/code-quality/ +or read the archives at https://mail.python.org/pipermail/code-quality/ + +Pull requests are amazing and most welcome. + +Install +------- + +Pylint can be simply installed by running:: + + pip install pylint + +If you are using Python 3.6+, upgrade to get full support for your version:: + + pip install pylint --upgrade + +If you want to install from a source distribution, extract the tarball and run +the following command :: + + python setup.py install + + +Do make sure to do the same for astroid, which is used internally by pylint. + +For debian and rpm packages, use your usual tools according to your Linux distribution. + +More information about installation and available distribution format +can be found here_. + +Documentation +------------- + +The documentation lives at http://pylint.pycqa.org/. + +Pylint is shipped with following additional commands: + +* pyreverse: an UML diagram generator +* symilar: an independent similarities checker +* epylint: Emacs and Flymake compatible Pylint + + +Testing +------- + +We use tox_ for running the test suite. You should be able to install it with:: + + pip install tox pytest + + +To run the test suite for a particular Python version, you can do:: + + tox -e py37 + + +To run individual tests with ``tox``, you can do:: + + tox -e py37 -- -k name_of_the_test + + +We use pytest_ for testing ``pylint``, which you can use without using ``tox`` for a faster development cycle. + +If you want to run tests on a specific portion of the code with pytest_, (pytest-cov_) and your local python version:: + + # ( pip install pytest-cov ) + # Everything: + python3 -m pytest tests/ + # Everything in tests/message with coverage for the relevant code: + python3 -m pytest tests/message/ --cov=pylint.message + coverage html + # Only the functional test "missing_kwoa_py3": + python3 -m pytest "tests/test_functional.py::test_functional[missing_kwoa_py3]" + + +Do not forget to clone astroid_ and install the last version:: + + + git clone https://github.com/PyCQA/astroid.git + + # From source + python3 astroid/setup.py build sdist + pip3 install astroid/dist/astroid*.tar.gz + + # Using an editable installation + cd astroid + python3 -m pip install -e . + + +For more detailed information, check the documentation. + +.. _here: http://pylint.pycqa.org/en/latest/user_guide/installation.html +.. _tox: https://tox.readthedocs.io/en/latest/ +.. _pytest: https://docs.pytest.org/en/latest/ +.. _pytest-cov: https://pypi.org/project/pytest-cov/ +.. _astroid: https://github.com/PyCQA/astroid + +License +------- + +pylint is, with a few exceptions listed below, `GPLv2 `_. + +The icon files are licensed under the `CC BY-SA 4.0 `_ license: + +- `doc/logo.png `_ +- `doc/logo.svg `_ + + diff --git a/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/RECORD b/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/RECORD new file mode 100644 index 0000000..06062e7 --- /dev/null +++ b/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/RECORD @@ -0,0 +1,161 @@ +pylint/__init__.py,sha256=4q6rdl1balJqnrIL-PvmRQjhUVZudPskFR_FCmyXCNI,1075 +pylint/__main__.py,sha256=8vKyCk6C5CcmdnhB7enBUDvHlzfPw3kCOg1NDMYT2f8,206 +pylint/__pkginfo__.py,sha256=DZsRD_0SjytZvXFo8vddIUj4IHkHu2u9wkslchWzPsY,3416 +pylint/config.py,sha256=2KHwQ9_Dzo8vYx9AecJF8qR7kZt1fq-Euw_777-G_sk,32626 +pylint/constants.py,sha256=rrW4Rztp75h0RIvy6jRc-zdDIWd8_M2d7OyoLmEz6u4,1185 +pylint/epylint.py,sha256=hSBM9-wetxUHvjIqvTyooImc8WV02RdV9vpt4zj2ZrM,6972 +pylint/exceptions.py,sha256=UxbRwVONB4q1Q8UX8-Ywc5u_APVXcHD1Lxi_b4JSLx0,1040 +pylint/graph.py,sha256=rvwe1_uYAX4f2BKTBdVxt4dQoOCUbEPg6YMG7AnTA6c,6545 +pylint/interfaces.py,sha256=_DndrjiOJTix3PR4tfJAfMZFPZ69IOBsbZMBzs-yX4k,3176 +pylint/lint.py,sha256=UPSGMHFDaO-Qim7HuyEqFNzv4-HNVYvR1FY3JLInQQY,70721 +pylint/testutils.py,sha256=BL2lyuXIrSHEO-ScTEIdmPRvRqGiVmUMClInsA17kpo,9657 +pylint/checkers/__init__.py,sha256=awT2wQ7SPNGZteIaz1tOX59KbiY2UFy5r-NPU5c7N9w,1993 +pylint/checkers/async.py,sha256=y9-K0c8cNsy6YMKu_88wPeu61uYRaheInKJIGHMLHUw,3451 +pylint/checkers/base.py,sha256=rQsQSof2wx7wD5-HpygwUY74QXA26qcX2zLOANQxwVw,89595 +pylint/checkers/base_checker.py,sha256=ewLRP3fZ_tjzFzEmfugLfTeIU0TvZtjvF8m5Q3lABrY,7460 +pylint/checkers/classes.py,sha256=cvn-fYFdAURANVTE963Z3T3MKC_vE2lXatMyzRr6y08,69645 +pylint/checkers/design_analysis.py,sha256=vxEyEwUj_ends_cPB6e9Tc6Tv3HpYErskaCEby4_OI0,16621 +pylint/checkers/exceptions.py,sha256=MOO_5W854m0INx8usht1R5MvkpkbkZ2Khz1xZTu9uzg,20898 +pylint/checkers/format.py,sha256=Mm9tE37dkFH_1fuqccoe2x5vVQ9SOg8sUmLE3e2yRew,48349 +pylint/checkers/imports.py,sha256=kSfacz6r859NyafODJR6fVkffEHX8PmjrFdocETtJac,37704 +pylint/checkers/logging.py,sha256=mrl6jhnuBxRYHNZO-KkZbZP9UHxfEthRYus2YPBzEyo,14596 +pylint/checkers/misc.py,sha256=vGQmutXZcpz5hOx8SDcXtAzo7B_4I5wvjRgZhDli6vM,6033 +pylint/checkers/newstyle.py,sha256=zdip8yMkBW4E7LdQP6-p4Y6c62i7k_6KN49x39hJsGA,4655 +pylint/checkers/python3.py,sha256=gFjjlIxNnF12R4gQgWA4c0ltdtBX9yYuB4t1wrm7-Yo,51909 +pylint/checkers/raw_metrics.py,sha256=NeQi3tFoEMovJaEyV1eChxfN42IceADMKDSjj7UZP0M,3833 +pylint/checkers/refactoring.py,sha256=dM0Mtbp09U_lwNdohT877Boa7gt7DtMP3MHuSnuKtaA,60684 +pylint/checkers/similar.py,sha256=ED6DDyTVIZCGJ44ttoaAEInC0xoH4kNchclUSdHw8ro,15011 +pylint/checkers/spelling.py,sha256=ljuWf-rfYsZikKrg_ysVFax1n2hwhNVY5j6dFUEOZCw,13561 +pylint/checkers/stdlib.py,sha256=ksyf2XBkrct6DjS_sSKNW4-83klY29kTZPtwSgxH_eQ,17226 +pylint/checkers/strings.py,sha256=lKn_5Z4ImMNvHMVZRlJSEV11rsi8oucGKR55ascOchc,31064 +pylint/checkers/typecheck.py,sha256=NDNbCmQhOVNW1Vy13a3GIG2B9bGVtUfh86ms-lGHEUw,67752 +pylint/checkers/utils.py,sha256=D5i2uNXaWi4xWb4_B4ti91Hcc2bTokQ0mJ-rfuh6510,42482 +pylint/checkers/variables.py,sha256=dO7mZ9fpUBpIYZD8I6rv4NT2kYrBQhkEbCYmxo9s59w,76008 +pylint/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/extensions/_check_docs_utils.py,sha256=4ma2xqZKDqwB8jJskxUwdQkeG-ebO4P124qrw32E7XY,22777 +pylint/extensions/bad_builtin.py,sha256=6Via-KVRtuDry55wEhS5va4xeavB86IorvbWe5u7uG8,2358 +pylint/extensions/broad_try_clause.py,sha256=YD2E10bCOwzTzAdPMj45t_CI8BfFhWz-nUevvAjqubc,1799 +pylint/extensions/check_docs.py,sha256=PUXI8A1742UTxcoBAQ-dE88e_lFXlUYxfmkIS1z5eq8,784 +pylint/extensions/check_elif.py,sha256=qm_W2MJ5RBR2lt3K-E8JfXIYJTRuuFdDYeslO2UsG5s,2494 +pylint/extensions/comparetozero.py,sha256=_cKM2ulCv7Ig12gjQEANKOUvR0J4kp0TtaVqe16tEkE,2357 +pylint/extensions/docparams.py,sha256=uc2OfCYmGgAJxtBupEeiGPyjhlBCqRvEvGgik7teNB0,20161 +pylint/extensions/docstyle.py,sha256=ZlzRRXn0_b0a_AIHr-gTXtyIOm7pAVjVC_RvTLxBMSg,2904 +pylint/extensions/emptystring.py,sha256=BlYgMnaL0-N6We1cqQStYpQcyoYfoB9zbF6gM-UxPko,2456 +pylint/extensions/mccabe.py,sha256=1LYOmLdtiF_dyf1CKdixVBHeqWjfGHR6F1clKQiEmJM,6123 +pylint/extensions/overlapping_exceptions.py,sha256=xI8wsuncRzEW1Lf4xOhOLqjeWMF1qbYo91m2IQLBUi0,3291 +pylint/extensions/redefined_variable_type.py,sha256=RhDFCUUzkh8maonooUYDiq3GILUWjgkMtd7CLcy3o_o,4207 +pylint/message/__init__.py,sha256=mF-jL0vStH9kGJolQ11BHWpUfWx4hy1MeuaHOWTML2c,2654 +pylint/message/message.py,sha256=E-2yX4WtE0543P_z72ds3aH-mdg52pQKvdh0rk2k_JE,1324 +pylint/message/message_definition.py,sha256=NihHjlvXHhws0TbpRK-qE7YFvOdRhHYrHCdRh87tGc8,3008 +pylint/message/message_definition_store.py,sha256=OIXHLV153vuEpoup8QqUxy7Z0J4g63afjJXNuwvoZhg,3560 +pylint/message/message_handler_mix_in.py,sha256=FGyDLUBLHfoyryMHlBkbo3qbzpabtVgwcfsspLmlKDA,15264 +pylint/message/message_id_store.py,sha256=hn5KuWPh1FbzxuAkVxOsz3KYTWUPemVW7-DhlRbPEQo,5316 +pylint/pyreverse/__init__.py,sha256=runafCn0veg0di-i8TztMGlKEJO3Qg01MICGqDgZ0c0,202 +pylint/pyreverse/diadefslib.py,sha256=K29JXIglMxnU4qunTajs6Ehh1_lzeO3-pwqlFBkuWz4,8628 +pylint/pyreverse/diagrams.py,sha256=fQ36OWK0XnGtCSAdOxithCkoTt-ZuYwDmf2k7apTchM,8962 +pylint/pyreverse/inspector.py,sha256=FF8GZh_sexjveki7CsJUVaQZV-9zlAj20fUfVcMaVkk,11996 +pylint/pyreverse/main.py,sha256=-uIdvJxlEeh2gte5ioGTYQC2gMUbcnAesAUAH9Cx21g,6329 +pylint/pyreverse/utils.py,sha256=4GmoTztZ19Fy7Qr7q38OGaAib-QkdQQUbfc4kVFDFRk,6183 +pylint/pyreverse/vcgutils.py,sha256=-aMHC9LhVsE4kmHrSyC_qowfxpKKLnBHj3Q84vFOwlc,6408 +pylint/pyreverse/writer.py,sha256=ouwvhkec8FAg1FzhtEnnrEXSH1e7khXdM6J4F8O6YqY,7803 +pylint/reporters/__init__.py,sha256=Wy75bdMIrvt6vpXnAmR86uyofWlSpk-bDrqMv3dk0ls,1530 +pylint/reporters/base_reporter.py,sha256=xzI1J2Be-i43Dbik7ei_4SmzXmmw9vTQqMZZWI4BVsg,2056 +pylint/reporters/collecting_reporter.py,sha256=swn9TgqlYF9pIM_ZY5gdE_oh4l1I5MTfqt6ao_l4_SQ,503 +pylint/reporters/json_reporter.py,sha256=-rumpEwEWgoeKf48a0Y5M8mWAaM1uU3uMbR2dYCT56A,1775 +pylint/reporters/reports_handler_mix_in.py,sha256=dtPqqs1EmzQgi8dlZ5nrLYrOc4PqgHwWa_3GWkqcfPM,2729 +pylint/reporters/text.py,sha256=3lpsa3jTI-EaUmGHk3cFHRHmiW-GdpUvRBdVOywNsiw,7930 +pylint/reporters/ureports/__init__.py,sha256=L-azj4EDF4DEtR9bIU8C5F2y_fgtxCySP_UzKK-4G1M,3156 +pylint/reporters/ureports/nodes.py,sha256=RJj-HfDAyGg7TbplWMOODsqM96q_pc0PfCx2v4PZ3no,5196 +pylint/reporters/ureports/text_writer.py,sha256=f5UWHO343n417BgVX8HrrMJaQTPrFdyHP3QmWQz_HRY,3232 +pylint/utils/__init__.py,sha256=Recd7HK7QOwdxExYLWWf0mQxLPQVMC3Ih0AgH6P17wE,2735 +pylint/utils/ast_walker.py,sha256=Hx9TIbHaWjlIVdQSuotLVgrf-noGGc2-9XsGJABLLBs,2932 +pylint/utils/file_state.py,sha256=lCuwlKTZefCDWjSu6Hyqt2TjKaLpm0FWSFfSPZMSIag,5987 +pylint/utils/utils.py,sha256=_lyD_iGf3bLW-AWaaEDaMQZPWA3zZ1mUfhCUCFA_rq4,12392 +pylint-2.4.4.data/scripts/epylint,sha256=ebDphNeMoKus049k5MQbxN1JYsHUsOXZxws0Do6gCG0,51 +pylint-2.4.4.data/scripts/pylint,sha256=wXf1V2_-AB_S1uuYztSS90GiTeCkJ4eBOGEQ7CO2Nmc,53 +pylint-2.4.4.data/scripts/pyreverse,sha256=4UQf7-hfOAx6Ux8d5g0d2KIjpUPRMwFhBdsKsu0gWg0,59 +pylint-2.4.4.data/scripts/symilar,sha256=iz6DGtePyfs0haoFobDfsRsMjaFOizh7E3vsevB2Ipw,55 +pylint-2.4.4.dist-info/COPYING,sha256=w4runjyMTV1ZT_VIob4FRTAjAW1ihpMfZRLbIV7B_UI,17989 +pylint-2.4.4.dist-info/METADATA,sha256=RNy4cq2r2CQ1GQdc8lt_Ds-gFkFKSR2GbllMSCa4B1c,6549 +pylint-2.4.4.dist-info/WHEEL,sha256=p46_5Uhzqz6AzeSosiOnxK-zmFja1i22CrQCjmYe8ec,92 +pylint-2.4.4.dist-info/entry_points.txt,sha256=WUTwHM2ZcExO-VSvss18AMFsQL-XcWg6O3_MwobWfmw,137 +pylint-2.4.4.dist-info/top_level.txt,sha256=j6Z9i__pIuaiCka6Ul9YIy6yI5aw5QbCtldLvZlMksE,7 +pylint-2.4.4.dist-info/RECORD,, +../../../bin/epylint,sha256=_FJoSRCXOiKzK7GaMWVHeWRTwliOmOOysdU9bVt6FfI,246 +../../../bin/pylint,sha256=mHs9pAGF9L3NlRSTQlOvACRrYc_WG3MhCD2Qfjm0lq8,244 +../../../bin/pyreverse,sha256=noqHm6b4S-uGFujku0i95kpFk8R4udTGDgk4P_HDsFg,250 +../../../bin/symilar,sha256=8OnyJ59AQRgP2pN-hx25nyFGJeeqNoKiRP9tixtDWl4,246 +pylint-2.4.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pylint/message/__pycache__/message_handler_mix_in.cpython-36.pyc,, +pylint/message/__pycache__/__init__.cpython-36.pyc,, +pylint/message/__pycache__/message.cpython-36.pyc,, +pylint/message/__pycache__/message_definition.cpython-36.pyc,, +pylint/message/__pycache__/message_id_store.cpython-36.pyc,, +pylint/message/__pycache__/message_definition_store.cpython-36.pyc,, +pylint/reporters/ureports/__pycache__/text_writer.cpython-36.pyc,, +pylint/reporters/ureports/__pycache__/nodes.cpython-36.pyc,, +pylint/reporters/ureports/__pycache__/__init__.cpython-36.pyc,, +pylint/reporters/__pycache__/reports_handler_mix_in.cpython-36.pyc,, +pylint/reporters/__pycache__/__init__.cpython-36.pyc,, +pylint/reporters/__pycache__/text.cpython-36.pyc,, +pylint/reporters/__pycache__/collecting_reporter.cpython-36.pyc,, +pylint/reporters/__pycache__/base_reporter.cpython-36.pyc,, +pylint/reporters/__pycache__/json_reporter.cpython-36.pyc,, +pylint/pyreverse/__pycache__/diagrams.cpython-36.pyc,, +pylint/pyreverse/__pycache__/vcgutils.cpython-36.pyc,, +pylint/pyreverse/__pycache__/__init__.cpython-36.pyc,, +pylint/pyreverse/__pycache__/writer.cpython-36.pyc,, +pylint/pyreverse/__pycache__/utils.cpython-36.pyc,, +pylint/pyreverse/__pycache__/diadefslib.cpython-36.pyc,, +pylint/pyreverse/__pycache__/inspector.cpython-36.pyc,, +pylint/pyreverse/__pycache__/main.cpython-36.pyc,, +pylint/checkers/__pycache__/typecheck.cpython-36.pyc,, +pylint/checkers/__pycache__/format.cpython-36.pyc,, +pylint/checkers/__pycache__/variables.cpython-36.pyc,, +pylint/checkers/__pycache__/async.cpython-36.pyc,, +pylint/checkers/__pycache__/raw_metrics.cpython-36.pyc,, +pylint/checkers/__pycache__/logging.cpython-36.pyc,, +pylint/checkers/__pycache__/base.cpython-36.pyc,, +pylint/checkers/__pycache__/refactoring.cpython-36.pyc,, +pylint/checkers/__pycache__/python3.cpython-36.pyc,, +pylint/checkers/__pycache__/similar.cpython-36.pyc,, +pylint/checkers/__pycache__/classes.cpython-36.pyc,, +pylint/checkers/__pycache__/newstyle.cpython-36.pyc,, +pylint/checkers/__pycache__/__init__.cpython-36.pyc,, +pylint/checkers/__pycache__/strings.cpython-36.pyc,, +pylint/checkers/__pycache__/spelling.cpython-36.pyc,, +pylint/checkers/__pycache__/stdlib.cpython-36.pyc,, +pylint/checkers/__pycache__/utils.cpython-36.pyc,, +pylint/checkers/__pycache__/exceptions.cpython-36.pyc,, +pylint/checkers/__pycache__/base_checker.cpython-36.pyc,, +pylint/checkers/__pycache__/design_analysis.cpython-36.pyc,, +pylint/checkers/__pycache__/imports.cpython-36.pyc,, +pylint/checkers/__pycache__/misc.cpython-36.pyc,, +pylint/__pycache__/__pkginfo__.cpython-36.pyc,, +pylint/__pycache__/testutils.cpython-36.pyc,, +pylint/__pycache__/config.cpython-36.pyc,, +pylint/__pycache__/graph.cpython-36.pyc,, +pylint/__pycache__/__main__.cpython-36.pyc,, +pylint/__pycache__/lint.cpython-36.pyc,, +pylint/__pycache__/__init__.cpython-36.pyc,, +pylint/__pycache__/interfaces.cpython-36.pyc,, +pylint/__pycache__/exceptions.cpython-36.pyc,, +pylint/__pycache__/constants.cpython-36.pyc,, +pylint/__pycache__/epylint.cpython-36.pyc,, +pylint/extensions/__pycache__/redefined_variable_type.cpython-36.pyc,, +pylint/extensions/__pycache__/docstyle.cpython-36.pyc,, +pylint/extensions/__pycache__/check_elif.cpython-36.pyc,, +pylint/extensions/__pycache__/emptystring.cpython-36.pyc,, +pylint/extensions/__pycache__/__init__.cpython-36.pyc,, +pylint/extensions/__pycache__/bad_builtin.cpython-36.pyc,, +pylint/extensions/__pycache__/broad_try_clause.cpython-36.pyc,, +pylint/extensions/__pycache__/comparetozero.cpython-36.pyc,, +pylint/extensions/__pycache__/check_docs.cpython-36.pyc,, +pylint/extensions/__pycache__/mccabe.cpython-36.pyc,, +pylint/extensions/__pycache__/docparams.cpython-36.pyc,, +pylint/extensions/__pycache__/_check_docs_utils.cpython-36.pyc,, +pylint/extensions/__pycache__/overlapping_exceptions.cpython-36.pyc,, +pylint/utils/__pycache__/file_state.cpython-36.pyc,, +pylint/utils/__pycache__/__init__.cpython-36.pyc,, +pylint/utils/__pycache__/utils.cpython-36.pyc,, +pylint/utils/__pycache__/ast_walker.cpython-36.pyc,, diff --git a/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/WHEEL b/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/WHEEL new file mode 100644 index 0000000..3b5c403 --- /dev/null +++ b/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.33.6) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/entry_points.txt b/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/entry_points.txt new file mode 100644 index 0000000..063b5e4 --- /dev/null +++ b/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/entry_points.txt @@ -0,0 +1,6 @@ +[console_scripts] +epylint = pylint:run_epylint +pylint = pylint:run_pylint +pyreverse = pylint:run_pyreverse +symilar = pylint:run_symilar + diff --git a/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/top_level.txt b/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/top_level.txt new file mode 100644 index 0000000..7fb0ea1 --- /dev/null +++ b/py3/lib/python3.6/site-packages/pylint-2.4.4.dist-info/top_level.txt @@ -0,0 +1 @@ +pylint diff --git a/py3/lib/python3.6/site-packages/pylint/__init__.py b/py3/lib/python3.6/site-packages/pylint/__init__.py new file mode 100644 index 0000000..8980938 --- /dev/null +++ b/py3/lib/python3.6/site-packages/pylint/__init__.py @@ -0,0 +1,43 @@ +# Copyright (c) 2008, 2012 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014, 2016-2017 Claudiu Popa +# Copyright (c) 2014 Arun Persaud +# Copyright (c) 2015 Ionel Cristian Maries +# Copyright (c) 2018 Nick Drozd + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +import sys + +from pylint.__pkginfo__ import version as __version__ +from pylint.checkers.similar import Run as SimilarRun +from pylint.epylint import Run as EpylintRun +from pylint.lint import Run as PylintRun +from pylint.pyreverse.main import Run as PyreverseRun + + +def run_pylint(): + """run pylint""" + + try: + PylintRun(sys.argv[1:]) + except KeyboardInterrupt: + sys.exit(1) + + +def run_epylint(): + """run pylint""" + + EpylintRun() + + +def run_pyreverse(): + """run pyreverse""" + + PyreverseRun(sys.argv[1:]) + + +def run_symilar(): + """run symilar""" + + SimilarRun(sys.argv[1:]) diff --git a/py3/lib/python3.6/site-packages/pylint/__main__.py b/py3/lib/python3.6/site-packages/pylint/__main__.py new file mode 100644 index 0000000..e12309b --- /dev/null +++ b/py3/lib/python3.6/site-packages/pylint/__main__.py @@ -0,0 +1,7 @@ +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +#!/usr/bin/env python +import pylint + +pylint.run_pylint() diff --git a/py3/lib/python3.6/site-packages/pylint/__pkginfo__.py b/py3/lib/python3.6/site-packages/pylint/__pkginfo__.py new file mode 100644 index 0000000..68702f4 --- /dev/null +++ b/py3/lib/python3.6/site-packages/pylint/__pkginfo__.py @@ -0,0 +1,85 @@ +# Copyright (c) 2006-2015 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2010 Julien Jehannet +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Brett Cannon +# Copyright (c) 2014 Ricardo Gemignani +# Copyright (c) 2014 Arun Persaud +# Copyright (c) 2015 Ionel Cristian Maries +# Copyright (c) 2016 Moises Lopez +# Copyright (c) 2016 Florian Bruhin +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2017-2018 Hugo +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Ashley Whetter + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +# pylint: disable=redefined-builtin,invalid-name +"""pylint packaging information""" + +from os.path import join + +# For an official release, use dev_version = None +numversion = (2, 4, 4) +dev_version = None + +version = ".".join(str(num) for num in numversion) +if dev_version is not None: + version += "-dev" + str(dev_version) + +install_requires = ["astroid>=2.3.0,<2.4", "isort>=4.2.5,<5", "mccabe>=0.6,<0.7"] + +dependency_links = [] # type: ignore + +extras_require = {} +extras_require[':sys_platform=="win32"'] = ["colorama"] + +license = "GPL" +description = "python code static checker" +web = "https://github.com/PyCQA/pylint" +mailinglist = "mailto:code-quality@python.org" +author = "Python Code Quality Authority" +author_email = "code-quality@python.org" + +classifiers = [ + "Development Status :: 6 - Mature", + "Environment :: Console", + "Intended Audience :: Developers", + "License :: OSI Approved :: GNU General Public License (GPL)", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Software Development :: Debuggers", + "Topic :: Software Development :: Quality Assurance", + "Topic :: Software Development :: Testing", +] + + +long_desc = """\ + Pylint is a Python source code analyzer which looks for programming + errors, helps enforcing a coding standard and sniffs for some code + smells (as defined in Martin Fowler's Refactoring book) + . + Pylint can be seen as another PyChecker since nearly all tests you + can do with PyChecker can also be done with Pylint. However, Pylint + offers some more features, like checking length of lines of code, + checking if variable names are well-formed according to your coding + standard, or checking if declared interfaces are truly implemented, + and much more. + . + Additionally, it is possible to write plugins to add your own checks. + . + Pylint is shipped with "pyreverse" (UML diagram generator) + and "symilar" (an independent similarities checker).""" + +scripts = [ + join("bin", filename) for filename in ("pylint", "symilar", "epylint", "pyreverse") +] diff --git a/py3/lib/python3.6/site-packages/pylint/checkers/__init__.py b/py3/lib/python3.6/site-packages/pylint/checkers/__init__.py new file mode 100644 index 0000000..9c6306f --- /dev/null +++ b/py3/lib/python3.6/site-packages/pylint/checkers/__init__.py @@ -0,0 +1,64 @@ +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2013 buck@yelp.com +# Copyright (c) 2014-2017 Claudiu Popa +# Copyright (c) 2014 Brett Cannon +# Copyright (c) 2014 Arun Persaud +# Copyright (c) 2015 Ionel Cristian Maries +# Copyright (c) 2016 Moises Lopez +# Copyright (c) 2017-2018 Bryce Guinta + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""utilities methods and classes for checkers + +Base id of standard checkers (used in msg and report ids): +01: base +02: classes +03: format +04: import +05: misc +06: variables +07: exceptions +08: similar +09: design_analysis +10: newstyle +11: typecheck +12: logging +13: string_format +14: string_constant +15: stdlib +16: python3 +17: refactoring +18-50: not yet used: reserved for future internal checkers. +51-99: perhaps used: reserved for external checkers + +The raw_metrics checker has no number associated since it doesn't emit any +messages nor reports. XXX not true, emit a 07 report ! + +""" + +from pylint.checkers.base_checker import BaseChecker, BaseTokenChecker +from pylint.utils import register_plugins + + +def table_lines_from_stats(stats, _, columns): + """get values listed in from and , + and return a formated list of values, designed to be given to a + ureport.Table object + """ + lines = [] + for m_type in columns: + new = stats[m_type] + new = "%.3f" % new if isinstance(new, float) else str(new) + lines += (m_type.replace("_", " "), new, "NC", "NC") + return lines + + +def initialize(linter): + """initialize linter with checkers in this package """ + register_plugins(linter, __path__[0]) + + +__all__ = ("BaseChecker", "BaseTokenChecker", "initialize") diff --git a/py3/lib/python3.6/site-packages/pylint/checkers/async.py b/py3/lib/python3.6/site-packages/pylint/checkers/async.py new file mode 100644 index 0000000..c33071e --- /dev/null +++ b/py3/lib/python3.6/site-packages/pylint/checkers/async.py @@ -0,0 +1,89 @@ +# Copyright (c) 2015-2018 Claudiu Popa +# Copyright (c) 2017 Derek Gustafson + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Checker for anything related to the async protocol (PEP 492).""" + +import sys + +import astroid +from astroid import bases, exceptions + +from pylint import checkers, interfaces, utils +from pylint.checkers import utils as checker_utils +from pylint.checkers.utils import decorated_with + + +class AsyncChecker(checkers.BaseChecker): + __implements__ = interfaces.IAstroidChecker + name = "async" + msgs = { + "E1700": ( + "Yield inside async function", + "yield-inside-async-function", + "Used when an `yield` or `yield from` statement is " + "found inside an async function.", + {"minversion": (3, 5)}, + ), + "E1701": ( + "Async context manager '%s' doesn't implement __aenter__ and __aexit__.", + "not-async-context-manager", + "Used when an async context manager is used with an object " + "that does not implement the async context management protocol.", + {"minversion": (3, 5)}, + ), + } + + def open(self): + self._ignore_mixin_members = utils.get_global_option( + self, "ignore-mixin-members" + ) + self._async_generators = ["contextlib.asynccontextmanager"] + + @checker_utils.check_messages("yield-inside-async-function") + def visit_asyncfunctiondef(self, node): + for child in node.nodes_of_class(astroid.Yield): + if child.scope() is node and ( + sys.version_info[:2] == (3, 5) or isinstance(child, astroid.YieldFrom) + ): + self.add_message("yield-inside-async-function", node=child) + + @checker_utils.check_messages("not-async-context-manager") + def visit_asyncwith(self, node): + for ctx_mgr, _ in node.items: + inferred = checker_utils.safe_infer(ctx_mgr) + if inferred is None or inferred is astroid.Uninferable: + continue + + if isinstance(inferred, bases.AsyncGenerator): + # Check if we are dealing with a function decorated + # with contextlib.asynccontextmanager. + if decorated_with(inferred.parent, self._async_generators): + continue + else: + try: + inferred.getattr("__aenter__") + inferred.getattr("__aexit__") + except exceptions.NotFoundError: + if isinstance(inferred, astroid.Instance): + # If we do not know the bases of this class, + # just skip it. + if not checker_utils.has_known_bases(inferred): + continue + # Just ignore mixin classes. + if self._ignore_mixin_members: + if inferred.name[-5:].lower() == "mixin": + continue + else: + continue + + self.add_message( + "not-async-context-manager", node=node, args=(inferred.name,) + ) + + +def register(linter): + """required method to auto register this checker""" + linter.register_checker(AsyncChecker(linter)) diff --git a/py3/lib/python3.6/site-packages/pylint/checkers/base.py b/py3/lib/python3.6/site-packages/pylint/checkers/base.py new file mode 100644 index 0000000..c94676e --- /dev/null +++ b/py3/lib/python3.6/site-packages/pylint/checkers/base.py @@ -0,0 +1,2333 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2016 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2010 Daniel Harding +# Copyright (c) 2012-2014 Google, Inc. +# Copyright (c) 2013-2018 Claudiu Popa +# Copyright (c) 2014 Brett Cannon +# Copyright (c) 2014 Arun Persaud +# Copyright (c) 2015 Nick Bastin +# Copyright (c) 2015 Michael Kefeder +# Copyright (c) 2015 Dmitry Pribysh +# Copyright (c) 2015 Stephane Wirtel +# Copyright (c) 2015 Cosmin Poieana +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2015 Radu Ciorba +# Copyright (c) 2015 Ionel Cristian Maries +# Copyright (c) 2016, 2018 Jakub Wilk +# Copyright (c) 2016-2017 Łukasz Rogalski +# Copyright (c) 2016 Glenn Matthews +# Copyright (c) 2016 Elias Dorneles +# Copyright (c) 2016 Ashley Whetter +# Copyright (c) 2016 Yannack +# Copyright (c) 2016 Alex Jurkiewicz +# Copyright (c) 2017 Jacques Kvam +# Copyright (c) 2017 ttenhoeve-aa +# Copyright (c) 2017 hippo91 +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Steven M. Vascellaro +# Copyright (c) 2018 Mike Frysinger +# Copyright (c) 2018 ssolanki +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Chris Lamb +# Copyright (c) 2018 glmdgrielson <32415403+glmdgrielson@users.noreply.github.com> +# Copyright (c) 2018 Ville Skyttä + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""basic checker for Python code""" + +import builtins +import collections +import itertools +import re +import sys +from typing import Pattern + +import astroid +import astroid.bases +import astroid.scoped_nodes +from astroid.arguments import CallSite + +import pylint.utils as lint_utils +from pylint import checkers, exceptions, interfaces +from pylint.checkers import utils +from pylint.checkers.utils import is_property_setter_or_deleter +from pylint.reporters.ureports import nodes as reporter_nodes + + +class NamingStyle: + # It may seem counterintuitive that single naming style + # has multiple "accepted" forms of regular expressions, + # but we need to special-case stuff like dunder names + # in method names. + CLASS_NAME_RGX = None # type: Pattern[str] + MOD_NAME_RGX = None # type: Pattern[str] + CONST_NAME_RGX = None # type: Pattern[str] + COMP_VAR_RGX = None # type: Pattern[str] + DEFAULT_NAME_RGX = None # type: Pattern[str] + CLASS_ATTRIBUTE_RGX = None # type: Pattern[str] + + @classmethod + def get_regex(cls, name_type): + return { + "module": cls.MOD_NAME_RGX, + "const": cls.CONST_NAME_RGX, + "class": cls.CLASS_NAME_RGX, + "function": cls.DEFAULT_NAME_RGX, + "method": cls.DEFAULT_NAME_RGX, + "attr": cls.DEFAULT_NAME_RGX, + "argument": cls.DEFAULT_NAME_RGX, + "variable": cls.DEFAULT_NAME_RGX, + "class_attribute": cls.CLASS_ATTRIBUTE_RGX, + "inlinevar": cls.COMP_VAR_RGX, + }[name_type] + + +class SnakeCaseStyle(NamingStyle): + """Regex rules for snake_case naming style.""" + + CLASS_NAME_RGX = re.compile("[a-z_][a-z0-9_]+$") + MOD_NAME_RGX = re.compile("([a-z_][a-z0-9_]*)$") + CONST_NAME_RGX = re.compile("(([a-z_][a-z0-9_]*)|(__.*__))$") + COMP_VAR_RGX = re.compile("[a-z_][a-z0-9_]*$") + DEFAULT_NAME_RGX = re.compile( + "(([a-z_][a-z0-9_]{2,})|(_[a-z0-9_]*)|(__[a-z][a-z0-9_]+__))$" + ) + CLASS_ATTRIBUTE_RGX = re.compile(r"(([a-z_][a-z0-9_]{2,}|(__.*__)))$") + + +class CamelCaseStyle(NamingStyle): + """Regex rules for camelCase naming style.""" + + CLASS_NAME_RGX = re.compile("[a-z_][a-zA-Z0-9]+$") + MOD_NAME_RGX = re.compile("([a-z_][a-zA-Z0-9]*)$") + CONST_NAME_RGX = re.compile("(([a-z_][A-Za-z0-9]*)|(__.*__))$") + COMP_VAR_RGX = re.compile("[a-z_][A-Za-z0-9]*$") + DEFAULT_NAME_RGX = re.compile("(([a-z_][a-zA-Z0-9]{2,})|(__[a-z][a-zA-Z0-9_]+__))$") + CLASS_ATTRIBUTE_RGX = re.compile(r"([a-z_][A-Za-z0-9]{2,}|(__.*__))$") + + +class PascalCaseStyle(NamingStyle): + """Regex rules for PascalCase naming style.""" + + CLASS_NAME_RGX = re.compile("[A-Z_][a-zA-Z0-9]+$") + MOD_NAME_RGX = re.compile("[A-Z_][a-zA-Z0-9]+$") + CONST_NAME_RGX = re.compile("(([A-Z_][A-Za-z0-9]*)|(__.*__))$") + COMP_VAR_RGX = re.compile("[A-Z_][a-zA-Z0-9]+$") + DEFAULT_NAME_RGX = re.compile("[A-Z_][a-zA-Z0-9]{2,}$|(__[a-z][a-zA-Z0-9_]+__)$") + CLASS_ATTRIBUTE_RGX = re.compile("[A-Z_][a-zA-Z0-9]{2,}$") + + +class UpperCaseStyle(NamingStyle): + """Regex rules for UPPER_CASE naming style.""" + + CLASS_NAME_RGX = re.compile("[A-Z_][A-Z0-9_]+$") + MOD_NAME_RGX = re.compile("[A-Z_][A-Z0-9_]+$") + CONST_NAME_RGX = re.compile("(([A-Z_][A-Z0-9_]*)|(__.*__))$") + COMP_VAR_RGX = re.compile("[A-Z_][A-Z0-9_]+$") + DEFAULT_NAME_RGX = re.compile("([A-Z_][A-Z0-9_]{2,})|(__[a-z][a-zA-Z0-9_]+__)$") + CLASS_ATTRIBUTE_RGX = re.compile("[A-Z_][A-Z0-9_]{2,}$") + + +class AnyStyle(NamingStyle): + @classmethod + def get_regex(cls, name_type): + return re.compile(".*") + + +NAMING_STYLES = { + "snake_case": SnakeCaseStyle, + "camelCase": CamelCaseStyle, + "PascalCase": PascalCaseStyle, + "UPPER_CASE": UpperCaseStyle, + "any": AnyStyle, +} + +# do not require a doc string on private/system methods +NO_REQUIRED_DOC_RGX = re.compile("^_") +REVERSED_PROTOCOL_METHOD = "__reversed__" +SEQUENCE_PROTOCOL_METHODS = ("__getitem__", "__len__") +REVERSED_METHODS = (SEQUENCE_PROTOCOL_METHODS, (REVERSED_PROTOCOL_METHOD,)) +TYPECHECK_COMPARISON_OPERATORS = frozenset(("is", "is not", "==", "!=", "in", "not in")) +LITERAL_NODE_TYPES = (astroid.Const, astroid.Dict, astroid.List, astroid.Set) +UNITTEST_CASE = "unittest.case" +BUILTINS = builtins.__name__ +TYPE_QNAME = "%s.type" % BUILTINS +ABC_METACLASSES = {"_py_abc.ABCMeta", "abc.ABCMeta"} # Python 3.7+, + +# Name categories that are always consistent with all naming conventions. +EXEMPT_NAME_CATEGORIES = {"exempt", "ignore"} + +# A mapping from builtin-qname -> symbol, to be used when generating messages +# about dangerous default values as arguments +DEFAULT_ARGUMENT_SYMBOLS = dict( + zip( + [".".join([BUILTINS, x]) for x in ("set", "dict", "list")], + ["set()", "{}", "[]"], + ) +) +REVERSED_COMPS = {"<": ">", "<=": ">=", ">": "<", ">=": "<="} +COMPARISON_OPERATORS = frozenset(("==", "!=", "<", ">", "<=", ">=")) +# List of methods which can be redefined +REDEFINABLE_METHODS = frozenset(("__module__",)) +TYPING_FORWARD_REF_QNAME = "typing.ForwardRef" + + +def _redefines_import(node): + """ Detect that the given node (AssignName) is inside an + exception handler and redefines an import from the tryexcept body. + Returns True if the node redefines an import, False otherwise. + """ + current = node + while current and not isinstance(current.parent, astroid.ExceptHandler): + current = current.parent + if not current or not utils.error_of_type(current.parent, ImportError): + return False + try_block = current.parent.parent + for import_node in try_block.nodes_of_class((astroid.ImportFrom, astroid.Import)): + for name, alias in import_node.names: + if alias: + if alias == node.name: + return True + elif name == node.name: + return True + return False + + +def in_loop(node): + """return True if the node is inside a kind of for loop""" + parent = node.parent + while parent is not None: + if isinstance( + parent, + ( + astroid.For, + astroid.ListComp, + astroid.SetComp, + astroid.DictComp, + astroid.GeneratorExp, + ), + ): + return True + parent = parent.parent + return False + + +def in_nested_list(nested_list, obj): + """return true if the object is an element of or of a nested + list + """ + for elmt in nested_list: + if isinstance(elmt, (list, tuple)): + if in_nested_list(elmt, obj): + return True + elif elmt == obj: + return True + return False + + +def _get_break_loop_node(break_node): + """ + Returns the loop node that holds the break node in arguments. + + Args: + break_node (astroid.Break): the break node of interest. + + Returns: + astroid.For or astroid.While: the loop node holding the break node. + """ + loop_nodes = (astroid.For, astroid.While) + parent = break_node.parent + while not isinstance(parent, loop_nodes) or break_node in getattr( + parent, "orelse", [] + ): + break_node = parent + parent = parent.parent + if parent is None: + break + return parent + + +def _loop_exits_early(loop): + """ + Returns true if a loop may ends up in a break statement. + + Args: + loop (astroid.For, astroid.While): the loop node inspected. + + Returns: + bool: True if the loop may ends up in a break statement, False otherwise. + """ + loop_nodes = (astroid.For, astroid.While) + definition_nodes = (astroid.FunctionDef, astroid.ClassDef) + inner_loop_nodes = [ + _node + for _node in loop.nodes_of_class(loop_nodes, skip_klass=definition_nodes) + if _node != loop + ] + return any( + _node + for _node in loop.nodes_of_class(astroid.Break, skip_klass=definition_nodes) + if _get_break_loop_node(_node) not in inner_loop_nodes + ) + + +def _is_multi_naming_match(match, node_type, confidence): + return ( + match is not None + and match.lastgroup is not None + and match.lastgroup not in EXEMPT_NAME_CATEGORIES + and (node_type != "method" or confidence != interfaces.INFERENCE_FAILURE) + ) + + +BUILTIN_PROPERTY = "builtins.property" + + +def _get_properties(config): + """Returns a tuple of property classes and names. + + Property classes are fully qualified, such as 'abc.abstractproperty' and + property names are the actual names, such as 'abstract_property'. + """ + property_classes = {BUILTIN_PROPERTY} + property_names = set() # Not returning 'property', it has its own check. + if config is not None: + property_classes.update(config.property_classes) + property_names.update( + (prop.rsplit(".", 1)[-1] for prop in config.property_classes) + ) + return property_classes, property_names + + +def _determine_function_name_type(node, config=None): + """Determine the name type whose regex the a function's name should match. + + :param node: A function node. + :type node: astroid.node_classes.NodeNG + :param config: Configuration from which to pull additional property classes. + :type config: :class:`optparse.Values` + + :returns: One of ('function', 'method', 'attr') + :rtype: str + """ + property_classes, property_names = _get_properties(config) + if not node.is_method(): + return "function" + + if is_property_setter_or_deleter(node): + # If the function is decorated using the prop_method.{setter,getter} + # form, treat it like an attribute as well. + return "attr" + + if node.decorators: + decorators = node.decorators.nodes + else: + decorators = [] + for decorator in decorators: + # If the function is a property (decorated with @property + # or @abc.abstractproperty), the name type is 'attr'. + if isinstance(decorator, astroid.Name) or ( + isinstance(decorator, astroid.Attribute) + and decorator.attrname in property_names + ): + inferred = utils.safe_infer(decorator) + if inferred and inferred.qname() in property_classes: + return "attr" + return "method" + + +def _has_abstract_methods(node): + """ + Determine if the given `node` has abstract methods. + + The methods should be made abstract by decorating them + with `abc` decorators. + """ + return len(utils.unimplemented_abstract_methods(node)) > 0 + + +def report_by_type_stats(sect, stats, _): + """make a report of + + * percentage of different types documented + * percentage of different types with a bad name + """ + # percentage of different types documented and/or with a bad name + nice_stats = {} + for node_type in ("module", "class", "method", "function"): + try: + total = stats[node_type] + except KeyError: + raise exceptions.EmptyReportError() + nice_stats[node_type] = {} + if total != 0: + try: + documented = total - stats["undocumented_" + node_type] + percent = (documented * 100.0) / total + nice_stats[node_type]["percent_documented"] = "%.2f" % percent + except KeyError: + nice_stats[node_type]["percent_documented"] = "NC" + try: + percent = (stats["badname_" + node_type] * 100.0) / total + nice_stats[node_type]["percent_badname"] = "%.2f" % percent + except KeyError: + nice_stats[node_type]["percent_badname"] = "NC" + lines = ("type", "number", "old number", "difference", "%documented", "%badname") + for node_type in ("module", "class", "method", "function"): + new = stats[node_type] + lines += ( + node_type, + str(new), + "NC", + "NC", + nice_stats[node_type].get("percent_documented", "0"), + nice_stats[node_type].get("percent_badname", "0"), + ) + sect.append(reporter_nodes.Table(children=lines, cols=6, rheaders=1)) + + +def redefined_by_decorator(node): + """return True if the object is a method redefined via decorator. + + For example: + @property + def x(self): return self._x + @x.setter + def x(self, value): self._x = value + """ + if node.decorators: + for decorator in node.decorators.nodes: + if ( + isinstance(decorator, astroid.Attribute) + and getattr(decorator.expr, "name", None) == node.name + ): + return True + return False + + +class _BasicChecker(checkers.BaseChecker): + __implements__ = interfaces.IAstroidChecker + name = "basic" + + +class BasicErrorChecker(_BasicChecker): + msgs = { + "E0100": ( + "__init__ method is a generator", + "init-is-generator", + "Used when the special class method __init__ is turned into a " + "generator by a yield in its body.", + ), + "E0101": ( + "Explicit return in __init__", + "return-in-init", + "Used when the special class method __init__ has an explicit " + "return value.", + ), + "E0102": ( + "%s already defined line %s", + "function-redefined", + "Used when a function / class / method is redefined.", + ), + "E0103": ( + "%r not properly in loop", + "not-in-loop", + "Used when break or continue keywords are used outside a loop.", + ), + "E0104": ( + "Return outside function", + "return-outside-function", + 'Used when a "return" statement is found outside a function or method.', + ), + "E0105": ( + "Yield outside function", + "yield-outside-function", + 'Used when a "yield" statement is found outside a function or method.', + ), + "E0106": ( + "Return with argument inside generator", + "return-arg-in-generator", + 'Used when a "return" statement with an argument is found ' + "outside in a generator function or method (e.g. with some " + '"yield" statements).', + {"maxversion": (3, 3)}, + ), + "E0107": ( + "Use of the non-existent %s operator", + "nonexistent-operator", + "Used when you attempt to use the C-style pre-increment or " + "pre-decrement operator -- and ++, which doesn't exist in Python.", + ), + "E0108": ( + "Duplicate argument name %s in function definition", + "duplicate-argument-name", + "Duplicate argument names in function definitions are syntax errors.", + ), + "E0110": ( + "Abstract class %r with abstract methods instantiated", + "abstract-class-instantiated", + "Used when an abstract class with `abc.ABCMeta` as metaclass " + "has abstract methods and is instantiated.", + ), + "W0120": ( + "Else clause on loop without a break statement", + "useless-else-on-loop", + "Loops should only have an else clause if they can exit early " + "with a break statement, otherwise the statements under else " + "should be on the same scope as the loop itself.", + ), + "E0112": ( + "More than one starred expression in assignment", + "too-many-star-expressions", + "Emitted when there are more than one starred " + "expressions (`*x`) in an assignment. This is a SyntaxError.", + ), + "E0113": ( + "Starred assignment target must be in a list or tuple", + "invalid-star-assignment-target", + "Emitted when a star expression is used as a starred assignment target.", + ), + "E0114": ( + "Can use starred expression only in assignment target", + "star-needs-assignment-target", + "Emitted when a star expression is not used in an assignment target.", + ), + "E0115": ( + "Name %r is nonlocal and global", + "nonlocal-and-global", + "Emitted when a name is both nonlocal and global.", + ), + "E0116": ( + "'continue' not supported inside 'finally' clause", + "continue-in-finally", + "Emitted when the `continue` keyword is found " + "inside a finally clause, which is a SyntaxError.", + ), + "E0117": ( + "nonlocal name %s found without binding", + "nonlocal-without-binding", + "Emitted when a nonlocal variable does not have an attached " + "name somewhere in the parent scopes", + ), + "E0118": ( + "Name %r is used prior to global declaration", + "used-prior-global-declaration", + "Emitted when a name is used prior a global declaration, " + "which results in an error since Python 3.6.", + {"minversion": (3, 6)}, + ), + } + + @utils.check_messages("function-redefined") + def visit_classdef(self, node): + self._check_redefinition("class", node) + + def _too_many_starred_for_tuple(self, assign_tuple): + starred_count = 0 + for elem in assign_tuple.itered(): + if isinstance(elem, astroid.Tuple): + return self._too_many_starred_for_tuple(elem) + if isinstance(elem, astroid.Starred): + starred_count += 1 + return starred_count > 1 + + @utils.check_messages("too-many-star-expressions", "invalid-star-assignment-target") + def visit_assign(self, node): + # Check *a, *b = ... + assign_target = node.targets[0] + # Check *a = b + if isinstance(node.targets[0], astroid.Starred): + self.add_message("invalid-star-assignment-target", node=node) + + if not isinstance(assign_target, astroid.Tuple): + return + if self._too_many_starred_for_tuple(assign_target): + self.add_message("too-many-star-expressions", node=node) + + @utils.check_messages("star-needs-assignment-target") + def visit_starred(self, node): + """Check that a Starred expression is used in an assignment target.""" + if isinstance(node.parent, astroid.Call): + # f(*args) is converted to Call(args=[Starred]), so ignore + # them for this check. + return + if isinstance( + node.parent, (astroid.List, astroid.Tuple, astroid.Set, astroid.Dict) + ): + # PEP 448 unpacking. + return + + stmt = node.statement() + if not isinstance(stmt, astroid.Assign): + return + + if stmt.value is node or stmt.value.parent_of(node): + self.add_message("star-needs-assignment-target", node=node) + + @utils.check_messages( + "init-is-generator", + "return-in-init", + "function-redefined", + "return-arg-in-generator", + "duplicate-argument-name", + "nonlocal-and-global", + "used-prior-global-declaration", + ) + def visit_functiondef(self, node): + self._check_nonlocal_and_global(node) + self._check_name_used_prior_global(node) + if not redefined_by_decorator( + node + ) and not utils.is_registered_in_singledispatch_function(node): + self._check_redefinition(node.is_method() and "method" or "function", node) + # checks for max returns, branch, return in __init__ + returns = node.nodes_of_class( + astroid.Return, skip_klass=(astroid.FunctionDef, astroid.ClassDef) + ) + if node.is_method() and node.name == "__init__": + if node.is_generator(): + self.add_message("init-is-generator", node=node) + else: + values = [r.value for r in returns] + # Are we returning anything but None from constructors + if any(v for v in values if not utils.is_none(v)): + self.add_message("return-in-init", node=node) + # Check for duplicate names by clustering args with same name for detailed report + arg_clusters = collections.defaultdict(list) + arguments = filter(None, [node.args.args, node.args.kwonlyargs]) + + for arg in itertools.chain.from_iterable(arguments): + arg_clusters[arg.name].append(arg) + + # provide detailed report about each repeated argument + for argument_duplicates in arg_clusters.values(): + if len(argument_duplicates) != 1: + for argument in argument_duplicates: + self.add_message( + "duplicate-argument-name", + line=argument.lineno, + node=argument, + args=(argument.name,), + ) + + visit_asyncfunctiondef = visit_functiondef + + def _check_name_used_prior_global(self, node): + + scope_globals = { + name: child + for child in node.nodes_of_class(astroid.Global) + for name in child.names + if child.scope() is node + } + + if not scope_globals: + return + + for node_name in node.nodes_of_class(astroid.Name): + if node_name.scope() is not node: + continue + + name = node_name.name + corresponding_global = scope_globals.get(name) + if not corresponding_global: + continue + + global_lineno = corresponding_global.fromlineno + if global_lineno and global_lineno > node_name.fromlineno: + self.add_message( + "used-prior-global-declaration", node=node_name, args=(name,) + ) + + def _check_nonlocal_and_global(self, node): + """Check that a name is both nonlocal and global.""" + + def same_scope(current): + return current.scope() is node + + from_iter = itertools.chain.from_iterable + nonlocals = set( + from_iter( + child.names + for child in node.nodes_of_class(astroid.Nonlocal) + if same_scope(child) + ) + ) + + if not nonlocals: + return + + global_vars = set( + from_iter( + child.names + for child in node.nodes_of_class(astroid.Global) + if same_scope(child) + ) + ) + for name in nonlocals.intersection(global_vars): + self.add_message("nonlocal-and-global", args=(name,), node=node) + + @utils.check_messages("return-outside-function") + def visit_return(self, node): + if not isinstance(node.frame(), astroid.FunctionDef): + self.add_message("return-outside-function", node=node) + + @utils.check_messages("yield-outside-function") + def visit_yield(self, node): + self._check_yield_outside_func(node) + + @utils.check_messages("yield-outside-function") + def visit_yieldfrom(self, node): + self._check_yield_outside_func(node) + + @utils.check_messages("not-in-loop", "continue-in-finally") + def visit_continue(self, node): + self._check_in_loop(node, "continue") + + @utils.check_messages("not-in-loop") + def visit_break(self, node): + self._check_in_loop(node, "break") + + @utils.check_messages("useless-else-on-loop") + def visit_for(self, node): + self._check_else_on_loop(node) + + @utils.check_messages("useless-else-on-loop") + def visit_while(self, node): + self._check_else_on_loop(node) + + @utils.check_messages("nonexistent-operator") + def visit_unaryop(self, node): + """check use of the non-existent ++ and -- operator operator""" + if ( + (node.op in "+-") + and isinstance(node.operand, astroid.UnaryOp) + and (node.operand.op == node.op) + ): + self.add_message("nonexistent-operator", node=node, args=node.op * 2) + + def _check_nonlocal_without_binding(self, node, name): + current_scope = node.scope() + while True: + if current_scope.parent is None: + break + + if not isinstance(current_scope, (astroid.ClassDef, astroid.FunctionDef)): + self.add_message("nonlocal-without-binding", args=(name,), node=node) + return + + if name not in current_scope.locals: + current_scope = current_scope.parent.scope() + continue + + # Okay, found it. + return + + if not isinstance(current_scope, astroid.FunctionDef): + self.add_message("nonlocal-without-binding", args=(name,), node=node) + + @utils.check_messages("nonlocal-without-binding") + def visit_nonlocal(self, node): + for name in node.names: + self._check_nonlocal_without_binding(node, name) + + @utils.check_messages("abstract-class-instantiated") + def visit_call(self, node): + """ Check instantiating abstract class with + abc.ABCMeta as metaclass. + """ + try: + for inferred in node.func.infer(): + self._check_inferred_class_is_abstract(inferred, node) + except astroid.InferenceError: + return + + def _check_inferred_class_is_abstract(self, inferred, node): + if not isinstance(inferred, astroid.ClassDef): + return + + klass = utils.node_frame_class(node) + if klass is inferred: + # Don't emit the warning if the class is instantiated + # in its own body or if the call is not an instance + # creation. If the class is instantiated into its own + # body, we're expecting that it knows what it is doing. + return + + # __init__ was called + abstract_methods = _has_abstract_methods(inferred) + + if not abstract_methods: + return + + metaclass = inferred.metaclass() + + if metaclass is None: + # Python 3.4 has `abc.ABC`, which won't be detected + # by ClassNode.metaclass() + for ancestor in inferred.ancestors(): + if ancestor.qname() == "abc.ABC": + self.add_message( + "abstract-class-instantiated", args=(inferred.name,), node=node + ) + break + + return + + if metaclass.qname() in ABC_METACLASSES: + self.add_message( + "abstract-class-instantiated", args=(inferred.name,), node=node + ) + + def _check_yield_outside_func(self, node): + if not isinstance(node.frame(), (astroid.FunctionDef, astroid.Lambda)): + self.add_message("yield-outside-function", node=node) + + def _check_else_on_loop(self, node): + """Check that any loop with an else clause has a break statement.""" + if node.orelse and not _loop_exits_early(node): + self.add_message( + "useless-else-on-loop", + node=node, + # This is not optimal, but the line previous + # to the first statement in the else clause + # will usually be the one that contains the else:. + line=node.orelse[0].lineno - 1, + ) + + def _check_in_loop(self, node, node_name): + """check that a node is inside a for or while loop""" + _node = node.parent + while _node: + if isinstance(_node, (astroid.For, astroid.While)): + if node not in _node.orelse: + return + + if isinstance(_node, (astroid.ClassDef, astroid.FunctionDef)): + break + if ( + isinstance(_node, astroid.TryFinally) + and node in _node.finalbody + and isinstance(node, astroid.Continue) + ): + self.add_message("continue-in-finally", node=node) + + _node = _node.parent + + self.add_message("not-in-loop", node=node, args=node_name) + + def _check_redefinition(self, redeftype, node): + """check for redefinition of a function / method / class name""" + parent_frame = node.parent.frame() + + # Ignore function stubs created for type information + redefinitions = parent_frame.locals[node.name] + defined_self = next( + (local for local in redefinitions if not utils.is_overload_stub(local)), + node, + ) + if defined_self is not node and not astroid.are_exclusive(node, defined_self): + + # Additional checks for methods which are not considered + # redefined, since they are already part of the base API. + if ( + isinstance(parent_frame, astroid.ClassDef) + and node.name in REDEFINABLE_METHODS + ): + return + + if utils.is_overload_stub(node): + return + + # Check if we have forward references for this node. + try: + redefinition_index = redefinitions.index(node) + except ValueError: + pass + else: + for redefinition in redefinitions[:redefinition_index]: + inferred = utils.safe_infer(redefinition) + if ( + inferred + and isinstance(inferred, astroid.Instance) + and inferred.qname() == TYPING_FORWARD_REF_QNAME + ): + return + + dummy_variables_rgx = lint_utils.get_global_option( + self, "dummy-variables-rgx", default=None + ) + if dummy_variables_rgx and dummy_variables_rgx.match(node.name): + return + self.add_message( + "function-redefined", + node=node, + args=(redeftype, defined_self.fromlineno), + ) + + +class BasicChecker(_BasicChecker): + """checks for : + * doc strings + * number of arguments, local variables, branches, returns and statements in + functions, methods + * required module attributes + * dangerous default values as arguments + * redefinition of function / method / class + * uses of the global statement + """ + + __implements__ = interfaces.IAstroidChecker + + name = "basic" + msgs = { + "W0101": ( + "Unreachable code", + "unreachable", + 'Used when there is some code behind a "return" or "raise" ' + "statement, which will never be accessed.", + ), + "W0102": ( + "Dangerous default value %s as argument", + "dangerous-default-value", + "Used when a mutable value as list or dictionary is detected in " + "a default value for an argument.", + ), + "W0104": ( + "Statement seems to have no effect", + "pointless-statement", + "Used when a statement doesn't have (or at least seems to) any effect.", + ), + "W0105": ( + "String statement has no effect", + "pointless-string-statement", + "Used when a string is used as a statement (which of course " + "has no effect). This is a particular case of W0104 with its " + "own message so you can easily disable it if you're using " + "those strings as documentation, instead of comments.", + ), + "W0106": ( + 'Expression "%s" is assigned to nothing', + "expression-not-assigned", + "Used when an expression that is not a function call is assigned " + "to nothing. Probably something else was intended.", + ), + "W0108": ( + "Lambda may not be necessary", + "unnecessary-lambda", + "Used when the body of a lambda expression is a function call " + "on the same argument list as the lambda itself; such lambda " + "expressions are in all but a few cases replaceable with the " + "function being called in the body of the lambda.", + ), + "W0109": ( + "Duplicate key %r in dictionary", + "duplicate-key", + "Used when a dictionary expression binds the same key multiple times.", + ), + "W0122": ( + "Use of exec", + "exec-used", + 'Used when you use the "exec" statement (function for Python ' + "3), to discourage its usage. That doesn't " + "mean you cannot use it !", + ), + "W0123": ( + "Use of eval", + "eval-used", + 'Used when you use the "eval" function, to discourage its ' + "usage. Consider using `ast.literal_eval` for safely evaluating " + "strings containing Python expressions " + "from untrusted sources. ", + ), + "W0150": ( + "%s statement in finally block may swallow exception", + "lost-exception", + "Used when a break or a return statement is found inside the " + "finally clause of a try...finally block: the exceptions raised " + "in the try clause will be silently swallowed instead of being " + "re-raised.", + ), + "W0199": ( + "Assert called on a 2-item-tuple. Did you mean 'assert x,y'?", + "assert-on-tuple", + "A call of assert on a tuple will always evaluate to true if " + "the tuple is not empty, and will always evaluate to false if " + "it is.", + ), + "W0124": ( + 'Following "as" with another context manager looks like a tuple.', + "confusing-with-statement", + "Emitted when a `with` statement component returns multiple values " + "and uses name binding with `as` only for a part of those values, " + "as in with ctx() as a, b. This can be misleading, since it's not " + "clear if the context manager returns a tuple or if the node without " + "a name binding is another context manager.", + ), + "W0125": ( + "Using a conditional statement with a constant value", + "using-constant-test", + "Emitted when a conditional statement (If or ternary if) " + "uses a constant value for its test. This might not be what " + "the user intended to do.", + ), + "W0126": ( + "Using a conditional statement with potentially wrong function or method call due to missing parentheses", + "missing-parentheses-for-call-in-test", + "Emitted when a conditional statement (If or ternary if) " + "seems to wrongly call a function due to missing parentheses", + ), + "W0127": ( + "Assigning the same variable %r to itself", + "self-assigning-variable", + "Emitted when we detect that a variable is assigned to itself", + ), + "W0128": ( + "Redeclared variable %r in assignment", + "redeclared-assigned-name", + "Emitted when we detect that a variable was redeclared in the same assignment.", + ), + "E0111": ( + "The first reversed() argument is not a sequence", + "bad-reversed-sequence", + "Used when the first argument to reversed() builtin " + "isn't a sequence (does not implement __reversed__, " + "nor __getitem__ and __len__", + ), + "E0119": ( + "format function is not called on str", + "misplaced-format-function", + "Emitted when format function is not called on str object. " + 'e.g doing print("value: {}").format(123) instead of ' + 'print("value: {}".format(123)). This might not be what the user ' + "intended to do.", + ), + } + + reports = (("RP0101", "Statistics by type", report_by_type_stats),) + + def __init__(self, linter): + _BasicChecker.__init__(self, linter) + self.stats = None + self._tryfinallys = None + + def open(self): + """initialize visit variables and statistics + """ + self._tryfinallys = [] + self.stats = self.linter.add_stats(module=0, function=0, method=0, class_=0) + + @utils.check_messages("using-constant-test", "missing-parentheses-for-call-in-test") + def visit_if(self, node): + self._check_using_constant_test(node, node.test) + + @utils.check_messages("using-constant-test", "missing-parentheses-for-call-in-test") + def visit_ifexp(self, node): + self._check_using_constant_test(node, node.test) + + @utils.check_messages("using-constant-test", "missing-parentheses-for-call-in-test") + def visit_comprehension(self, node): + if node.ifs: + for if_test in node.ifs: + self._check_using_constant_test(node, if_test) + + def _check_using_constant_test(self, node, test): + const_nodes = ( + astroid.Module, + astroid.scoped_nodes.GeneratorExp, + astroid.Lambda, + astroid.FunctionDef, + astroid.ClassDef, + astroid.bases.Generator, + astroid.UnboundMethod, + astroid.BoundMethod, + astroid.Module, + ) + structs = (astroid.Dict, astroid.Tuple, astroid.Set) + + # These nodes are excepted, since they are not constant + # values, requiring a computation to happen. + except_nodes = ( + astroid.Call, + astroid.BinOp, + astroid.BoolOp, + astroid.UnaryOp, + astroid.Subscript, + ) + inferred = None + emit = isinstance(test, (astroid.Const,) + structs + const_nodes) + if not isinstance(test, except_nodes): + inferred = utils.safe_infer(test) + + if emit: + self.add_message("using-constant-test", node=node) + elif isinstance(inferred, const_nodes): + # If the constant node is a FunctionDef or Lambda then + #  it may be a illicit function call due to missing parentheses + call_inferred = None + if isinstance(inferred, astroid.FunctionDef): + call_inferred = inferred.infer_call_result() + elif isinstance(inferred, astroid.Lambda): + call_inferred = inferred.infer_call_result(node) + if call_inferred: + try: + for inf_call in call_inferred: + if inf_call != astroid.Uninferable: + self.add_message( + "missing-parentheses-for-call-in-test", node=node + ) + break + except astroid.InferenceError: + pass + self.add_message("using-constant-test", node=node) + + def visit_module(self, _): + """check module name, docstring and required arguments + """ + self.stats["module"] += 1 + + def visit_classdef(self, node): # pylint: disable=unused-argument + """check module name, docstring and redefinition + increment branch counter + """ + self.stats["class"] += 1 + + @utils.check_messages( + "pointless-statement", "pointless-string-statement", "expression-not-assigned" + ) + def visit_expr(self, node): + """Check for various kind of statements without effect""" + expr = node.value + if isinstance(expr, astroid.Const) and isinstance(expr.value, str): + # treat string statement in a separated message + # Handle PEP-257 attribute docstrings. + # An attribute docstring is defined as being a string right after + # an assignment at the module level, class level or __init__ level. + scope = expr.scope() + if isinstance( + scope, (astroid.ClassDef, astroid.Module, astroid.FunctionDef) + ): + if isinstance(scope, astroid.FunctionDef) and scope.name != "__init__": + pass + else: + sibling = expr.previous_sibling() + if ( + sibling is not None + and sibling.scope() is scope + and isinstance(sibling, (astroid.Assign, astroid.AnnAssign)) + ): + return + self.add_message("pointless-string-statement", node=node) + return + + # Ignore if this is : + # * a direct function call + # * the unique child of a try/except body + # * a yield statement + # * an ellipsis (which can be used on Python 3 instead of pass) + # warn W0106 if we have any underlying function call (we can't predict + # side effects), else pointless-statement + if ( + isinstance( + expr, (astroid.Yield, astroid.Await, astroid.Ellipsis, astroid.Call) + ) + or ( + isinstance(node.parent, astroid.TryExcept) + and node.parent.body == [node] + ) + or (isinstance(expr, astroid.Const) and expr.value is Ellipsis) + ): + return + if any(expr.nodes_of_class(astroid.Call)): + self.add_message( + "expression-not-assigned", node=node, args=expr.as_string() + ) + else: + self.add_message("pointless-statement", node=node) + + @staticmethod + def _filter_vararg(node, call_args): + # Return the arguments for the given call which are + # not passed as vararg. + for arg in call_args: + if isinstance(arg, astroid.Starred): + if ( + isinstance(arg.value, astroid.Name) + and arg.value.name != node.args.vararg + ): + yield arg + else: + yield arg + + @staticmethod + def _has_variadic_argument(args, variadic_name): + if not args: + return True + for arg in args: + if isinstance(arg.value, astroid.Name): + if arg.value.name != variadic_name: + return True + else: + return True + return False + + @utils.check_messages("unnecessary-lambda") + def visit_lambda(self, node): + """check whether or not the lambda is suspicious + """ + # if the body of the lambda is a call expression with the same + # argument list as the lambda itself, then the lambda is + # possibly unnecessary and at least suspicious. + if node.args.defaults: + # If the arguments of the lambda include defaults, then a + # judgment cannot be made because there is no way to check + # that the defaults defined by the lambda are the same as + # the defaults defined by the function called in the body + # of the lambda. + return + call = node.body + if not isinstance(call, astroid.Call): + # The body of the lambda must be a function call expression + # for the lambda to be unnecessary. + return + if isinstance(node.body.func, astroid.Attribute) and isinstance( + node.body.func.expr, astroid.Call + ): + # Chained call, the intermediate call might + # return something else (but we don't check that, yet). + return + + call_site = CallSite.from_call(call) + ordinary_args = list(node.args.args) + new_call_args = list(self._filter_vararg(node, call.args)) + if node.args.kwarg: + if self._has_variadic_argument(call.kwargs, node.args.kwarg): + return + + if node.args.vararg: + if self._has_variadic_argument(call.starargs, node.args.vararg): + return + elif call.starargs: + return + + if call.keywords: + # Look for additional keyword arguments that are not part + # of the lambda's signature + lambda_kwargs = {keyword.name for keyword in node.args.defaults} + if len(lambda_kwargs) != len(call_site.keyword_arguments): + # Different lengths, so probably not identical + return + if set(call_site.keyword_arguments).difference(lambda_kwargs): + return + + # The "ordinary" arguments must be in a correspondence such that: + # ordinary_args[i].name == call.args[i].name. + if len(ordinary_args) != len(new_call_args): + return + for arg, passed_arg in zip(ordinary_args, new_call_args): + if not isinstance(passed_arg, astroid.Name): + return + if arg.name != passed_arg.name: + return + + self.add_message("unnecessary-lambda", line=node.fromlineno, node=node) + + @utils.check_messages("dangerous-default-value") + def visit_functiondef(self, node): + """check function name, docstring, arguments, redefinition, + variable names, max locals + """ + self.stats["method" if node.is_method() else "function"] += 1 + self._check_dangerous_default(node) + + visit_asyncfunctiondef = visit_functiondef + + def _check_dangerous_default(self, node): + # check for dangerous default values as arguments + is_iterable = lambda n: isinstance(n, (astroid.List, astroid.Set, astroid.Dict)) + for default in node.args.defaults: + try: + value = next(default.infer()) + except astroid.InferenceError: + continue + + if ( + isinstance(value, astroid.Instance) + and value.qname() in DEFAULT_ARGUMENT_SYMBOLS + ): + + if value is default: + msg = DEFAULT_ARGUMENT_SYMBOLS[value.qname()] + elif isinstance(value, astroid.Instance) or is_iterable(value): + # We are here in the following situation(s): + # * a dict/set/list/tuple call which wasn't inferred + # to a syntax node ({}, () etc.). This can happen + # when the arguments are invalid or unknown to + # the inference. + # * a variable from somewhere else, which turns out to be a list + # or a dict. + if is_iterable(default): + msg = value.pytype() + elif isinstance(default, astroid.Call): + msg = "%s() (%s)" % (value.name, value.qname()) + else: + msg = "%s (%s)" % (default.as_string(), value.qname()) + else: + # this argument is a name + msg = "%s (%s)" % ( + default.as_string(), + DEFAULT_ARGUMENT_SYMBOLS[value.qname()], + ) + self.add_message("dangerous-default-value", node=node, args=(msg,)) + + @utils.check_messages("unreachable", "lost-exception") + def visit_return(self, node): + """1 - check is the node has a right sibling (if so, that's some + unreachable code) + 2 - check is the node is inside the finally clause of a try...finally + block + """ + self._check_unreachable(node) + # Is it inside final body of a try...finally bloc ? + self._check_not_in_finally(node, "return", (astroid.FunctionDef,)) + + @utils.check_messages("unreachable") + def visit_continue(self, node): + """check is the node has a right sibling (if so, that's some unreachable + code) + """ + self._check_unreachable(node) + + @utils.check_messages("unreachable", "lost-exception") + def visit_break(self, node): + """1 - check is the node has a right sibling (if so, that's some + unreachable code) + 2 - check is the node is inside the finally clause of a try...finally + block + """ + # 1 - Is it right sibling ? + self._check_unreachable(node) + # 2 - Is it inside final body of a try...finally bloc ? + self._check_not_in_finally(node, "break", (astroid.For, astroid.While)) + + @utils.check_messages("unreachable") + def visit_raise(self, node): + """check if the node has a right sibling (if so, that's some unreachable + code) + """ + self._check_unreachable(node) + + @utils.check_messages("exec-used") + def visit_exec(self, node): + """just print a warning on exec statements""" + self.add_message("exec-used", node=node) + + def _check_misplaced_format_function(self, call_node): + if not isinstance(call_node.func, astroid.Attribute): + return + if call_node.func.attrname != "format": + return + + expr = utils.safe_infer(call_node.func.expr) + if expr is astroid.Uninferable: + return + if not expr: + # we are doubtful on inferred type of node, so here just check if format + # was called on print() + call_expr = call_node.func.expr + if not isinstance(call_expr, astroid.Call): + return + if ( + isinstance(call_expr.func, astroid.Name) + and call_expr.func.name == "print" + ): + self.add_message("misplaced-format-function", node=call_node) + + @utils.check_messages( + "eval-used", "exec-used", "bad-reversed-sequence", "misplaced-format-function" + ) + def visit_call(self, node): + """visit a Call node -> check if this is not a blacklisted builtin + call and check for * or ** use + """ + self._check_misplaced_format_function(node) + if isinstance(node.func, astroid.Name): + name = node.func.name + # ignore the name if it's not a builtin (i.e. not defined in the + # locals nor globals scope) + if not (name in node.frame() or name in node.root()): + if name == "exec": + self.add_message("exec-used", node=node) + elif name == "reversed": + self._check_reversed(node) + elif name == "eval": + self.add_message("eval-used", node=node) + + @utils.check_messages("assert-on-tuple") + def visit_assert(self, node): + """check the use of an assert statement on a tuple.""" + if ( + node.fail is None + and isinstance(node.test, astroid.Tuple) + and len(node.test.elts) == 2 + ): + self.add_message("assert-on-tuple", node=node) + + @utils.check_messages("duplicate-key") + def visit_dict(self, node): + """check duplicate key in dictionary""" + keys = set() + for k, _ in node.items: + if isinstance(k, astroid.Const): + key = k.value + if key in keys: + self.add_message("duplicate-key", node=node, args=key) + keys.add(key) + + def visit_tryfinally(self, node): + """update try...finally flag""" + self._tryfinallys.append(node) + + def leave_tryfinally(self, node): # pylint: disable=unused-argument + """update try...finally flag""" + self._tryfinallys.pop() + + def _check_unreachable(self, node): + """check unreachable code""" + unreach_stmt = node.next_sibling() + if unreach_stmt is not None: + self.add_message("unreachable", node=unreach_stmt) + + def _check_not_in_finally(self, node, node_name, breaker_classes=()): + """check that a node is not inside a finally clause of a + try...finally statement. + If we found before a try...finally bloc a parent which its type is + in breaker_classes, we skip the whole check.""" + # if self._tryfinallys is empty, we're not an in try...finally block + if not self._tryfinallys: + return + # the node could be a grand-grand...-children of the try...finally + _parent = node.parent + _node = node + while _parent and not isinstance(_parent, breaker_classes): + if hasattr(_parent, "finalbody") and _node in _parent.finalbody: + self.add_message("lost-exception", node=node, args=node_name) + return + _node = _parent + _parent = _node.parent + + def _check_reversed(self, node): + """ check that the argument to `reversed` is a sequence """ + try: + argument = utils.safe_infer(utils.get_argument_from_call(node, position=0)) + except utils.NoSuchArgumentError: + pass + else: + if argument is astroid.Uninferable: + return + if argument is None: + # Nothing was inferred. + # Try to see if we have iter(). + if isinstance(node.args[0], astroid.Call): + try: + func = next(node.args[0].func.infer()) + except astroid.InferenceError: + return + if getattr( + func, "name", None + ) == "iter" and utils.is_builtin_object(func): + self.add_message("bad-reversed-sequence", node=node) + return + + if isinstance(argument, (astroid.List, astroid.Tuple)): + return + + if isinstance(argument, astroid.Instance): + if argument._proxied.name == "dict" and utils.is_builtin_object( + argument._proxied + ): + self.add_message("bad-reversed-sequence", node=node) + return + if any( + ancestor.name == "dict" and utils.is_builtin_object(ancestor) + for ancestor in argument._proxied.ancestors() + ): + # Mappings aren't accepted by reversed(), unless + # they provide explicitly a __reversed__ method. + try: + argument.locals[REVERSED_PROTOCOL_METHOD] + except KeyError: + self.add_message("bad-reversed-sequence", node=node) + return + + if hasattr(argument, "getattr"): + # everything else is not a proper sequence for reversed() + for methods in REVERSED_METHODS: + for meth in methods: + try: + argument.getattr(meth) + except astroid.NotFoundError: + break + else: + break + else: + self.add_message("bad-reversed-sequence", node=node) + else: + self.add_message("bad-reversed-sequence", node=node) + + @utils.check_messages("confusing-with-statement") + def visit_with(self, node): + # a "with" statement with multiple managers coresponds + # to one AST "With" node with multiple items + pairs = node.items + if pairs: + for prev_pair, pair in zip(pairs, pairs[1:]): + if isinstance(prev_pair[1], astroid.AssignName) and ( + pair[1] is None and not isinstance(pair[0], astroid.Call) + ): + # Don't emit a message if the second is a function call + # there's no way that can be mistaken for a name assignment. + # If the line number doesn't match + # we assume it's a nested "with". + self.add_message("confusing-with-statement", node=node) + + def _check_self_assigning_variable(self, node): + # Detect assigning to the same variable. + + scope = node.scope() + scope_locals = scope.locals + + rhs_names = [] + targets = node.targets + if isinstance(targets[0], astroid.Tuple): + if len(targets) != 1: + # A complex assignment, so bail out early. + return + targets = targets[0].elts + + if isinstance(node.value, astroid.Name): + if len(targets) != 1: + return + rhs_names = [node.value] + elif isinstance(node.value, astroid.Tuple): + rhs_count = len(node.value.elts) + if len(targets) != rhs_count or rhs_count == 1: + return + rhs_names = node.value.elts + + for target, lhs_name in zip(targets, rhs_names): + if not isinstance(lhs_name, astroid.Name): + continue + if not isinstance(target, astroid.AssignName): + continue + if isinstance(scope, astroid.ClassDef) and target.name in scope_locals: + # Check that the scope is different than a class level, which is usually + # a pattern to expose module level attributes as class level ones. + continue + if target.name == lhs_name.name: + self.add_message( + "self-assigning-variable", args=(target.name,), node=target + ) + + def _check_redeclared_assign_name(self, targets): + for target in targets: + if not isinstance(target, astroid.Tuple): + continue + + found_names = [] + for element in target.elts: + if isinstance(element, astroid.Tuple): + self._check_redeclared_assign_name([element]) + elif isinstance(element, astroid.AssignName) and element.name != "_": + found_names.append(element.name) + + names = collections.Counter(found_names) + for name, count in names.most_common(): + if count > 1: + self.add_message( + "redeclared-assigned-name", args=(name,), node=target + ) + + @utils.check_messages("self-assigning-variable", "redeclared-assigned-name") + def visit_assign(self, node): + self._check_self_assigning_variable(node) + self._check_redeclared_assign_name(node.targets) + + @utils.check_messages("redeclared-assigned-name") + def visit_for(self, node): + self._check_redeclared_assign_name([node.target]) + + +KNOWN_NAME_TYPES = { + "module", + "const", + "class", + "function", + "method", + "attr", + "argument", + "variable", + "class_attribute", + "inlinevar", +} + + +HUMAN_READABLE_TYPES = { + "module": "module", + "const": "constant", + "class": "class", + "function": "function", + "method": "method", + "attr": "attribute", + "argument": "argument", + "variable": "variable", + "class_attribute": "class attribute", + "inlinevar": "inline iteration", +} + +DEFAULT_NAMING_STYLES = { + "module": "snake_case", + "const": "UPPER_CASE", + "class": "PascalCase", + "function": "snake_case", + "method": "snake_case", + "attr": "snake_case", + "argument": "snake_case", + "variable": "snake_case", + "class_attribute": "any", + "inlinevar": "any", +} + + +def _create_naming_options(): + name_options = [] + for name_type in sorted(KNOWN_NAME_TYPES): + human_readable_name = HUMAN_READABLE_TYPES[name_type] + default_style = DEFAULT_NAMING_STYLES[name_type] + name_type = name_type.replace("_", "-") + name_options.append( + ( + "%s-naming-style" % (name_type,), + { + "default": default_style, + "type": "choice", + "choices": list(NAMING_STYLES.keys()), + "metavar": "