././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8727553 stevedore-3.5.0/0000775000175000017500000000000000000000000013542 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/.pre-commit-config.yaml0000664000175000017500000000252300000000000020025 0ustar00zuulzuul00000000000000# We from the Oslo project decided to pin repos based on the # commit hash instead of the version tag to prevend arbitrary # code from running in developer's machines. To update to a # newer version, run `pre-commit autoupdate` and then replace # the newer versions with their commit hash. default_language_version: python: python3 repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: 9136088a246768144165fcc3ecc3d31bb686920a # v3.3.0 hooks: - id: trailing-whitespace # Replaces or checks mixed line ending - id: mixed-line-ending args: ['--fix', 'lf'] exclude: '.*\.(svg)$' # Forbid files which have a UTF-8 byte-order marker - id: check-byte-order-marker # Checks that non-binary executables have a proper shebang - id: check-executables-have-shebangs # Check for files that contain merge conflict strings. - id: check-merge-conflict # Check for debugger imports and py37+ breakpoint() # calls in python source - id: debug-statements - id: check-yaml files: .*\.(yaml|yml)$ - repo: local hooks: - id: flake8 name: flake8 additional_dependencies: - hacking>=3.0.1,<3.1.0 language: python entry: flake8 files: '^.*\.py$' exclude: '^(doc|releasenotes|tools)/.*$' ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/.stestr.conf0000664000175000017500000000006100000000000016010 0ustar00zuulzuul00000000000000[DEFAULT] test_path=./stevedore/tests top_dir=./ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/.zuul.yaml0000664000175000017500000000034000000000000015500 0ustar00zuulzuul00000000000000- project: templates: - check-requirements - lib-forward-testing-python3 - openstack-python3-yoga-jobs - periodic-stable-jobs - publish-openstack-docs-pti - release-notes-jobs-python3 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550441.0 stevedore-3.5.0/AUTHORS0000664000175000017500000000510000000000000014606 0ustar00zuulzuul00000000000000Abhishek Chanda Andreas Jaeger Artem Goncharov Bernhard M. Wiedemann Cao Xuan Hoang ChangBo Guo(gcb) Chris Yeoh Cleber Rosa Corey Bryant Cyril Roelandt Daniel Bengtsson Daniel Rocco Daniel Watkins Davanum Srinivas Dirk Mueller Doug Hellmann Doug Hellmann Doug Hellmann Elod Illes Evgeni Golov Flavio Percoco Ghanshyam Mann Hervé Beraud Jamie Lennox Jason R. Coombs Jeremy Stanley Joshua Harlow Joshua Harlow Julien Danjou Kevin Benton Louis Taylor Marc Koderer Marianne Linhares Michał Górny OpenStack Release Bot Philip Tzou Pierre Riteau Ricardo Kirkner Ryan Petrello Sahid Orentino Ferdjaoui Sean McGinnis Sean McGinnis Stephen Finucane Swapnil Kulkarni (coolsvap) Thomas Bechtold Thomas Goirand Tony Breeds Vu Cong Tuan Wes Turner XiaojueGuan Yvonne Stachowski Zhao Lei caoyue gengchc2 liangjingtao lingyongxu liuwei maaoyu malei markmcclain melissaml pengyuesheng qingszhao shuangtai wu.chunyang wu.shiming zhang.lei zhangwen1 zhangziwen Łukasz Jernaś ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/CONTRIBUTING.rst0000664000175000017500000000051300000000000016202 0ustar00zuulzuul00000000000000Changes should be submitted for review via the Gerrit tool, following the workflow documented at: http://docs.openstack.org/infra/manual/developers.html#development-workflow Pull requests submitted through GitHub will be ignored. Bugs should be filed on Launchpad, not GitHub: https://bugs.launchpad.net/python-stevedore ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550441.0 stevedore-3.5.0/ChangeLog0000664000175000017500000003224000000000000015315 0ustar00zuulzuul00000000000000CHANGES ======= 3.5.0 ----- * Add Python3 yoga unit tests * Update master for stable/xena * Rely on member access, the preferred access since importlib\_metadata 4.8 3.4.0 ----- * setup.cfg: Replace dashes with underscores * Fix formatting of release list * Remove lower-constraints remnants * Move flake8 as a pre-commit local target * Add Python3 xena unit tests * Update master for stable/wallaby * Dropping lower constraints testing 3.3.0 ----- * Use TOX\_CONSTRAINTS\_FILE * Use py3 as the default runtime for tox * Adding pre-commit * Fix cache dir flooding when running from /tmp * Add Python3 wallaby unit tests * Update master for stable/victoria 3.2.2 ----- * fix supported python versions in documentation 3.2.1 ----- * Fix the bug 1892610. There're some syntax errors in the comment of stevedore code 3.2.0 ----- * add property methods to extension for more entry point values 3.1.0 ----- * sphinxext: fix warning message for detailed list 3.0.0 ----- * add release note before major version update * switch to importlib.metadata package 2.0.1 ----- * Remove Travis CI config * Replace external mock with built-in unittest.mock 2.0.0 ----- * Stop to use the \_\_future\_\_ module * Switch to newer openstackdocstheme and reno versions * Add Python3 victoria unit tests * Mark sphinx extensions thread safe * Remove dead files * Drop Python 2.7 support * Update master for stable/ussuri 1.32.0 ------ * Switch to Ussuri jobs * Blacklist sphinx 2.1.0 (autodoc bug) * Update the constraints url * Update master for stable/train 1.31.0 ------ * Add Python 3 Train unit tests * Add local bindep.txt * Cap Bandit below 1.6.0 and update Sphinx requirement * update git.openstack.org to opendev * OpenDev Migration Patch * Dropping the py35 testing * Update master for stable/stein * Delete repeated param description * add python 3.7 unit test job 1.30.1 ------ * Use template for lower-constraints * Change openstack-dev to openstack-discuss 1.30.0 ------ * Update sphinx logging to not use app object * Removed older version of python added 3.5 * Update doc/conf.py to avoid warnings with sphinx 1.8 * add lib-forward-testing-python3 test job * fix wrong link * add python 3.6 unit test job * import zuul job settings from project-config * Update reno for stable/rocky 1.29.0 ------ * Remove unnecessary py27 testenv * Switch to stestr * fix tox python3 overrides * Trivial: Update pypi url to new url * Trivial: Update pypi url to new url * set default python to python3 * add lower-constraints job * Updated from global requirements * Update links in README * Update reno for stable/queens * Updated from global requirements * Updated from global requirements * Follow the new PTI for document build 1.28.0 ------ * Updated from global requirements * Remove -U from pip install * Avoid tox\_install.sh for constraints support * add bandit to pep8 job * move doc requirements to doc/requirements.txt * Remove setting of version/release from releasenotes * Updated from global requirements 1.27.1 ------ * Move reno to optional docs requirements * Remove duplicate optional requirement 1.27.0 ------ * Updated from global requirements 1.26.0 ------ * Updated from global requirements * Remove Pillow from test-requirements * Make openstackdocstheme an optional doc dependency * Updated from global requirements * Add an ExtensionManager.items() method * Update reno for stable/pike * Updated from global requirements 1.25.0 ------ * Update URLs in documents according to document migration 1.24.0 ------ * switch from oslosphinx to openstackdocstheme * turn on warning-is-error for doc build * move documentation into the new standard layout * Updated from global requirements * fix setuptools url 1.23.0 ------ * Updated from global requirements * Remove 'run\_sphinx' script * Remove unused doc/requirements.txt * Mark as Production/Stable instead of Alpha 1.22.0 ------ * Remove oslotest from test-requirements * Updated from global requirements * Updated from global requirements * Updated from global requirements * Update reno for stable/ocata 1.21.0 ------ * Updated from global requirements * Updated from global requirements * Updated from global requirements * Remove support for py34 1.20.0 ------ * extension: add entry\_point\_names method * extension: expose \_find\_entry\_points as list\_entry\_points * Allow suppression of warnings from DriverManager * Show team and repo badges on README * Add Constraints support 1.19.1 ------ * Broken link at stevedore developer documentation 1.19.0 ------ * Add Apache 2.0 license to source file * Updated from global requirements * Add reno for release notes management * Updated from global requirements * Remove reference to non-existing page 1.18.0 ------ * Updated from global requirements * Fix typos in exception.py 1.17.1 ------ * do not emit warnings for missing hooks 1.17.0 ------ * Remove discover from test-requirements * make error reporting for extension loading quieter * Add Python 3.5 classifier and venv * Replace assertEquals() with assertEqual() 1.16.0 ------ * Fix NamedExtensionManager fails when loading failing extension in order * Remove irrelated output item * Fix broken link about setuptools entry points * NamedExtensionManager: call a callback when some names cannot be found * Updated from global requirements 1.15.0 ------ * Updated from global requirements 1.14.0 ------ * Trivial: ignore openstack/common in flake8 exclude list 1.13.0 ------ * dont claim copyright for future years 1.12.0 ------ * Add a reference to entry\_point\_inspector 1.11.0 ------ * Updated from global requirements * Trival:Remove unused logging import * Remove work around for NullHandler * remove unnecessary dependency on argparse 1.10.0 ------ * Use Stevedore exceptions for finding extensions * Clean up Python 2.6 related stuff * Updated from global requirements * Remove Python 2.6 classifier * cleanup tox.ini 1.9.0 ----- * Updated from global requirements * docs - Set pbr 'warnerrors' option for doc build * Add clarifying language to description of scanning for plugins * clean up default tox environment list * Show how to add a plugin in a separate package * replace the hard-coded history list with an auto-generated one * Fix spelling typo for maunal * Updated from global requirements * Examples typo fix 1.8.0 ----- * Updated from global requirements * Updated from global requirements * Updated from global requirements 1.7.0 ----- * Updated from global requirements * Updated from global requirements * Titlecase looks nicer sometimes in detailed mode * Updated from global requirements * Updated from global requirements * Updated from global requirements * Update homepage to openstack hosted docs page 1.6.0 ----- * Document the signature for check\_func * Updated from global requirements * Switch badges from 'pypip.in' to 'shields.io' * Remove unnecessary openstack-common.conf 1.5.0 ----- * Removed non-free color profile from .jpg * Add sphinx integration * Updated from global requirements * Fix Python versions supported * Remove run\_cross\_tests.sh * fix author contact details * re-raise exception with full traceback 1.4.0 ----- * Uncap library requirements for liberty * Add pypi download + version badges * Updated from global requirements 1.3.0 ----- * Updated from global requirements * Fix test for finding multiple drivers * ignore .testrepository directory created by testr * clean up default environments run by tox 1.2.0 ----- * Use pkg\_resources resolve() and require() instead of load() * Fix the README.rst file format for pypi * Workflow documentation is now in infra-manual * Implement a \_\_contains\_\_ override for extension manager * Update link to docs in README * Bring doc build up to standard 1.1.0 ----- * Add pbr to dependency list * Updated from global requirements * Add more detail to the README * Migrate tox to use testr * Update repository location in docs 1.0.0 ----- * Build universal wheels * Work toward Python 3.4 support and testing * warn against sorting requirements 1.0.0.0a1 --------- * Updated from global requirements * Fix incorrect image reference in documentation * Fix requirement handling in tox * Updated from global requirements * use six.add\_metaclass * Updated from global requirements * driver: raise by default on import failure * Add doc requirements to venv environ * Import run\_cross\_tests.sh from oslo-incubator * fix link to entry point docs 0.15 ---- * Only log error when no load handler is set * Update readme with links to bug tracker and source * Update .gitreview after moving the repository 0.14.1 ------ * Fix the test manager implementation 0.14 ---- * prep history for 0.14 release * Make requirements checking optional * Update docstrings * Remove requirements checking for dependencies * fix typo in contrib docs * Add contributing instructions for github mirrors * Allow a on\_load\_failure\_callback to be provided * Add venv environment to tox * driver: remove useless arg propagate\_map\_exceptions * Move to stackforge * update release announcement file * update release number in history 0.13 ---- * update history file before release * deprecate TestExtensionManager * clean up docs for DriverManager * simplify test instance factory contract * driver extension manager test instance factory * enabled extension manager test instance factory * make Extension responsible for formatting its target name * add test instance factory for the base, named, and hook managers * use item access instead of temporary dict when ordering extensions * DOC: Updated index.rst: distribute -> setuptools * a work-around to avoid cpython bug (15881) * add pypy to travis config * add pypy to default test env list * Fix pip call in tox config * fix version number in blog announcement file 0.12 ---- * update history and announce file for release * remove version from setup.cfg and rely on git tag * Switch to pbr * Fix flake8 failures from pull/27 * Add map\_method function to managers * Fixes reporting the error when drivers have the same name 0.11 ---- * prep for release 0.11 * Update null log handling for py26 0.10 ---- * prep for 0.10 release * fixed a bug in the test for propagating map exceptions * Fix doc build with Python 2.6.x * Update docstrings for map exception propagation * Formatting fix * Adds ability to propogate exceptions within map 0.9.1 ----- * prep for 0.9.1 release * Include all images from docs in sdist 0.9 --- * prep for 0.9 release * add docs to default tox suite * Remove reliance on distribute * doc cleanup * add reference to test class * finish tutorial section on loading plugins * remove line number references * Add example of loading as a driver * Add tutorial section on creating plugins * add docs about names and namespaces * touch up ceilometer design diagram * add tox env for building docs * Add structure for tutorial * Add PyCon 2013 essay * Update docs for NameDispatchExtensionManager * Clean up autodoc for manager classes * Add ExtensionManager.\_\_getitem\_\_ * Change sort for NamedExtensionManager * Ignore missing extensions in named dispatch * Set up extlinks extension * document new name\_order param in history * Correct argument types in name sort tests * fix type definition of names parameter * optionally sort named extensions * flake8 fixes * Add travis-ci configuration file * add python 3.3 support tag * add python 3.3 setup to tox * link to docs from README 0.8 --- * update settings for 0.8 release * Check the names of plugins before importing them * fix typo in docstring * Let AssertionErrors bubble up 0.7.2 ----- * prep for release 0.7.2 * fix logging support under python 2.6 * Run tests under python 2.6 0.7.1 ----- * Fix logging configuration 0.7 --- * prepare release 0.7 * Cache the entry points discovered within a namespace 0.6 --- * Bump version to 0.6 * Load extensions before checking enabled status * Fix line lengths for pep8 0.5 --- * Prepare for 0.5 release * Add TestExtensionManager 0.4 --- * Add driver property to DriverManager * Prepare release 0.4 * Remove the name argument to extension constructors * fix inheritence hierarchy of DriverManager * Set up logging in enabled module * Log the full exception when plugin load fails * Optimize implementation of NameDispatchExtensionManager * Add response callback to \_invoke\_one\_plugin() * Refactor code for invoking plugins from map() * clean up formatting 0.3 --- * make DriverManager callable * add download link * clean up announcement text * add installation instructions * update history for 0.3 release * add dispatch managers * documentation touch-up 0.2 --- * release 0.2 with docs * finish first draft of documentation * add API documentation * rename loading; add enabling patterns * add diagrams to illustrate the loading patterns * Add descriptions of loading patterns * add script for running sphinx as I edit * add history file 0.1 --- * get the version from setup.py and always use today's date * doc files created by sphinx-quickstart * logging tweak * add DriverManager * add hook manager * break up monolithic module * add EnabledExtensionManager and NamedExtensionManager * add docstring gs * make ExtensionManager iterable * error when no extensions to map() * add map method * basic ExtensionManager implementation * add license * set up tox and fix packaging * create setup.py * Initial commit ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/LICENSE0000664000175000017500000002613600000000000014557 0ustar00zuulzuul00000000000000 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 [yyyy] [name of copyright owner] 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. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8727553 stevedore-3.5.0/PKG-INFO0000664000175000017500000000446400000000000014647 0ustar00zuulzuul00000000000000Metadata-Version: 1.2 Name: stevedore Version: 3.5.0 Summary: Manage dynamic plugins for Python applications Home-page: https://docs.openstack.org/stevedore/latest/ Author: OpenStack Author-email: openstack-discuss@lists.openstack.org License: UNKNOWN Description: =========================================================== stevedore -- Manage dynamic plugins for Python applications =========================================================== .. image:: https://img.shields.io/pypi/v/stevedore.svg :target: https://pypi.org/project/stevedore/ :alt: Latest Version .. image:: https://governance.openstack.org/tc/badges/stevedore.svg :target: https://governance.openstack.org/tc/reference/tags/index.html Python makes loading code dynamically easy, allowing you to configure and extend your application by discovering and loading extensions ("*plugins*") at runtime. Many applications implement their own library for doing this, using ``__import__`` or ``importlib``. stevedore avoids creating yet another extension mechanism by building on top of `setuptools entry points`_. The code for managing entry points tends to be repetitive, though, so stevedore provides manager classes for implementing common patterns for using dynamically loaded extensions. .. _setuptools entry points: http://setuptools.readthedocs.io/en/latest/pkg_resources.html?#entry-points * Free software: Apache license * Documentation: https://docs.openstack.org/stevedore/latest * Source: https://opendev.org/openstack/stevedore * Bugs: https://bugs.launchpad.net/python-stevedore Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: License :: OSI Approved :: Apache Software License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 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: Intended Audience :: Developers Classifier: Environment :: Console Requires-Python: >=3.6 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/README.rst0000664000175000017500000000243400000000000015234 0ustar00zuulzuul00000000000000=========================================================== stevedore -- Manage dynamic plugins for Python applications =========================================================== .. image:: https://img.shields.io/pypi/v/stevedore.svg :target: https://pypi.org/project/stevedore/ :alt: Latest Version .. image:: https://governance.openstack.org/tc/badges/stevedore.svg :target: https://governance.openstack.org/tc/reference/tags/index.html Python makes loading code dynamically easy, allowing you to configure and extend your application by discovering and loading extensions ("*plugins*") at runtime. Many applications implement their own library for doing this, using ``__import__`` or ``importlib``. stevedore avoids creating yet another extension mechanism by building on top of `setuptools entry points`_. The code for managing entry points tends to be repetitive, though, so stevedore provides manager classes for implementing common patterns for using dynamically loaded extensions. .. _setuptools entry points: http://setuptools.readthedocs.io/en/latest/pkg_resources.html?#entry-points * Free software: Apache license * Documentation: https://docs.openstack.org/stevedore/latest * Source: https://opendev.org/openstack/stevedore * Bugs: https://bugs.launchpad.net/python-stevedore ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/bindep.txt0000664000175000017500000000043300000000000015544 0ustar00zuulzuul00000000000000# This is a cross-platform list tracking distribution packages needed for install and tests; # see https://docs.openstack.org/infra/bindep/ for additional information. # graphviz is necessary for documentation build graphviz [!platform:gentoo] media-gfx/graphviz [platform:gentoo] ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8567553 stevedore-3.5.0/doc/0000775000175000017500000000000000000000000014307 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/Makefile0000664000175000017500000001335300000000000015754 0ustar00zuulzuul00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/stevedore.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/stevedore.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/stevedore" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/stevedore" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/requirements.txt0000664000175000017500000000045600000000000017600 0ustar00zuulzuul00000000000000# The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. openstackdocstheme>=2.2.1 # Apache-2.0 reno>=3.1.0 # Apache-2.0 sphinx>=2.0.0,!=2.1.0 # BSD ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8567553 stevedore-3.5.0/doc/source/0000775000175000017500000000000000000000000015607 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/conf.py0000664000175000017500000001010300000000000017101 0ustar00zuulzuul00000000000000# -*- coding: utf-8 -*- # Copyright (C) 2020 Red Hat, Inc. # # 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. # # stevedore documentation build configuration file, created by # sphinx-quickstart on Sun Jul 22 14:01:09 2012. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. # make openstackdocstheme an optional dependency. stevedore is a # low level lib # that is used outside of OpenStack. Not having something OpenStack specific # as build requirement is a good thing. try: import openstackdocstheme # noqa except ImportError: has_openstackdocstheme = False else: has_openstackdocstheme = True # If extensions (or modules to document with autodoc) # are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, # like shown here.sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------- # Add any Sphinx extension module names here, as strings. # They can be extensions coming with Sphinx (named 'sphinx.ext.*') # or your custom ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.graphviz', 'sphinx.ext.extlinks', 'stevedore.sphinxext', ] if has_openstackdocstheme: extensions.append('openstackdocstheme') # openstackdocstheme options openstackdocs_repo_name = 'openstack/stevedore' openstackdocs_auto_name = False openstackdocs_bug_project = 'python-stevedore' openstackdocs_bug_tag = '' # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The master toctree document. master_doc = 'index' # General information about the project. project = u'stevedore' copyright = u'2016, DreamHost' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [] # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'native' # -- Options for HTML output ------------------------------------------ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. if has_openstackdocstheme: html_theme = 'openstackdocs' # Output file base name for HTML help builder. htmlhelp_basename = 'stevedoredoc' # -- Options for LaTeX output ---------------------------------------- latex_elements = {} # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, # documentclass [howto/manual]). latex_documents = [ ( 'index', 'stevedore.tex', u'stevedore Documentation', u'DreamHost', 'manual' ), ] # -- Options for Texinfo output ------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ( 'index', 'stevedore', u'stevedore Documentation', u'DreamHost', 'stevedore', 'One line description of project.', 'Miscellaneous' ), ] extlinks = { 'issue': ('https://github.com/dreamhost/stevedore/issues/%s', 'issue '), } autodoc_default_options = { 'members': None, 'special-members': None, 'show-inheritance': None } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/index.rst0000664000175000017500000000172100000000000017451 0ustar00zuulzuul00000000000000============================================================= stevedore -- Manage Dynamic Plugins for Python Applications ============================================================= Python makes loading code dynamically easy, allowing you to configure and extend your application by discovering and loading extensions ("*plugins*") at runtime. Many applications implement their own library for doing this, using ``__import__`` or :mod:`importlib`. stevedore avoids creating yet another extension mechanism by building on top of `entry points`_. The code for managing entry points tends to be repetitive, though, so stevedore provides manager classes for implementing common patterns for using dynamically loaded extensions. .. toctree:: :glob: :maxdepth: 2 user/index reference/index install/index .. _entry points: https://docs.python.org/3/library/importlib.metadata.html#entry-points .. rubric:: Indices and tables * :ref:`genindex` * :ref:`search` ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8567553 stevedore-3.5.0/doc/source/install/0000775000175000017500000000000000000000000017255 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/install/index.rst0000664000175000017500000000206600000000000021122 0ustar00zuulzuul00000000000000============ Installation ============ Python Versions =============== stevedore is tested under Python 3.6 and 3.7. .. _install-basic: Basic Installation ================== stevedore should be installed into the same site-packages area where the application and extensions are installed (either a virtualenv or the global site-packages). You may need administrative privileges to do that. The easiest way to install it is using pip_:: $ pip install stevedore or:: $ sudo pip install stevedore .. _pip: http://pypi.org/project/pip Download ======== stevedore releases are hosted on PyPI and can be downloaded from: http://pypi.org/project/stevedore Source Code =========== The source is hosted on the OpenStack infrastructure: https://opendev.org/openstack/stevedore/ Entry point inspector ===================== To list entrypoints and registered plugins this tool can be also very useful: https://pypi.org/project/entry_point_inspector Reporting Bugs ============== Please report bugs through the launchpad project: https://launchpad.net/python-stevedore ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8567553 stevedore-3.5.0/doc/source/reference/0000775000175000017500000000000000000000000017545 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/reference/index.rst0000664000175000017500000000173100000000000021410 0ustar00zuulzuul00000000000000=========================== Extension Manager Classes =========================== DriverManager ============= .. autoclass:: stevedore.driver.DriverManager HookManager =========== .. autoclass:: stevedore.hook.HookManager NamedExtensionManager ===================== .. autoclass:: stevedore.named.NamedExtensionManager EnabledExtensionManager ======================= .. autoclass:: stevedore.enabled.EnabledExtensionManager DispatchExtensionManager ======================== .. autoclass:: stevedore.dispatch.DispatchExtensionManager NameDispatchExtensionManager ============================ .. autoclass:: stevedore.dispatch.NameDispatchExtensionManager ExtensionManager ================ .. autoclass:: stevedore.extension.ExtensionManager Extension ========= .. autoclass:: stevedore.extension.Extension :members: :show-inheritance: :no-special-members: TestExtensionManager ==================== .. autoclass:: stevedore.tests.manager.TestExtensionManager ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8567553 stevedore-3.5.0/doc/source/user/0000775000175000017500000000000000000000000016565 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8607552 stevedore-3.5.0/doc/source/user/essays/0000775000175000017500000000000000000000000020074 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/essays/api-enforcement.jpg0000664000175000017500000026762600000000000023675 0ustar00zuulzuul00000000000000JFIFHHExifMM*>F(iNHH02100100http://ns.adobe.com/xap/1.0/ 72 72 Inch Exif Version 2.1 FlashPix Version 1.0 Internal error (unknown value 65535) 1024 768 C     C    O.$ d&!L IbP9tV~bV;>}&vê&*|>޻]H&F>߬oו1yU=wO"vi>{~3Ş7{yZfgwjDk Tϵ{O.mPE !  UHD@$*C< z]| c}?4x}6^zx_?_|<3D [ z>6*[]Wy2ɸ[FҗϹܽ+o==QqN.Gޥ\Θ?Z-_um6ksWrҶiDfjX*j1x}KѬ_]v|'1o?3K:zWm~~|^>gպ|Mz?>js=- V -}[Sozr=8}CFſ'baz}⫶hod_?E*a>c鷝N@_"D~o&Uh>x}}+>ZܚNd&؞4@ż/:B?mݞۥ>{q:yqyO|wy[F4~[}\s}-¬fGm=_OteeKӽ'p{C/;9}>r;lUt|ǔy]g}/G¿߄ /z}89>/8z6~EM߱=hyA٧ .~>/[=ۿѺ߉] +}?|}>A>aOj^O>]IgzBXk]*1#_=r=/Mo9ݤcmxIr[;M1?0ɜ]^Gϣ_瀄 |m5o1y[{<=O͐/o#|43D [(;wjzy"cNh~n.~>/[=ۻѺ牸] MX]â9=O]oԽ?Fϲw%ޤ3'ݿ9ݦuUoLt|{z^s>/[=ۻ|/;>T7g?{|mϵ9t}ϱ|Cr G>uڼU7)"|ף}@B~Km9+wvޅZΞ_1qƸ/Mtּ6$qWN28 N/ߺ|g_|%tyʍn_]&;6 Z7VFPǻ 4]1L}y?Y˯{e.  @&A, D!K%$ I A%ldJIMI$&$A$XhY,Fo #HLVuߟ-Ky{k+Ο:&D!_)@%{"$|Zh;>@|N|%싏kgG]p5;ץE^{.?@ŭdMwó^mP yȸty5'ϳPz_)_@%{"$|ZDx;>@|N|%싏Ity5'ϳTH ^mP yȸ)x3:S IAd`%~R@Z>ͧ5c.GŕoPŭdMwñ}?YVoXSo@XtxivqS}ou-Mӷ7&[7V˰XukÛ:WWU2듚SzVB4ߚ;nNw9=^_]n*]&fs;ץE^{.?@E3gDc{ӎY7Wƙ}GEg疳0]'Kd:oRxt/jŭdMwñX{?Nf?W}'ͬZt=o>b~o}_KKGr_w};dz+/;gs{ztzwagIv|f6zworWr{s摱}Z^ڗgzo^mP yȸɶ|;/K<-=~b ry'S}g=6]|KOW7 |.דޅn?xzJ|ZDx;_Kz?;=u5>ikǫ5p8?}?<봗skwɝ3?g~m;<2]jW4J|k߾oZ7ߝ;sӴoyDz-{n"4üzSzץE^{.?@[wx6]y\|m9uU9TC]^E7b_82nfŶ08~%s]j}%Cj͡{bty5'z?1-|K4ך~5uձֺJ7JėG~g'?~NI-yc2oGe[N|T߫ɤq ,[p~krTf[~n M/eۚ{;Vd>&=MJ/= $|!1cYBe.!H'L³@[:<ȚbH–\Ij@o B4E@_ODJAH\B%$JE~$JVSTKv(d\D@ $Ώ2&j$޽//?q>-l"kNf>'zShK|EH̉8v}MJ/= Ώ2&jwK6(d\D[:<Țg٨޽//?q-lbkNmP"wK6(ٿ q>$-v|nQ:VB  יnjG%QzDv +<9)wJJ("S9@i椀 E%)(LsÚ%x%3jH]RJ/HP:ZG<9 QwJJ("S9@i椀 E%)(L,I&Ba[jH]RJ/HPTI{Az5n-#Ԑ(ĥ%^)2^?j{ >n"NƐpQ_4>Ͽ'^_ jH]RJ/HP/Xeyٽd':uGSIrST=;,1< 77-e~D't6ma,>2WjQ)|.JFvnhMm E%)(L,V&!2aYH &$" jHB$UVV'g;ȺjD$\'7y<ՂQwJJ("S9@I:ZG<9 ؀ $@L +J%x%39MyM3Έ:ZG<9 %o=HI R&\{;e;JRP E$^ATXjH<+t+~P"I՝{LJ.)I@%Jg(c_>Luiz9@ sÚy} IV{:ae= %08@(ĥ%^)Uzlco+&ӗ4nE\ޗwl5惝SKH5$ir__y~wX:ZG<9 M ҈`ΙЙZ3_Sxgm7p\઺vqoΠ]RJ/HPES?u~oO\Q{lTcni椀%Egׂ-+ѴθZ\5ONYߧcy=3)= (ĥ%^)%.v`H HDKH5$ RQ),ADQzDrLP1䊄H,TYEo>QtxsR@Lv}ǖ?WеgWwx~SN<4R+soKP-#ԐVx /_6^ax;'JW{L8k-'ç_9(ĥ%^) 4)vnڑq$ӕ/78}-#Ԑ8~e+!g:~Q:D|Z;4d%x%3 :aZPIT$9IdU$:ӧeӚEQ (ĥ%^)" ޳ ~E $B^!$J!i@$_9QҋfjH$QwJJ("S9@Sq*]c4}kUˮ2-p%af=Z7ViynGMj3ӍvvaY9 _2^# :=<KH5$J.)I@%Jg( V>7O^n_zlҺ9~7k7GUuW=Uך=;G9 ƑmVOOS}|k7Gw:KH5$J.)I@%Jg(kWE~g'ߜU7?Ӕ~g&Q%\l=W̾8o_*5(77z咍tXcdJn?*̈@&!FGf?R O,B҅\he^Y`)lhQ&;zla8k&FZə k(2bs9yQ]ɤr>L&#OLNy+g5p,VGЉ.%.h@sn m`o1#'Rce%Gɤ\]Z##C^w>O=`ؙoN1%y(?:Zk0=AJx92\\G06L{I^wY9ux{wXfVSQ9QCdP@;_a R9;Cp,ZD+Drܤx!\=7O=;fםci& 3-8"T) +9 4fsKp8|8;fM~p~:40rcK+dTU8gǗ>~QcaW::)vJCldR& O.ڭ^[/^rˇ\4Sa QxldRE} laܸue\qBڛ\'mhI C)RQJ R!62)v=k ; j1RMx\%Swـf#\UPhtld|*N٦t䯦vqJAtѽW\1䚯"LH"c쪯bŇ13yd~OT, q - n@ I2"#OAFmrCmzpJậU!\&s"#ϙ]^wS,>|TO2ɮ:y)XO'2-,eQ5TĢÒ{ ΅&(Yd-AE0Is5I&kc#/|\F&_l,]D&iw}dk . *SӬDH­ˆË9FaB"2ʞ[򵏾/IɛATĢÒ{ &,촊AY?mQn+n`]gp% cr̊RsI+;LeѴUBE x{RЈ]D8-Bkl#yꜪ7r'MdW16ZDݲ+mzgf+AN#a lEbeیJ_|[~ak5HZ* `a3S*bHݬ) ]B2YEN1//m39*;0{c6̏)z"-'f m-3} ߲yۣ2c7~{٘lL%\X_E1gZ5%s!q{@M=j L2|;iGS`&Y #˟q\52ZL=p&  U2Y ,ZJٮSN&pC{=[yۣY~+]%'. QͲm#2B7qUX:o6D9wI8ic)9vQM\&āSbq,p&nbUF@r!b%Q*L85@Y2ӭ;tz>@cb$/Y1s$8_$0V2ӭ;tz?1is, E'; ;.<4ND7poFF߸}mR)1/$%edm:9icN&| L" B|fP(WŽs$ VdnZ;tz ,CVqcr;^Z,2"eR. G8F4ظ9Ϳ4{SM#hv+{^8.Ra g&\ke0P٥ VnG/9?uXq'Qe HB>դ51m(Z:Idb Rsդ#2LyA-"@\mvVc$(\3QLIVmHֲCLT4#īiF& 嬊GqۼuC.2Cdv\paIͿ4{kIKn>AUdгYR.s1v ;cNY~U6L}QNmR$XO;tz>q1/rJ،.,5?4{SR: (a"Ѩ73*N0by'mGJ*R7-xPR.\[!^v}p_Mԛ ( F^hvk~l`;;T (GN?`\ԙpiE}-ۄ=1[ڛ:*~PK+o<]+Dަt/!z[.5q# '/:srCAl*dN0Yୗڥl )rqI8sbnZE`ԁfbdUfGɘh!6SM?ڐ8C,S/$2c0T̅SifBl-e-VB% r&hcRh鷳4{B-_ 0G) x8&K$,p1^)wpݤgaYyۣX%ƓdܝbYFmla;ea=$MڤRE,f'Z~?8wƝoh `7X}ea(]vC ?P^39y #s@IM$,ͤGټ,p9b ˛eÐ\a>k?op*j%%f%9$F|xA)Z^ӭ<=jT[pٛvv@K5Ֆ(2nszڭAM "_<;L-0BW/U襞5- acnA}/:ؘFf*-JπyۣjI?v:O 0ii)DQ)B0]MSI[NznG/:ܹ95xU&bT8L5ų8"J@Ib$A7R@ܜׁyIۖH备:I1pLI&Dn#(0.p[\ZuنA4Ƣl˷"8{%##@cF'9r[_us&mI)x:$ղl۷1sV38f7yʵtRnF*`R$YF0udM'cl_BKLTF80gjIۙNف"c+_Gr/r묺TWE&b h91Co;tz?1iB-1QHvaJ42,"ByhPE#i}VJUW9L&), *&(Db }6[k&FO.QeeHؼj(mqg>Gߠa5dUv\1nG/:يOcb qd<1[v~bӭ;tz?1i=4|_uanG/:0GƝoyۣfWu\p:UWu\p:UWu\p:UWu\p:UWu\p:UWu\p:UWu\p:Uz.ۇu\p:UWu\p:UWu\p:UWu\p:UWu\p:UWu\p:UWu\p:UU+o7!1R"23@A0BPQ #4`a$bDqr?v`e[-I ubW?u`BeSq۰Tpqb\_a4&dw!]*oC \UT*Ӯ\,cbaU1;{,3ī'0l.yT&?s0ʮtRe*n]`;2܅Oc5>Wn`D+#`!xUw-{7[+]wi6C^ôj"%F A2AX\N"˕r*Xg4lwyYbVT48nQԵ)γ+"|YZ6Ɍ1a96}h p-D1&V .eATG9G$U-U]a.fF(gm@F?Q"Q 6Upe+i,j*^sMOc^;qZl,Bw1G%Q)MRUAJX-UK <:8XV%نxUWs_Ovt7CWzꮯ칛 >*Ĭ3BˀA5+ $`tM(x1U9֪ A5U%9aeWG+q * NئhrY9ٝ~ѨTu]T6fQO}ʫ49 O袩t1;\ѿSX&mܪ8CEK0UB`lW^(' -*LG6IKe-`URqu쎪)IL*8=c\q0EQS}mPCeI7UuBpT]uYT& AXģGT:}NnenH'jtDL)1+,nݑjٿnSI[+rdjEVWWZkkDE[:+vBhP Dp@ BepKCN=/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\>㺪! wE\/r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/\r~W/*k:ܭVUjZVUjZVUjZVUjZVUjZVUjZVUjuTojZVUjZVUjZVUjZVUjZVUjZVUjZVUV$o?~{!ʛ %'Ǻb^~{!ʛ %'Ǻb^~{!ʛ %'Ǻb^~]!;Fg;&epi quU~Ô!f! jB 7 }M26"% A wB𫒼+RVbeMK Rbɠ 5_jsK( WtvKTq VLiTsCes/1klR8ꉸZ9T2+d@4Z[NlfWhC)]1/??_6s Fv_{'U.T1rd`^:eة*b[j*0K/:=:*i?iڪ :" )!V@#5|:8:-9ѬNw\DxnaR?⧼ES ;G;UN{b^~BX T؃eo Us%PEXwqMm+ T摩bGxU,<(T1MUĪqkX~Q;-Q{Se)UCW2PL*^ؙu af*o(/R1*6I{lUt8E8%MU1aQzUtT70*1fb{3eC&*T t썻z16Te}It75e?yMIFV4T+OSM$Yo*XiʣRa]8Snl%SpnȰfr)S7 PfoROTD罊6 J3D"h9b^~Ra 1uʨkUp`<rYJfx))((zeSBC yܨ)D1*:/~bUdꒋn{j); #biD!2:3I'P `!;xت*>U4`TXi{iLn.+e{[6RB`"7>3 U 7̯5~bUM~a;(2KGh Se(\kza+,bLTЉ5ܪ88 ^KOV[e/M-Hfd5[G!ʛ C@n͖xQ&QЧm4GUk-@t][oe+tMe~uV4 N v[^茽pr~y7 *o(/pr~y7 *o(/pr~y7 b^ ܆!>% \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #ī+!+(+!k|KAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԹKAԆ!٢+YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYD]lVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ~G8G~}%n bPplæ =!/0SI*V&F_{K=(G8G)%6UNZWj4jm$f{xz&$5|,%GRH<(%sJfb=G8Gg, ¨gGj9/>J^R僋TF!,N Fw&L4NѨ{h =Y I9Nm2}G8GRPtC(,UMnݎRaQæ}U!UM>\*Wq7M]ʭ6Vf9PJU<*TRgQ Fm{ٲ3Wy=KrըTM@sT>VNꀜEE.n\BFTlũ9fĢwFWYF:3doJvu{!B?6".o~+___Մ} u guM\&JNm4W (lٝU1u * )YLfeSGnB!~G8CxsVTxR'&Ks1;I uC-i:Gl)_OcC0I3(mpTPJ=TO˖IUoGW=@VRw? ûN?x&PݗrT:Vh͚(,hPwot[xVQ2/)ą!xr]P싗nѻPò{'u xRQSj M 6Kn*U du>#|dǹaKN*`rU6c+s0ܨͪHU3;B{xb͙jFU[/oBGj[&ʞQS:USB.f*]M7 uÃYrkUE/WJ"Up*HE=ʘI CMRjN!L@*TlyU~Wn3 ,1uIb:ʶ>#}1^E~|T6X$1'WQ1Q84تYfTA*fk Zfޚc8*3|~#Ab22 rpRsv-I Am%GKzrs UJx$8.7Nշ;paIN6kx FgiiUZ;T:w& 65*V s>[4Ra!ʤCvAӆ3{zU|>ZV}ׇeTu Q>0>~h 6~ːm7Eds;^X{*yx]Ppa۩RB7^i_+34]/eTDR(7W7W+ĭ-_'}W7o{[3Մ},Ql d'R6v1*B?4fdP y[2S잇"DGѝ:fw{er}XGҿ=2eS49&ݑ3 _ƴHJe45¦\e5, ؝K*ZFx\.𤣉¤22Y;M TtꤎJ).STV07,#҄~}-H,Tg]S~d3fQpU=& yiZ ʖL*i #R>yCq:}TNETcuM<' UBgYIW %jef\@8dhԌ[UKVn|E+;i8f (E?]krj3Q^βW+OS'veSR~f#[}7^%tHsugq8{Z=.[nZˢZ֫1k{R9PZt #u;3W\A!I:YeorEپ kR/e!KMPa7 C\.p*yYO %g5Fd'ke$y*Uc?yU9d6@ ¦7&aeltY?e *xB+S:C,03*ȉ(Nؤ"ʧ[RaQӉ|['V@pUM~Nv|YVݚ+X-NkZ*(LGlR3 #1 ;6SC:E#2  B<0_Gݒ%e*k5DB>i5:h;pBnʢG8 OǜGXi.J3T׆l;abۺIʴ9uL̃SszI"pKDJzGEle&p9ѣ߰}Lxm{Q$?y6[Q=272j$«/uWk,<s-V f°&|eaH5*Og 9'v*3Za5N}ν)Z8)jLX,@F^DƪwXPZwFgw,8]t#ԺP!{ZPwuR:VY]W;9T9SjNڠeaH4*hm=?]ʧJv鑡T~;VAV; GvP.UWTUtr FFan-L<n;ʏs\#3Y ;tW/ sor2n!)!릸w>_n5kh7s ss|rNPB>Ȩ1l[Ӳ].=Gj,kk;_te[#GE \y2g A[kebu:N ګEp!FHd]tu`(.Wl2l?,vU[> eGj~3IQBe"e'*\S8qfͪ& rn< ۛ);*ew;p*:WwOkZn5СGKw%%eʚ&L$iCuQgia,JA=W XV8shGċPtڻ@HڕWYIIaD޲,BBr ,{:+(?*J3J9W [BQ mgd4^.U|TNUP%J+}uQg銤&J*{WD#/TSeP8UIts RF~Y ^.5|XvsԲ$?,##vG*ڞ3B`bu 7@(M e D )df2|ԓu["GS;LF"}bĐW_[^UA!etbfh\edd~FGIl9*05'f_<#ZlsE搤y-}M?5$9QyY-p?IY 2GR1=.xя%MF,gO\1eL7KUm ȻHɍb ;ri)b]KYfO^Hq09mm3 &1b+#|,\R6_r< ${؃mLiَZ+ q"02$&vw ?Fyx(2]IHiyd?cKbg$bG(S]:]gv>Nq<;7cFe^;E9礄7licOÉ13W|ܟ۫c`O]}D1? dǴmTlKW"H3cJ"|ajtĐ؋,cǨ(:^na]|1fuGr8% #b$,2|m:fi EL''^xW2{v pO X3IDž )RgcU;'Ą6=+/|l.O󐖲Ә˓LDX̮DS!)_&H̒]z3"Sxƽ6Ki"d`rr}ԇBlϏZWTc}ɪ 3V݊RAIY_l} ?z2xe5$WrG3m&ǏSy. Pgfy;t,2g3#3=F b)z⼱fFY܌5D:2NfL˓R1΅3Y&,hnW`O<*715:'2˚yhYeɫdYY<г#.[1%~B$Seٗ%ŒSeɨÖ2]522eq6F9ic̉DrмB2bČ5۫⽇% *%g8Trw;>ءr>J%dU!wά򣰕4vEyWYUQػww;Yܫ4U凷W|ܟ۫c`O_10w'p;8{u|W~='?F0冡`fCc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 *dX3c!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62u"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r,"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\E̡e _0P e _0P e _0!"au_";єn/]Wㅕпj.{%Z?ֺ˪DD%}7ߒDBhbɐ==&_U jYu_SFL#,t,*hG"n ɽ#H5H*d\#2G{$1tp#_%7)i"율sܓI29dB"ԣf< ;#5('=JŚTvo:!x&gWeĄ+ٟiqȫ mp 3?.S2GDN3EC/h.S/c h5Rf:y)"2 m"|JWQ>>+:E]~ ^T2]ʽmzEǗ苹דCh70R2cw.cxW$lƌvLc(3C+M}+!fc|_M7>zfgds!yQh빊\62EƙUDq;aȢd$Or?3}DAdZYPI/RbYDy1Ge)(ěd}S%J\Y23HSLdqF8zHBG"*fՎm:Qhj"1UHBo!ݷ^HoCr+5= ^ ^վRBRYi\ȽEW u:?.cʒ1ej^Z"^MeC*#;*mNTeDWMt?JDED'LȪcUG؂N2ƢNz"rK]WJƐםt){T1{2 /*Pneb>u˪J?BW%/Wʅ-cb}IK2Llfi'!K1ͼY|NY)Цc̓d^ΣfY?ٙ'/Ml=rNzHIQ _0Oɑ2KrvKr(b̩NhJN05yBs(j~s=120Ghk!4-V?Qq\CWraȯS(jyȆb}F#ӎq"ӛQd.6ONȹ2.44aIaURֈvcfr'FEъ:beIi0CJ2G['HlO\LqpkDm4WQ _0`WY(bB(b2/]W(b2/]W(b2/]W(b_0S !12A"34Qaqr#0@BPsR Cb$S5ctT`?y$pAҭSHa,-VTPQ_4mjS2ǚ8_WB;j#-.ڮRw-/qa(\@UWKsH6_94lri[2iKvꌹGOO(A)KO?0%ip)m6dRnk/GqjNdSZ6n{0rI4k )ͭ!\xC~#TL+@V_M<+ei&&Ѕ":y-g"Oſ6.RV Fo0aŪ ;J!)I1M-oj ſ6+ek1P? Db@^B 1:΃]™С5E:Tm8P}d·!9T@"ʧRO줨|vm~e.nI'p*ܿ=z?~YJsROWN M]7cr[ 0ˢEilJCU(sB@8{)$\;1'Q=Cb1fw}Lûba;{ڭ~ϿR9ב-Q'HL+IWT-TᜪIi|kX+m#)WޕU+Ocyw6?ZZENk%^~%;Ǟ-ӹRa#h̺Z(ƙ[WT C qW\Ʌ`%اrטAD%2uC]8e-bMPM#D8J1U_&tm0KQN9%2*dg~1=ie)(V{K*]X ne#zVT$[!xtkJꍯ,+(:9-V G)$(I'`;eoA? )5٪cxM.۩M[Yʡb/0ȥߏ.rcuƹakKmp0s*eͥPmLxiZTKƕV-J횡ąa^^#]혓( Ңg3ǂp~;ԝv'…9G*A%?qݝqJ] )0m[NrXQԨ#XP3EuRws cqO!>[ j5?xw0JxDPBK߿JӎQÉpďG7&Ҽ"Cߣ&/i&K g8N쌿?.Qz~0 ;'/%WW{f$ F,NZҴ$eFmNemI8(vG(vG(vCsNАZ46 m+Kup)C:ao*JFIG8) ]Hq%M٣j$֣tn%EZ\pi J H"؊1̡s5y̳vrw70X yHSD- < ms91&ߙJF-x5"EAD-{T@:iy'֔bPY(Jff`L*E!D 2!e@fL E!D  }RTݚ6Mj9F.U(8Yu JLph>eU)=Q2 q DzXE~]Mh)gKN%F5+MpeLڙy @3S |%Gqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr>u.ڗk iNx=vG)Ӳ9Ov{Sݧdr;#iN=vG)Ӳ9Ov{Sݧdr;#iN=vG)Ӳ9Ov{Sݧdr;#iN=vG)Ӳ9Ov{Sݧdr;#iN=vG)Ӳ9Ov{Sݧdr;#iN=vG)Ӳ9Ov{Sݧdr;#iN=vG)Ӳ9Ov{Sݧdr;#wiNaڭTXHODL!)Q{Sݧdr;#iN=vG)Ӳ9Ov{Sݧdr;#iN=vG)Ӳ9Ov{Sݧdr;#iN=vG)Ӳ9Ov{Sݧdr;#iN=vG)Ӳ9Ov{Sݧdr;#iN=vG)Ӳ9Ov{Sݧdr;#iN=vG)Ӳ9Ov{Sݧdr;#iN=vG*Ӳ9Ov\^1a&o;+soUW?H󲽧>ٕI|e^#{fW}&'={;+s_UW?H󲽧>ٕI|e^#yK(%"a O# %9?hviVT}T T*ԟ. 1"i(lm ts|7-$JڳJ@D08+ b]ȑ*%3 #@07,n|ͳ,%RV޴3E#,^Z Au% Uq;(V*0_vEĶ|Th S8*}DPl)lע%svVSm8==(bil\0Z/8)-J86W̓\7.JW!_#U'm36FZ4VM~ыeo,e2F5%)*1qrGq^HJ@:uB&B7a5Ie uOW2`-)A|)Y~'L`?LbY[lzIa)*1I-M$&UR0tZz(V::$@SESV융* ^| :jtn1_?G52U]a\埅Yb~qM( D˔TK)ɲ T+}yhפ/$QT 1,Ლ쓉k)<ë,N0mNٳ] Wl$ΰ>*eQbA~ͩ+ ~ \ az- Qeo/- * vW/^|/?JI?(VCR-ҕ`'.2۪4CR5-)ןoIH8H*YOJaZxҠ`_2^pkB\'g$,K3~~0\gޥ$ӛ Qef%PBlȲ^kB7ĥ.W4(qRGW'U"$Pc8̼PIfyĹŔҕ`B(9kl͔ڻ0gغ'"AM6E%:m&&%dV$Yedp YrDӳ.aNoo_weݞF2U-pfo抲ЕVL`3+>p6mY4KE塞o8.E9:lZ<]4(\4F_ZSI@&2 0nBV@ l)431 ДTY~~k%~q#E\B ⢽Y70uѯDISi[ߡ{ 1$N[Kyp)a'3bx7f}&IĻ BT4RhfZu4XpkH)C"Rz2CL ]@I?vw;sR}yzɮC݄xFi%o"IFXjrg|˾ :&b])V'Pp]S'T%אҫ@%!`ELϽKkKeT:I6A J:ٱpE@vh=2UlXeSu$!,ڦY!(i M^-(@[)ҨjBn͗I(=T"g ?BাI*IHGLKoЗ ȪGF TԶUCsd0ģY\7XdQ^AvWϻf´Z Ƞs S fPh), *~mL n*2V\?I*^eqqe'֩tc5mKp$+<# u L4hKwU,*:~S5jd%g+J*Ji"/)\"SŻHP5Qj+Կ`U)(a# eXٷK;{E]6 pmMP!61 KwpExQ>ƴӭ`ʌ-7bs/;_ >XZ0Ma< S L/Lw)*(cG1Nbؔ (]#$ayZP{5]#hᤳBZV~zVML%hI$ iu7#dgyrJp$cU~MGq.!AI~b=b^Vĵ%,'%kb)_D%rXZV[vX=1jڜʵR'[sڨ5 9JZ+9&-fsE]] m֑/,[ Zi?$-/R lOx!N;6kaMk'yb!lSK.XNJ,hRN_D%rXZV[velԢu/7 ߘ!.8B@"BVЖAYIdܒDܲkJ*ʯ?KqU9d%arJ&Qκ^'"Ż5 Ż_:fKmkdS%"^h#YX]ҽLmeݛvx27(MB-Y)<92ARr' m32JkyCn2͐щys%*mNa0Ȓ8[X4q(i09g|6)fŪ p3()#&PZ9q!eDmVݢrAmfPViCb`(r=|طK!-?|~e{N}+QʽG9̯LN{G*vW219ly^ӟolo_}|~e{N}+QʽG9̯LN{G*vW219lywX ]9Nv&97xɻM'lrn;cwNv&97xɻM'lrn;cwNv&97xɻM'lrn;cwNv&97xɻM'lrn;cwNv&97xɻM'lrn;cwNv&97xɻM'lrn;cwNv&97xɻM'lr^;abiSm'=12%!nI6Ӓq{M'lrn;cwNv&97xɻM'lrn;cwNv&97xɻM'lrn;cwNv&97xɻM'lrn;cwNv&97xɻM'lrn;cwNv&97xɻM'lrn;cwNv&97xɻM'lrn;cwNv&97x[F-eҪT9HW Lf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'Tf'T*B8  )v;1;>of;[}Gg-|koWeϝml\#>vc+v}gvep϶[َDC)VXxWCt"Z][戲.O22j*BZ8 u"#eE@ ᩆBGg-|koK1(]`XXfYVhZ֠`^B xpiiq"j [y +U+ހV DZ ;ߺ1, Vu9ᵾ G6֚^eUkѓdMQC>\v/%^P}p϶[َDa0qCJut Fm)x,/#"WKəΡ@Co=KݶEP.JEijA&$HqT亍l.X2.EF.˘qX aXr)󻚢???ôrr5'B?mgD~_DҔʓ]z)(p-z'eϝmI}&%S3m%4p![+y1{c-?, /d^4oz* %4[d:Nm%QØ iHKrgE lĶE2uocSa[=:(:(a?,m.YHS:Bm! :Ŧ[EkMz=p϶[َDe @q!Be%$PB fipr2Yо,rEDÎk#ʲ:oWj-ukxKݭ-k,L28_bi5FJ@nɰU)IKh.};1veP!Pu1(J_M\#>vcfSMr\!R(C۳]{M \Zt6IʹⱄL%ĚBL̠-ZY!R-EBq5;>w{!mZW*e%j |KL!9aljTkk!J.csy>vc_/ K)XwMP?t@WJ?hD䉉jhL6 *0T2Z14Ȥ*OLMҫ5olCjFiTIP4O酴V˨M[:ViCHCζba6!A&|04q6-c%$U0p!iJ W6_[>UDqiWdv,ZxN&rJtýčn-&ih͌Jm0ȇ}nSKZP0Jʝ!)5Tl]O0q2Ю]Sr[5CL6( -̸.V+ iV喫]?KآzȾU:) e@\Q ^jp Rdp] iF7$#nerYJ,\iq q6h ys@DTڲSLˮ`$ЮGۨmQ%qUl]ê5q>M}cη=!~~X&^%\]#TH kXkMXû/&y$[[OB**H9+k,O4L d*ahhi!,y?&UJ0N+k$aæOTJ6 jL4R] 8)^Ѳ?i;K pϝ?IpJ20N&u E> Д9]*y[%˖Mq#8$5'咉(XqIKS 6stOFf=4M56i$"" }Q:dfhPhd Ѐ$R7P qftܡHu8*k6 Er<lK#G ,o„F hNL6G "$p]N$RNX­#m] \M2D1=Vw%8B}O144k|koΡ +ZP H7C}QxIb]_!J-$T7/"օSLoG0k ENEŊ!ReQo0HY6T D;.c)035 Bԉ ҂/0%',] D4]bY+J&Neqǂ[iI*$ҡB"Y,0V]KiNkm MCI0e%FSHaR 6UKHa[K\GgcbՋ8;pTn-'fEaBh73r6APlJ77t}zbY>])vX` EgXfs0c'-+L0N.G׭&+4hiam/eQ$im(W]r6R+0 `-ƚa%r$&aS(U.H'աF*]MEiJe&[vHX&2vQJ$ӒQ $}2r8-I THq% KI*"0mݕbm`hꦘ^ p1#MHH :XY(POof;[}Gg\7/9 To)brOɭ Mu~< H{}>u82e6BEof;[}Gg-|ko=!):m(tHJюVKamZ 83.7Ǔ+@OuD-|Bҫ") v|6B{Ő,cT/Ij֘Tr@?ڢ^9[!L$pRk>c{˺$qMڹrO*&/(?0e&+,mRѓ,K% UkSK-R^QKTy;\H|ko~ɛcqW15v+_ %n@@7//yCԄ>Ѣ 15#.&HQCiN $n˹@flK &qVږU8V2|!$Z!h[rBSAʿ>$̸Q`_GO.KE7_-v<)R$^zdss SÄS`\:)6VJB+!VIT`!l'.1NEnM>f</8O&zov)Fތ4ۺӄIa3mXQPtBfsXGŒ)}8I[N8sN\IHgbެ' FZ%ϨJSD:ILTDUJHO?LariǓNdy~a- )[nI547ٮAM&İq"4eӎ0'&ZBdPpGM2CsM:DNIW0dn8,-UCD +tLM)fiAvHKtkyؤ׮GgHu/ _h]8E`W6-󉗙C22R9SDN"}zlOJ~o>DLxWWSeW IPC'Ӿ1R RhÒeù>î.M|Lch=.nJymr,EBo i7mC/}&Qp+Sw0˘)S€5UUJs f9J JY\^*ZE/'`72J }a+5yf,OȼdSHVeݍk}bÏAU=!pϤ'H7a OBTv{Wh0ܳw+'7[TV. #u(qеfJN\#en-z4TGyvK͇ Zϝmd!ceDe!un8MgqqP6~RҬ:RBTt\aꚬkv}gPuDKTc0|ɼ4FH8/Bꌠģ3XtRmH}gv1Ym!P}l7zRWDԲȣ+RfŽev,~jGfe"&t;hcjshcM^@Rzip㲬@tO̸>T$ҦD.ioJo +}G?du.7zJi8)~O:pp[qd=>GgzcrImܥڧ#- R U+̴^N]_9W/>0ڱ&XMaeY@./05./*vY+\V /ʟJtq_bҍ>5?0.+"& SK]x\.Hv]9a8Qi s.UUcNΩ l Axuxgv4I-: PʛÅXZ]1AeP Y&8ٲVIR0O{Di~3ᅣF&0gL8nmvBp!8uYЗ"ғ˄v}g?P[zq [3 ІMXZa6XBbFjGT`^J`W~橧%rbiquU&/!(1m6٧EkZF=MRҀJf>p/&}3֟BbҒt ^m(NX`AB|kob#/1q6D .08 8R0TJ7c\51/61E v]d8S\*qMJȭ[2qIZaDÌ-0K5 W u٠ 9V1VЩgM9Wї^* cwʐB@/)Į\!P[d[fncZmz2R:RvaU&&[[dP_[uRYYwtB}JʕAR]lT(]ٮrW ǧըйW҅ҥaVb,c\'(d5 M4–@ xz#};1PQjE!lcn՛:`.};1:) jt%hPZ*P|ݶm֕mACҦp, Ih Ck}K++50k$*Ui\#苄v}.isS+CR͵1iYI)+}A^js.:"M^laM;!RRI&BB,eo_]&\ymaH*ai4!u+H1370jPTfCvwB]Z%ӕJ1e(t~$*m<# =ϝmWړw0WR)J!jNʠs&v8ApRsiJ2$*JJS)whIО H JPO@?x\qeBƤNWkC)eM2RE6;_"&+m'0WDY Bov}pϡ&M[75:$!@0R> =%,YBxMx6Yeoi$::i@ -z&U闵Ames ^0W4UZt³T]$uedЭ*0tԺCo-UUEvcMsj7#u.pd/QZ2 ҷk Cl2 YUjt Qmcy+xA—fOƱW*PN^pBR:"kĆZR&xF>Ҁ'ߠ)?xIoz w%k@b$e>4hRȼ'.};1iYII&۰!$D#>&͒_Svti#ht]ɹtLI<`%XAJ۸zt[n,6sMxo>,Օ?mp]Q'hMIaVrjk6| -}v_ -- kI#Ha3ͤ.˔Xo*bJ ~bmH4N&XlZpsk'ü'6DhRKlfQiZW ]zaUtR0{HsN_ p&(x7I]{!%-BYmRze*9I8:E6ꊱ XMxxMkC `)]Cmx=BhH2˴(@RWOG\#>vcدLRiତ<2L6kuŔ(&ҒP)P+v}gvep϶[َl};1;>of;[}Gg-|koWeϝml\#>ue HcLq11&8bcLq11&8bcLq11&8bcLq11&8bcLq11&8bcLq11&8bcLq11&8b`$E&8bcLq11&8bcLq11&8bcLq11&8bcLq11&8bcLq11&8bcLq11&8bcLq10AT,!1AQaq0@P `?!:PMIe4:[2&؟r/!–))آ\mētPØBWmjE2.w&mԴ@EV;#w%˙,]^1q)qH. 35^ DqStI־vo}nK ䷋ #{?혂&AsmlIe7+W"ř㒈,aF5G'@XrQ7#Se>⩌* 6&mݯ_/5E  R4 A08MYjTj"x# -^6P5n {4,'8|mKp dL" yb(S>QvZbMo3_$ ձL 5dLa (K42d@eT2yQDH ԱTP$6/`"T7ZCr+:W|n`E<(hAlQ.}Q􈠒#"x-7zMԖ,ެ&jaFq>NyM)\شl=G<=Utf4>a0@ J 4R]€}}v^,fe*ҭ>sb`ā%jYCբ@~%f̨!:YꐋYX  8֒Z13+yF}f Ă{y:\<ƕ ak/42Lm]I>r2& VD7xC)G RkC0( `&6ԫQۺ0l6(p[SW/ xroS^䦚 Q-n6ylZ& [ ŝʏ"f$?De}Lq dz4+cn!qA7:myH \vLJII s)aA `ZNdvx >jF, amnpKf#tLzM:ᔕ{&.ta9X1a,#( WJgWZIA@Yv6 Iaޭ(.=E}t]S/B'L|>vo}~2,Lea+>k>j0x\^ 1; RġQNAiS#94z:7EլhaI,𬙢Vݮ'!RѪDxP@Ҥa$Ob}m{RYVI9O~ l \DShFƥdM׳'7k~\JbFvR>FߥbR&&XOks2<˰Wء&,~xq#gpxc[c&Pi9Pg$t8ߕp>6Oc}^< 6r^Ad&㝟b,hzuKJi {H o 9l+(X^֌Rx4es yAk1dD)Kxdx40bC "=$l,'.z6Tn_t蒈 ` SYnrƧAXI7A}B7h d{lHJyl?}W kx\L0T؆A 㠔 J6y' ޭhyDt:[ 5yIOb<ʡL\м 3 l1KpSix tW"Ԥd!bOAJ j6vGIO(mҎ2O >,j2!4mw$ 3KCRLq"V[*#"JTwcKpA`X ⷤ$^ мT.ڐX{x \$4oSN8g͠!I' ^T!ȏ*DD@i _iL1iiiiiiiiiiiiiIPf2( e-4M4M4M4M4M4M4M4M4M4M4M4M4M4Pb W#ڈ6;j#ڈ6I,f0yvR},O2I0]#*a'%g\wmcoZ99u6^9I&d=ǁ-|zaio}bC֒k8&BW9(BNfRۂJ:Zᒗ!,(cVoFC]ͨhi0ccHq \relJt |ݡF\R~ +R-Y"ɜMMdX 3c\ANnEZM Z1]'>I(c ޥEkQNթE}ܞx%=*]Kie NIMAM57yQX`I,SJyXάN|@l|W-h$d` oJJu( `Ԛʒ %OD/43nY1<"RZ09v 6j*r8bll톕dwQYWȑV&h #،8x hq'8WΜC'Wg- G ؎b+]Th )ݻ{sWrNp )1Z4.^(UXTM85 m*0tAԱ6AI`б7VA,Q$BAD̢CB-0őf†}Sg7q^cVp13I84BҎb=Ro'Ej< h Xٛ!0RXآHX abKC$Mɉi)YB8F/ ZɎMЪm>``$*j{G7:\ fG&)Tͮ ̖6xg]QQf8@CPB8I13k;)&З}lLeʁ{FΧ%.7[<3UPС)0WpǃQh$pnJ>ݫ`N#$HAj,P2/3K\74wRH Y)!NI$&h fbEVBrTt`WIPivv2™B՛ײx{u䃥f7,eJtUn|~'I)3js *<  84偤eB՛rBGF#+!?jYwB+]6Gf /sV` Ƞ4ubT18ҦʲVΙ-8="£%jsB@pzM=+5+uu["ˆSwU g+$fkY'(ݭU,}/Q'>jf N594JLv&ns~XŦ5.")&XO8*({3x~"5j )R6fabjg #f^DSYbT X_"Pf|>l`2hFdyHJe4<̳= CAD Q,&ez΋ \Vѧjw`Qz\o<˃ϝl[z-YKY^2 HD$R.4ӊ4ghv8, #jƸE4bc0˺焻Ǐ^Eڿ NNM!4 @]V I74ވ*%1hXQ,mtdvhsVNQ].UTdNbuphXOJV7è[[Q<;GqmDwQGqm4!-͉ra"E) e*j4]L].kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkc DB\m]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]Ǵ8eu+ں躕]GN?t]J}~.{WC>S]Rz_.^Ͻt/Eԯjg޺?q@ --jIFz`쐟S$EʑwRR3T( pk`TmE;BoRz_L"ax0 Ǐ%&P!gi(ݼ%O@SlN^dMEAIME I)u5LNK!(ޣ,H,y GKO躕]GN?jMs' A,S*Y/DL!9Y9&KEm#K`HԐ ^8= AdI7MC+mx ]d5#&kfRY\!G(0:E\mf/5c4%0li:.{WC>S=]0[jɼ)N%Ŀ̈́' }q4c%ǝ@".6,Aꔸo{EhˁQQuSDq m׊Dk1ʞO44@j|`fT YtOEH5՘Rz_!D"@7F ij p`){̲7$f*ݵ4M`6!I C *L\^csKꫵwv;3gTa ݬZplyN^Ͻt/n"^A|枍JUo+z.{WC>S:DҲ;/rq'k얒lr%5!AVA `%e$ZoBI#LD2u+ں`]"z.twq(pQ"K)Lp(nRz u8"R׍PФeaeQ~_z_QR*E #t4e zA)Wlfk V]X@@sc%V 6-ADRg6X&C e>}l/4FQŐXC74 kGddPC-6,G8|`dHǞM OiD $ rHw]JMQ%Md2qlZc7 VP%Yyl 1P9M<%VI늅zm2l\B倂Ql-}'phF)2p.[Ԁ)MSE3 4 )ȩ7ISJsJD Ũ\,q0D eͼDil"m10D+;s"f,hA4g^eoʣbll%BFxS4 &W)x1d"Y4\`Ly!Ge_z_Q2X-^^3̘( u rjt 6#q0p: #AIE#kd.[56xzAt< K=$5X)G:DuxMwq"9P,&.Tb~bdD@ 4pClhb(jCDCeJ&H8ۍLB+`֌%@`! Iܥw\ b1IDѠ,b+Sg}~%P@֙sTPşO vA1M"8 C 1 ~%՞PۼDk`dv̋-E K{c7*1TXLj l&і`6F6R*6,.ćRvX pPbyZ^bFu+ں*q#iĞ2%^r%ҡmE%X  X$&NGfu)'Qjx]7""0 X&33i$i;9 &8DJ"aA( -%"g2ExL*愾?<zZ7بhD HD⧐0&DsP5hqӖԆ@{.88t]JlMũP8pn4aS 5FZ  ]RC3EgWISpSI/e&u ˂,i@D8k :T qO#EEK=nRDI0#9[%dI#m^śmMT(*W{GN?KE,<q+X($yb'F 1f(#Hڽ_Ao査a2 b >5mq^^Ia䴲!-m%o(,!+S ABq y&d'y+[3xlpwQ̅ IFNh80%xmm#\bOD ȉ1Ո 2Oz_PzYZ\ȷnZ<yZԁ5Ed21"O= 6$@`-QxB#H+f"<!Xo7!E2YE_E!\ /6[Wt?M`Bk9 : @7b DqdR"My؋# DHlr'Tk) E9uZ\A$rو0Ig%5T=   BoqZH !Dɵ; *Ҕ%rȂ+\ ]84氒&'s{u+ںT2SfMa_j>0?ҙ @쩽 fS8}躕]XF pzZŔ KzD耖`5XzT)Xo)~Eԯjg޺?q\85H3B4죎ui$2PكT0| 1c,F&-t}5EFO i̜JYH/,Opp-JHs] B'1$؇B2$˼f-Mab M/{ҡ)'4 xy#R_jt]`֕nRf!8`l̅k;VXOlDdpP$"S]RzXQܱgvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊXs$GDA0gvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊ4MC R%mmB:ۅi,Ku<P?@ cꓛ$+gW$ FpA~y"|c&3"EĆm}pr%H ܣP9Sʂe%oALxVx|WS>@9IR/Im}@2VkSI> }"ۀ ,vΌmVwEF? I#o,R aCmmmmmmmmmmmmmm@'Q$I$I$I$I$I$I$fI$I$I$I$I$I$IRfmmmmmmrr[mmmmmmlCmmmmmmmmmmmmmKmmmmmmmѶmmmmmmKmmmmmmmѶmmmmmmKmmmmmmmѶmmmmmmKmmmmmmmѶmmmmmmKmmMmm6mmіmmmmmmKmmfmRWzOKmmJi]m%{{SFijRKmmN0umЧI*4jOPaKmm}IDmӠ 1+0JF7@!Kmmp|amvx[Z<-G1PLKmmkͼOwem,e6N˭SA7Kmm-me-mѶmmemmmKmmmmmmmѶmmmmmmKmmmmmmmѶmmmmmmKmmmmmmmѶmmmmmmKmmmmmmmѶmmmmmmK$I$I$I$I$I$I$xI$I$I$I$I$I$IIi$I$I$I$I$I$I$#$I$I$I$I$I$I$,mmmmmmVmmmmmmm------? -q-gH-ݗI+-I3\-/\P-"m"C-a no~wc]/ [-.=λROhZy6`(-/Yǫ8ҝF-E1],孾dwOl-)=A"HY  -~ -^?-@Ky q7|0/i-s&?Ϡ[Z(gBMy-ӎ窾T@S'4- 1K$*!_-]CN/-bZp}-BDSs;-/J5J_"'-%q[ k0 ?-t"3ti"-&aR!X/- ݮs?†yf*-{GEY)o-&@ɻt-3d4.x -N7#-`X$Z-"Z}o-oB<9!(k- O.7v; -- ------mmmmmm}mmmmmmm^mmmmmmm[mmmmmmm,!1AQ0@Paq `?L=CB,Bz&>#Gz9.v& Ӣ J/96" &[> h'7-X ֹQm$l}G 9aB05nN'loepbD"Uj& PjiR 1/&ᜣ=،E D7)H ZRJ׶f8NfI?8]&%ZkKP#4,`ت~m79j*=2'1)ӂ:A%H]aF)38jȠ6"ըh5h.hG!|I1rLQ-kl7Zȋb--`%tkRdGTYlV 4-fߍ]qآDec:ѵZi#N $ir,Bg$9ʌF`}_k@: nٙ/-ĕMSɶ%Nȼ@j e[+)JM[\ɓ hhv8`[ }\]{8է"}w6Ke%j ܇vc\ {lYA\ж3V)k$Zj$Ԃdh_=PYv{U!|KyL`=OC xkhB.֝` ƙٴO( K eXn?ܳ񇡔OyDl4`i_֝kv(p܆v~_h쯽'oN<8vGJ?8v1hg&f>?ĵa:gJb<7 ^o4 b4H{&MdK {^LM3B(nh8Bq"P\՘R,E-*AyQ Jz &xJIE2zq-ZnT5D3TX2#H5mؤ=Nհc+HUj5-a y螈j6JZw9dI U0!VN1F6P$R҆"Q;EȽpЏ@bƵz%:R)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JRײ)JR)JR)JR)JR)JR)JR)J75)JR)JR)JR)JR)JR)JR)JRӽn: ΃gAl6t: ΃gAl6t: ΃gAl6t: ΃gAl6t: ΃gAl6t: ΃gAl6t: ΃gAlSF7|M#΃gAl6t: ΃gAl6t: ΃gAl6t: ΃gAl6t: ΃gAl6t: ΃gAl6t: ΃gAl6t_!!=\9999999999999999999999999992!El2kȜȜȜȜȜȜȜȜȜȜȜȜȜȜȜȜȜȜȜȜȜȜȜȜȜȜ U]ރ|M>7quno8iwo7z~7x4i?<]۽GϦvN'}INᦵ%ЏGNKw b,ɡBވUDȐ$ABQuH-޽?҆a%S400CL67K9D%炴KH< aj@Fv;$8dfF7FHp;dyfVq#Q-v]۽bElIHe_PEAX<6<^YP1JypX0_Q#)K&ؚR!bL^| k Z>`#2)R"&AHiYU24!e3}vKV̠JзF2wUP-!J7ݖUuj=Mu[1U+(E sp7 DODBec [S^Z /xjt-)^_o@ CeU>@wBCn-I-? S0Q-KwFZ]Z-"f҆\ȴ9'$mP>ϰƲ?6XڃhM{&B+;6%znXVIID|d[SOY X_lC!i̖fDZr&l R*"%CU4<puݹ*{|bMP°1Fa'f_TZ`[hiwn٢E {jPU.E5 K!SlkQ2ɚKSD^|`fy"lLU* نTpbI@R @ diH^hJ`Qj%,*ABrC%#Ppiwo7z~7x4i?<]ރ| ._mAO{6w'yǃKy|1;?Ng]3Lu:tκg]3Lu:tκg]3Lu:tκg]3Lu:tκg]3Lu:tκg]3Lu:tκg]3Lu&'Z|Ng]3Lu:tκg]3Lu:tκg]3Lu:tκg]3Lu:tκg]3Lu:tκg]3Lu:tκg]3Lt?{-5̒I$I$I$I$I$I$I$I$I$I$I$I$I$D"lT$I$I$I$I$I$I$I$I$I$I$I$I$I$ h!ypBv? /7cDGrЄD^!ysqvL_gkY/7cp -!8єJiD&A74!nG6x1 ሶv83) GCj[;X{Ob]$;PLE[xfP0xy_rԦl7& a9ຢYȭ;Ԑ]D% TW#٣P1W3&hgTmZA봨3LĪ)W.#4W܂卋QNf$$ɄCd <ڏH,q4Щwlpd4aB*FLjVj?̈ {0-D6(P.M7 ȞlrH 7܍eռв6vH0&Z&eA&,LzA[2Fdh&3>nZ5&+WXhB@^0ѯF:71 į3*7 wQ#RIB c΢mh~ BLW Z~D#%nGV}=F RTUI Hc$%am:;?"[q!^|[r1.7MRV%`{FpHGpo q7Yi/nb0mhKaFG CB@8p f(հ[ȅFg D@j7FNxaVl &hl`KÈ]뛨Jk`8HB0>#7:]+#fj6&O)F N$f#n)m!XD[,(c(/!xQ6Ya!p5+E}IǏnǍ J!aFޣ49)Sm,=È^P@!9HƋ]4֨I lF4ֽ\fPFf~ ͮ)?q]5wB`DD$`ͤ׿fGAւشXۣ8϶BI%? OF5BFH,"T8lq`iQO!x05 kHj(4U`$ ]EXУ(A% ExAr[6&.^ M jZsRX.D/nѣ:&?!4eE1^3VF #B:a.%Z\ޢX(@oD/>0dͪalciT ji{j$_mC؆@K%#zoCKz*dFA\h+HБ)A4f dK~BKJh6#DPNA,JpFn R 2 Oc5_cfI?V.Ħlefӄ<%*8J@ݡAa-85? !x'6BFJޣ${a=Nf t?Q날\mʏQ4k:\ń3Rإf#ItcVd4W5Q hVVб.]pܮzmSaՑq^ f!.C]HP$`&0!xvlaFO3b6Ğ ĈN!CW0DHH@N"h'Ț &E)5,2h+GRs F2}WTp.!yxyYz!y c'zq{,ZYW3Zm)KQOPiV!aJ%k"2%hpBUɀK hQ"M%FijAQhC׼ݏĐb5h^6՛ U%Y+b$6mJ->Ĥ/b w~!C_0"Zb}{B۷ТHaUZ#vLJi>4/%= O"=>8h$j" 28 Q([+Q"܌Ո* T(lp#Q=&7b׼ݏԯAcNՍ;lz]¸"$׿ݏNbgݏ8!ypBv? 밅}!B!B!B!B!B!B!B!B!B!B!B!B!B!B! !B!B!B!B!B!B!B!B!B!B!B!B!B!B)!1A0@PQ aq`?a栕*`d: O*HO*;ԢG^Ef Hz +f?yChhG9)6 (!Wu:6- /(OOZPooBv1!M v$aD3-LTj*$zq+I"nc GZK#IDUV~X(IHlٸf6'iBC^L^Cx20Gf>cE!ƁџΧ\ ?F4s1nበhk"z*HNCfDwXf0dRm b 7exa$*w L9<Vp gCZAA#- ?u뜡t']Q%ʾ|(Kv~-d%} P3 c q:)B_gZY}4ǶDM`1&<3-2d&Y{N\'V-^Ɵq-Lm4 BvcV͟"3RdȘ4O9MH46w,Tgh%f\y)FY:r? ׂ5Lr-d3M EX_!4EBrȚcbj5CggoL{q4?1bxttAlxS(7q ~*CW퇬C!eb۸ȥY o4Fec41sɐ!Vf3CEm w _H;5CZj Pbx.K#sBdl< ,-)(,Y?ڌb CGUUUUUUUUUUUUPcPRJ+)EQEQEQEQEQEQEQEQEQEQEQEQEQEA((((((((((((((F7[5G_.[kˮ|{#\-w[4G_.[kƶh]p ߍl|^n|:W_b/kƶhȄ,EiYb\2C36PLcV ŒJ[?*nႄ%"eЀ@x1Tol4lcDAFK~  +QŰwcŰw{#/bU7chgAYed ˌN4bCe}3m =cT gʪ6W6 Jݼ HW#fJSe%qD"hա  q*3١bhcFLBK ߍlyrV>ANqI%#\l-v-*@`4e11Cx TBZ . DD=p LSтBz]ځm Jh#.OѣY*Mh QG!&%$":Jn!`$U2'' vPu%5)PvG&d_ZMhllZ[4G^f5LEDMEQD!.uGM [WXJP( BC_ "3JjCYhN`2C  Z$ ESH:Ai)F0ذĩ A K*8j=41lZdSYŖ*YBHz;=٢:(A6 ;#m;&PMX&2`VFsnHևP.7AA&+|Zv5Lc5ٞPb_.$H%o M˜*ىAN jupˮ|{#\-w[4G_.[kƶh]p ߍl|n˽٪:u|whbUUUUUUUUUUUUUULg UUUUUUUUUUUUUj`lsn5V&?-|ƿ2!y5yȼ~d^u|ƿ2/:c_^yȼ֕  ֋v,EWdZ4(AWvj$zȼ+?cp(dsgdbz[R*j1zȼز",%fU6k[eX儌 _KD_^"p!:J1Rðk{䄆k^2/:lN_A; V+xש_ͺ/ͻ/:"VuByz;\"c8cE\μίEt4STfBT4?l$ J* iX14.ŎcB?h; $ BHhAII% KbF3)T0 xם^ٰJD(FSƫBQ1 1S1Ib_K_1Д*HJF+ij2 f.ٕ~5v-O(DTRhڑbIS5LI4n U~5Wb1-v5MْRSl[L j $UGK `Ų:*CZ qJ4S94j W8Q" Ї-CXv549cQnxם^yYt|) $M!JJOS_))! CAQQ K(`Ң8h7*;#x1?)c,I|kίW"!*O_n-p2^UWayC6S^X ?'<2C6ʛ y=I% ) }/ C*PNJ`{+,G6=`^ AkgG-ٚcНL'G^uzFh/E4PV,G욝db`Ճ #0(Qj|Kj#CS5!`2fv/ J&{/:Uj1vck ǽ?d?wpT-,C]QɠʁG2͎"xLeEjIF]PdlzL~EW$$SZj<8B ikr] C\6< =あt  80RKʼ{,0}Puؗ(]Ʊ_C( mFQXB%WSw+4E Tcg P hzb6FF,tih_̃.i%TLQf(bǿIyc"bb PD5ekXĢV`#bk`Kȩ(A ~y,Xs%(0)IMzdC|BɑL/:6("PŊK'J)S_T!ecЄkȈpV/:AM2CJ6$2+X-Q;)pLCyb$)X~ȅ> ! BBhg "h&7c0%/2FLd2/Pšz3S vh' s0e&&5-bRWb$)@(=S5WdKvf1'gk1@lH=}1*\m2b3VbbącБ?E#MfƱa1OMy$ b,,qKI-l L3zD?Cwlu)d\4S:f5I cFh^ux0M6;8JlH&H%M XFb!& $%k"ċ% >%,J? "F!L/0Xcl'ӵR,!}Nr^5YtRj7_^< $!ЍеX:0E! EYEi at?폪!Ɇ:]#5P^M~d^ux_m.}%Э[ PgQƚ hsiB- 35tvb2H݌놣Gym`d!Tz:ȼi䉤x2+#5lOFǏ=@Ī$zX HtS@=-r*р*X.F` gL#UpF br: [s4ˋ-7 /JLX &.X:1]r L0s̽T`! JawO!x]Cp Tq `נIu0e @#fA;!@>| P6 ԹMrFsb@PD,m62il0x Ds2sA@s#!9q-`TYm -0@L܂PM=*q懰T %rZtG_@RH+ a}_~ͧ? d y ,l"|dO̧z%*Qڮ|Zy¸T RԀn=@&.ڬY\Gq2f ?P s}i}}j/pq(`|@gz?g9|D0.p>A 9Ney x.x U)GjYk"2P2@n^B@kgm: F}B4Y% @B\*9&M.Db ='vWؼކJPw Pj :<1 轵SD@% @ j$X+¨QltP˧&TL@Kbc 4H` gLI{&b x:ݷ@+ eY60 c1j3a7.@Qݡ @-Br0: zlz>\ *y iT`#UUV$S7ϕ VdQRI3L5Z4M4M4M4M4M4M4M4M4M4M4M4M4M4]4M4M4M4M4M4M4M4M4M4M4M4M4M4M=ԡ} 84 0iL`4 0iL`4 0iL`4 0iL`4 0iL`4 0iL`4 0i`WӠcL`4 0iL`4 0iL`4 0iL`4 0iL`4 0iL`4 0iL`4Ljxw %DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(MAQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J% yѾX,T =_v`P(,wf`P(,wf`P(,wf`P(,wfM'3UAg;7|ԛ=afP0IA12F%D#b$ddŝ$5` KV*,sm|BW&TJ$|z>\|Կ(D1K#Q=!L"!~XBL}ODm:n%:8tlR"nKB71a ve*K6d*5$ +}JbN(p`Wdr0 S!U] 2mC@4ͼ202em@%jҲpZQBQaa"py(0 kd?.m4H"NP;m0 cЅ!Nl0BpL5bPY9*8\~ِ {(CH ׅe0G.!j]H r^'@NĂ\Z `0|lO@*낉]NgɀdfD?Xސ1Yh !wCC[=X`. iVP@H4R,΅vmNɝVsJ`?00"ng3$Gp,8:~ ew`捧S I/S^yپyEpA$Dj7?q`,-H!2zBqaCH%,/PK%%,EzCf_8 98  W8FvQȾh N 2 ;1+fvAɦPaR$wa!_2p/! N\16)-& 5[vP."2≀XhVֈE,t I *|ѵ&@rD|K{D@ )JFE什4ߒ5BӸXX߬ϱ֢h}``hG^2 "5 /‚҈)$>GK`5I2tTD @E^2 "5 ?fqiD)}rт[\& YClJsC'VL;'OG2B&TACK0w|3,_; ϰ?|? ks?X=35`OG`x*bkJ8E4i0S1E@3o ,LFq!5ǽr"S4CH+Ɇ!+c7TS Ej:FDJ-9, \h ^.Du@C_^Nkt4WWU)W@&D^B"@8V*@%|S@ƌ6@b*Dŕb&%tMA-+SBm+ԣ{w@w`1np9c'cxޠv@al?Ўw|3,_; ϰ "mAf{d 6kt ᜣCr p;S\˃` *.siw|3,_xB3u&+}.H`JrLCCpq)ȓr5ؖ8 >j@;vFY `'$ADldl$AD1\W@ԑػ hH]y^vo Wy^vo Wy^vo Wy^vo Wy^vo Wy^vo Wy_I`! PjT5A PjT5A PjT5A PjT5A PjT5A PjT5A PjTA PjT5A PjT5A PjT5A PjT5A PjT5A PjT5A PjTghoꪪ1!35UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUO~8 m|8 cMqc `砀A@`0 /W=x@ 쁦 PAX-PH [ʔ e]:K?y`':XLЀw~9䰀 ?%@L4,2PV i(  lH .Ȥ(jjZo@94@:uFZZN D 5煟(0)];9AJ@uD~ @pa)PPL 7Ѐ7B`JHN *Xm߻86!x9"*r:` g1w8<@8p@B?BhC}2Aop: q>0QV=`rpw( iސ0BݥL(2GY{ X8I p/areP#8"*;;$[]@ †,z xW@H2a[ʑD `%'FA+8bx >Hk 9:@T`Xy w\p@ȀLp@~hVx >q6 @YxtPm4j`h0Ev ` b@s!d 速$4q4 P۲̤@, |I\ ݬ?"\?2 Ft"A4S 8(d `uPgÄ2ɚ :%F)0"/ 7 !tQ M}z Z6Y 9V!b9c@Bv)`mƀC B fi/} 0Kg ~@`Nj#N GXE`I0P@E @>%e\i|{tZ5|SVh *02H 2%T`1xa95%5ɓ˨4A!H<ZN~@:{Q> (p(b<!D-;_(\@:]7˂G "9Qd/ /Ѷ2)L(N`88'$cz4Da8+rߢ; |pĩ3  lKih AVx kM* x,$ ʏ5kM檄udJDn6lS0e"لH1~$s.@"#}i.B%?~6w5Ãq] eYdH @/GƘ3cBD"A`C ` @pxHF }@@&b!e`,K"Fz/}0AT&qT 5 "^\<n8܂.]iXU!HeNWP@VC ʠGW 5. 9Ax g@ W# g҆ƺ`@R¨85H 2Xo4UrZ8iLк^WF$00psF@Sd@" ^ 1Ӑbm)r)<@%h?{Յ* T\ (ޒ6g Zݦ>o0 @E'BA 9][+Pso Uh9$:@+Qs)F 0)PL` t8 yϛ%_@[h @^P\TQzxc}4c@a+9guP@6yh APC P t,qL T8[QF8R<t ~e:P6ZC c<벁%B% 5MŬZ P&Z_`p  #9,g@;[puPq{Aa /; :jʳ%>Jx(a{섅ht ]E= A@9o@Yƃs%b.,1 'b@qhl+VOݣG(+`^P\8c8tR,@mtda*T7L(J Qc@ E P +T w;|Wl3:if8Ag3Z Op4UKP`S\@N [| \Y= $Vk;w.BT2$! @Iܲ `z< у c*} Ը Σ Q ‘?P=B`F 7xE&}t2$@ː۸;.H DHp9@qx0l8$ q .$!Jx[080ӊ<],4 јE5ځkD= n~Au V5 4@ 8@$/2o@{ f֘^? *@ 镬@qqAx{0:(q9nuNk=`\t !!``٥vH:V0 J)L@d2nNą#ږ nZ0d@a;F€*q`P 2 D ` Bwo@x$L΂( -hm|8 m|8:@RJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*\f TRJ*TRJ*TRJ*TRJ*TRJ*TSjTRJ*TS@././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/essays/ceilometer-design.jpg0000664000175000017500000025026600000000000024210 0ustar00zuulzuul00000000000000JFIFHHExifMM*>F(iNHH02100100http://ns.adobe.com/xap/1.0/ 72 72 Inch Exif Version 2.1 FlashPix Version 1.0 Internal error (unknown value 65535) 1024 768 C     C    'W(")" HLeQc')yT6Oܰ&;~~?@nyOϺYvq>ɢ M"v ` `S/]U݈nsivD*Cx w~o IPD, !@nfP`@&Y2M^ĻoC-5TJ&RUQk !A+EIѼ>dRZͩK&ŵћs8>'c_EǙVb2vi/f_RPi+eJG8Gonbù{52eN'ܿu'gmiacW?nZ%osuɏbºW}kUk6uW5+x`*κ? }n]X;ojqnwks꭯'?/qm]ߙFc{oCur5if]Le8q7cW_jv̚ћ^gsyV3st|̇ ~c[q}Oc*Oܟy'kq%=<}򎇯Ռ3G+Iv2}M~ ^[^S._$gAt:;B;Gt@u*t~ 3~'w꭯%?/,s=\mz;"/3~79ׄx^߶8>}o'9ݹ;ߗʴ'MbMbv.\36ëm(ξ7t;FN?-+-O[kk7GS}Sol52@oט=^}|:}1j>fx?*͜9kk|Oku'{G_5H"cCy9\sCYlô8b[&;^#k\D??ޟskcg .1<oV <ߪYs-b~X.3sGg(fCwz :Ww;mOW߷|m1ƛSpZ~_oy1|ݫc:u>׽~.;^7|Oku'Qbo'"+vo=f:Uu|˫;ͦ8kF=ou>q'Gk->O=.W׹z Fڸݔvm&n8ttd/Ñ^7mEr! 6$H AS TbL%0  $ LGM=/;MfEK%[8B0~YHL1>P"@@궪g[CcC}QaeǛ0'M[L1[*)3X_@Dg9@Y3-:bI^k"a8Ggn'~ #ހH6xSiׯ_3ϼsnqf䏧bXpVxvlFmje[knl;,@4 EXT T%TCC̀*y^/rK. QdW&>hŪΎ~SSDVӻ$pn[M<{TĮźEUO1 u5-}@7F$04cBb0ljh/0y=$Y,h~M9~W9|-]]AYLD/Gş6q[8Wk88Yt2﫥%NX4D[ Lj@Y!IV QK(̬e μFetc{C1f_aӒkX¬-^[%1ߨ!$f'g"NX 7)i*ܛb>y**g#dפ{D֯YYPG;{ŀ"%$*O+͢(c J yJbNDH 2#TGϘ@Qn[,d,ZaQY #6kp1 1#Ko!>; {ŀz$ hKP ymdZʎ#GGuAœxQ T'-z]T%$kvs8 +e8vH& [@fnDV!>; {ŀZdE)(@ϰd̅s̴Zί[0u"{ O˪ĹZL2U"rt:`e soHkV~ dg5:0߬c\Z8-<|%12浜97ulmT#}!>; {% g0ά$)Ԣ1v ;xO1ˏR93 cs:^Q^jC_uzSuYޕh(|H6x3*bM@s:u3뷀o1y\}-@Raɘ\ďcrjjU ١: -"KV`2{"2Lk> N./:XG?GuAxSl՗$f]>~rj┴LB${@γ$#TF3WZˎ m˲Vי4 {9,Y!p^{zny=/0|P/[ǹ:?SAx$ )(Tě>9z!h1gJn ÒCYFsS9!$x1vl{|s'/X|hie -D%j\MÊV93 czWM!nT˘D89$11j }I+3D]ЧjXvk~GzcXoϋY%lϕ g~Joy9͟[F%60g:=,{9urY$<KdusgfůYVۖYjI̼tv@% g/9%k3SAY1Vb-ÒCYFsS9-͑\yw i $Q߮c s O1w7YugMz!a+iH1̎e̕L VuszÉJ^*dq9xrHb5Dc5:UP\˳-. ,#fc*Ůe.Dpnl5;8Xq+b!e}|ZmsddǟXY)5+5X|_CaȀ J1&ώa1wilCDO3/I gS1NxԘ2w\( ;xO1ˏ; 44E 긥m>Ó194NfBgeәrjjWHL '씖ԕA`vxaع8vPڈ*Si3 7@Iˍc:~9ݞoxw[$<k@53M *bM`3/I gS1Nx T?\o 9q\@YR->Ó19Hγ$#TF3WZ+2^+f3GԒjqHwjϤLvbBQ]OIfB4=w[  s~u.eg|wk%j/ؤSq;*HRP6|s ÒCYF3S?\o 9q\qJZ}&b!s=s gYÒC#-T@:8aRe@&k!>; wrM]mjMldސ V֘F]..FRP6|s ÒCYF3S?\o 9q\qJZ}&b!s=s gYÒC#-TCXBZuYٺ-=@죺 wbH[%RPD69""e!N뗀 +v3rc*V7!s|ÓR}A죺 w`$ID qv54:p1_{i1@mLNSu2J3KdVвćoDZHэ긲e"%1LvՑnhq۬@5x2oQ+\W;.ޞWw@dL~Wh(|H6x3 j"P&6;Y=3w\S%9ƚ"c` ǩjaO\%ܞHEoLyJ"dȄƬfnfy5f1d#ѻ:(|ff֖ZNWYQ62nbkh(|H6x3h -mjF}WQu}J’Z*Iz/5I.ZHK"G}r$ "|5@A5cyCm`GDY[˂3|VӋ6^`Y`Fwăg9QC07%G K\Pc>{y=҈+7G&q74^J /kp~CWes}^F̏T*ܐMRUlYb>7zM0Nh+oKWD_XaNYƿgݶ8Fwćg8KWF7XVjD)@\bZj$c7S~ ,Ul5>>h̑^ťw!Myp86 Z fx3Qng0 _W@X_9^GKVH¶KǢTKgWgXĦ-vqi^bޯLk {-_W@Z/S{cy}~ޓ-:sHe&U i475&>On٦53cύL֩,e_Y$;<gWF'f.Ǜsװ b?fЇ1iDO>/r-|:S 'YJftߟoxz!7`6sk$[3O~;{ƀ mZk3EII3#Fwćg8ke*m9t魹uɬ>1lbS;\qit@h(|Hvx W.g[9vZ"C SO6Xfl] oD$[< Af,t@r ͷtgπR [o G &<+Bvk^)jk(.dzѺ^P6qlߠVG:>< {r6@<$w,Ƅ POiZ2S>fMBJEX<'dw͎!ja/d@vb\sˀRFŒeI<'dw͎Rغ5MRjˍ2"Ry+߀l CW.5ɾ jξ^Ml]4gbai"!^l<'dw͎Pxƹ@~fU-}[4[Z)Dfѕ|3N]QqwM6;Dr~gox|J҈r׺ƉNk'fax̩h<|x֧wKHaɼXVny*Թ=scș!±ۤcl< h_=$`F"bMmI%夺*aKtM%!sXŚIkK73Jr&",  3mkIcՋeY<"LUb !Rb7 02456 1@P!`3"#%&$Aeel[#U4&`VzILՍi. Z0SH?~]"M_RRz6D?m"tQ''ڏ'(G,IEtwq!SGUhQ]gQ{)s{^ƇZ6Fyv+v A HQ͟I-_UH!;2Z]67`P^s2[n;vts?p1L9Β]=O+cV BǙn"N(`D蝌-JDFj=7I ɉOId9J DH̱2dC9W]67`]KLn| =s:xʳzwti1GȵW[Q {v6M]\2Q{qe+(P IrK*aB8hͣxcݐc/xV߸׀Y{Ş.pbXG;e#n+;pEZ6.u.Im5:vr3ی-MGR"lF>LOR9Zv6M]\2Q{qe.TD\Sn)VE{WEu,ᥣ*1ZvFHY(G.uǝ<\iU~":0,d0Hih{-ɛ\Ww,7=c8JE.tU1c*QWn'U% !᛹)[JqCH=< .;Zrf֕~t )Oϓz6Q.!&oq_JI-c5MK#nIDKe VFM&U'PrzcDO,Ľֽoi%=lvsO=?Vd|{WBQ{n9ub\mԐ> E?OퟧC;M%yZ8<(zYڟ"1>שX7<ĕX$iC̏v'vuu ʹ$.Y_%E3T]مqFM{a )6sp AO!HQk)*Ii´],n1M\:r!E.&WBQ{tb/lj@;D ܁ D11#,0_ fR6hd{Cnk=ZBIIcMhY6yjx{_.q5p>E9X͙z֒Qe^MjZ=?qEsWǹI"W :F1z,w|r(]//kA=dՓvDFM{b/J>%KSZ6ظ6P{Y+2H6{HE'XN&޲˅4y"uPRKh5]Ҭtpƍm?$>nw7OSG'ZEy)MJG޻٣V- nv%fڌOf̮$dtu"s@!fyKlԮǧZ5^.ʎ6=ٕLNh="9Ά$x u3'oYObe%Ѕg98SR*Z4^^v>ԴH iRw!I{4nFՠjdN49 "Jð_+˞ѽA7xo 7ޛ,sOIibEB}#LdC$%,Id2K!Y dC%4SʊXVsNO/F4Ua)\}dC0hW$,;[dL 0 6_/.H'̇\bg]4F8f ZȄ6GvtئrD(G+9 qY)a8{sJm0ɫTdSN(aMb?aƏRj'\lyk'Va˶ n،XK8CHPKA3 ڠiATpj2dgg@ JqUqSRC*3kNkBy梷62ÝIc 8 0NrcB-eTj2yN!mHR@& ЀNjW3QAV;a߬2#m؈=-fquv ߗpݽ$U[ս"esGvLBͥb=Z'stj7I.ߦ\۬3äP$瓪I]O &iq#ʼ ,QAK:jE Bʲd+ẋPcy"x,-IBSS˖1C6ҏ1F[a6'ΆPr]A˨9u.M (])'T/iUR&)8UMmԚwא[d-J&fE3()j7^tG9I=4K̡)N?"g j=}%&*[qgº4#@ 24#@ 24#@ ۊ"JojPۢ:ˑFdhFdhFdhdYNy:<Ũ>:wvG26҇u[@ӝK6پnWij%ϱ>]v6R7~ߋ9oƳ)ӿ}?<}c{ >RCj&{;};#C;zn7bqdz-:C38ΐ:C38ΐ:Ceޜ瓪ZN$+#Il;l}LʧnqMPFZe2Xw +V@:۷T瓪ZN$+#Il;l}蚻)rN?\< 'whFxl0FU*wl>3NHKvH:^M)5^扶'QX 7;z~5Ar\*ׄ9NY7EZNɠY9aG)#u^Z')cfw29>!voSxT$^IWGD$uqV J\Rmޠ2QdM3*)MCH|ݿmD׏g|LNDi2|UI!JrY5 W ]WGoֻ7tmI8IqOxRo.$1 Ȓ,S踋vxWخ@dgM(F )j E^ {k] 4bM@ii+vom 떭-XkˡrI$RL$yM0tmX~6J´Vj5SX^\"ooZ2IgUiǮڪ髹SX6k'fEuXO>.[2qXtq.uWBY:9 }UVuZ:Nª$`$>n߶kdz&/b:^i6vdef#FXۡn*X34F#+"̳ =nҸCcw6WF F6n[˳VVMDfgHD'"P2- ZMZf1YBEbHiMṛWT'N1gW,U"%-E۫ؗpY+}+936J uFTAnQ7Y F.lȉWo ,[j:h+iDˈpժLcC7ѭ|.Ur6FôJI.")!Qc{ >VP5 w*Ĵ]vv$#dsD9$lWR6lbaA7oQ5&[dlO,w2ei[&f}͍ D/l;l}HIJAGj®[r<cQt`5iD-iEʙ#j"щ\o\[̒2oV7RWPFNnB舼O{^ߢ)Ya.LX#J֓NO,$z%Y*&k?;cC77l$>n߶kdz'ӿ}?mm&dOIЊԘQL(&z =IRaG0ԘQL0?D 'T'ڎ0ij՚vԼbOeH+fV&1K!<*ۙyj[Fr*X-7ǵna%uoEV騛tm;l{XO>Ԑ~ډNޓ7'~o.%rQG%rQaChڵkå)9`w}JN$+#IlavٴYHPDiMR!FQ(a 0Z !J SgNs -DUQ˾F+ԧԧԧԧԧr]G|JzSI/*$gܤb]鴨J<%+OOO4jWȽ(zzzz''MbWxE|}Jx=JxC)^*zzzzzHN.Vqډd]0q^<<< i!R-6/OOO4IOHĻ iQynJIKVzCQs/vI&SU)))))))OHO%NO/#G䣒J9(䣒lnEhrVRkê *];aĩגJ9(䢐LPG"Ԩ䣒"*վ)56^ Z#zrQBqFHۆV-&䣒JV`@8߯%rQBqFDەUDrQHow'@wmy(n킨B!:גJ9(䣒JܫVgEWgs+zȓƎ{9h籣Ǝ{9h籣Ǝ{%s$Z;/goLNy:΅1dJۡ3(X06ש3mGִ{{ } cWp5/oz½ҮY7:G2G,* : 8AeP,u\#Vw ; 2%gFR" vR!vC;<im0v꘯o}oaO|,d[)6TnL A`92DtNCU8+Vl徼zR+DKEjYt28uWnm[VMFN/-A=S?9mdkS_;dʲ/ҭ(Z+4 (ZWgܵ8nXU tjK%Yk(H 0UPnTLo}aOx{LZcԮߩNۘlD#,߷ɾ̊KQP,*ꩨPT q]. oHٗ5GGGGGGGGGḠ!0H(A*l(VV+npkQFRj)i5#B!vU} vߣy 䃒H9 䃒H9 䂐M V)MmJkJPr_A* T APa0j 5 ATٳ9!1"3Q 02AR@BP`a#4q$Cbr?eLAUD/oK)bB,2Ej.~bH-DMDKVo 4 jwcz."Z'z|*kcYW" Lɫ'AXbNdig[|]7Q}̶!bɲ34.f]t/}Ьem.B-  =.$Ni[BMjzv]~ ")Fb.cqmQw~ ƥ}WMUYQ7Lq{G3ĭj,>)Cub9 F5[ S.cڌ]S71dYO4 9**kfRX\ֽ V59Y9Sk)B/k^+D=Dt~axu"FB^g\cUtR0Y==ɹJީ_ fDCJ˨(9"mAir/ JzeF2fv."PBc[QNXWG|S-:h(iOVɗp)GKԲWKپS{HdJOYf QR.! 8H[d+)~Q2PHTlR&Cj LU7-5s vNCo Td{QR.! 8H[d+)~PETL#E1 PĹq-ZFV{ EUR]ZaSDq8~"pVT5J>)~&Rc fJ:bX$CgPir/8VoŐWI&}7Q}zeWӰKЋEC,aKu؂N񶥙Gd6t[)=iR/5pT\50!VW#SS\Y>63!|Ne*(MOTE-wQSC]YJ 1.Abc7ʙE{e01?J SبXSZx 15$tڈ) hhERSVUͰ8GXrdxI1 %Wf^t]D;z}=suoDt]FIG[Qq$%Uɑ$ hE\t'yK9T֤ډkނ.& k_!m4Qq4Bf)*f.$EBΥ6h*#.[v{={^Z?|;Hf i*:¦En0]+w\r˗/ھhz\f\ "ctB[r;ĸĸ4QS$=j X;ۣ &'?n*LeCbe["쫫l 0]5vܯ-7a}-wd{>wS6䒺Wo<9k(M&-BwȲߩ{f]+]+]+]+|#qnWܹr˗.\m˗.\r˗.(n\r˗.\qF.\r˗.\˗.\r[Tھj~>]++~< رbŋ,[9k}/r˗.\rn]+Wo'|6uSƙ]t<;*:Gnv>Go>'BQq۠_|||||"顙2q [|o-t#A;|#;|#;|#;|#A;|"KybW]%T17%;|#;|#;|#A;l#;l#;l#;t φl)ѷ?#;l?#;l?#;l?#;e77zp/Rxܜ-?z' J7В'BqG-v Sffff*(,uE3333333333,){.ffffffffffb[jffffff]Ku.Ժ_!7˩̗A=2q-tu ]L9vo=Y'KD9-p'W[\G99x/n/)'wmB#pQ0^BRp5 I#ISuJzt&_>' ,^b܎(Z)4Avοׂ*=.h.u]%l $.'$ u)*V}Ψb8#8#8#8#8#8#8#8#8#8#8#8#8#8#8#8!lѭs' =C)[.rnw|"5U*L=SW9k}΍%&fgv~v;ݴwm?CiO~v;ݴwm?CiO~v;ݴwm?CiO~v;ݴwm?CiO~v;ݴwm?CiO~v;ݴwm?CiO~v;ݴwm?CiO~v;ݴwm?Ci S&"l^U=>?r%5=U"[S_]l/Bڝ<*"-#q~R~Nmњ&qr{rn/ON?~nq- Do*0wG-v:}{_G-vѩH7D\p_GľCN7x7yrn/OT?p"B-T1ldM-ƻq~Z=¥ܗw^]7:=c5GGERRU_w.o.\.\آɅIC^zM6S-d^"X]oܹr7T˗/ejEU&_ +l"DƂ(NI.F/ASJCt*+H䶜d`l[NJ}ReІ:[PATW[Ar6nly Th#uz/%/[Ezpj9h5ȼ@=qңVbBd,9,Q-*T+ЯԿNg- DQcuFxڦ͚w>EqQ+c|7 Ր5j`G&XZ#3ApA-0QT\MPBx8TXQBlc"utjqSHQܛAQG:$N7TGoB8 ڦ͚ ܨI=-6* TVZ}GChufGVCiSfEٻ(\5K$b8kkAyr]f d[TZW T~`elhOh5=ʺc!mr)J?h6dMiB'YeZ`LڡQJOj6jK&+f7ЕlɅF!ZFd R&ҙ  j"Oj6j.F\0 eT]HQ3QًwmQ" 5T !}*J% #}6Sfo;pT " 0#[$m%!B7RG7BeG!m=l٩[9Aj%A B JڋStFR:: "Lbآܨap!`CԨQbnH&Q"#¢CAJB|a7&,*$42(h5(JB}uĬFۢ22S+jTB\%lϡRysAK!/eiqG8E_PB (PBY%.рFr_QBP)e zsR(Aܩo!oD^yFKS2sCB K?_SKW^EA0!9SB (R K\)f<(%!E =7EM◌*TЃ?ԩRJ:*TR(P-T/!y T/*%%`;1%HVPB7Hnܛv(TЃ?СB tjVʕPBב;k%Ff"`{NȊWnB\U s̸ NhhAjTRzT*V,[2S+6gȼ=.gm )mJЧJVʕ*TRY 36J=JsCB _bchhAhSj<憄t1uEzAmǩӧЃ?nŽWXzw#z44 ۧoUmoUEW{y 3^FV][[RsCB uWUW{LtsCB uWUW{TwoLh;puhJ-,TL6A9~-̢*Ц?NSK&*&44mUsm[ZV%}#sF3)YK_R 󨶵ZҢKnVh&+lTwzZڣOKPr4BMMgEQF>[4 psܢ~o.䣲hWЫ4S7 ؊.n%mHb׿ZW(z7 |y]m[ZRhzJ"\m?Dhp}{? T_`HM\)(xL!] jQ{hJYM m׋)eP̠35[Qϫ+J;!= Dw\1ުSQKF.H*׵mmťԗVjNu؂**965s< SV]2e桻E$j4DtЃ;3+ˢ "Ԧ㢝UoUmoUE F-ELd3:ZեȑܲsCBsB,Zi;w1[Hg ԻYQA^FV][[z 7$/!\"4Dix #J9VE9yӪ꭭(lRJ*W9SV L)է#yk[)̶.}{hhA+Q.MGڕiRAo,xR>QܗTon{Q+KE %G1ZWsCBֱ:hmPdeӨT6mq., ~zla\ vʞh*nc>Cddw71Ȱ~z+#ږ273ii>ǻZZG-}憄(lӺEImֵi uLڏKb+7vfٳ$f]dj$ģ6gwE!;'AwӚ}*Iz51o2 W>kGzzIqf$MIJTag44 ߹C::6U(mWźIEzݪFbOSchԔsCB~u/I156F̨Q)^R{ ?l S1r!zPBF/(#҇?%nܩV型fhzC憄69ZU G_!,nZGkn"HhJ3xRvl!zP̌Stɑ~ "lM&ޢsjĒhdˣJ֪5jKRƋFL,B -TNhhAȎ=G/$p|F"֘ٵ$`8I$p|NoM8I' 7&$p*vrĸg6I' 7&$p|NoM8I' 7&=Eu<' 7&$p|NoM8I' 7f,p*HĢ3܉M/ɥdRz.S싅fY^¾X"^es *ܘyW[@hNё'~|[*?PV!SRM. ku *.l-ʩH4j k&C(Y^T(D%֗BjL6һH?DAh9)&2QsO&޽WB0z]JQ!9FENIP4n۫= q!8(KmΰՒR$Ʋe25V zf$l>J òƥ#+O,n!9FENIP4n۫=7f&Ѕ#"ltL$ c5( 6Î+$`볲WP@H$@\e+U1yX4hBib9y-g$>J}JZSՇ *gT>mUuױijXuF`a:cT:*dn$:Pm?ZZѴ9Z%^d|%;My{~]\XVԩ[V ~s $UZj!EZLA^8Tʷ=ۘ r,!FM}xn]J;t+r0U,frµ+npjiF2=[Ba7*H?KUR\ )F5IM|&%\RbptѶyF*OZ,W:_00rJ1A e27]1-0UMas)k yTBG lsb] {zf$$^[d7"}FM뫯ca<jԱ_|u(ƨu)Twc; Յ cR^Rp䥹Fh0\QCOt~ؓ/Tq-@#\ܵES|O\mM:3JJδUp8~z ؊)u$e[L(udjSJ╤+*}mjINz⮼~`WʐzmMk<6[o|M^}iVCʠDG?N:f>/U{GXDYǁ<hT*Rx-yң^c D/1,$%! í )t!!) 4T,]#[Κspyq1BW|M^q^i pĵTu"GhiisP?ޑ'p6ԫm*cVx"Z9T KMjkXC-&hHJ!BIJ=I10l>6f$CmMk<6[o|M^}iVCʠEYeZˣ28`L3EauI9(^c.gEDG?LLjJsD_×'D#N"TO׏A$IMx F\s >?H)V()+,-(M[KgЗQ؟eY zQRO5 :rHa JFe[STbGa52Ta&>&gz> &M=2dpHCssi(1JnnOt!.>ʲ#*;RjA(uo *7ʶ$f꒥(- Z( \ˮ KL䂒B9k9".'^Q.ldpO2IUiZRxEvPxhgǠÿP}dj~wJfaڳJJ`PPlcO:8R~%YQg;kE8S쁬uÉ'~d~qXSDīE)[(biXShn(G(=+BkWP$PD)Әc'.Chkf'2tL<\qKQ' 攁KVU>6R(=+BkW݁ aXI3 )ž~`N w {O.5m#! MRqf#|O 6ǪI* Av<*8!l,qާX OהⰧ0f qAVQ/2RW֭| '3쏔Kud|_#N=At}'<ǚbEAD-; kaI@zVFe;Гtlm$-5XǴJkaZZ[k#x\-cy:ʏ,V}V|F߂7-v7,v7yZ}gʑo~g0ތl 611.Lc!iN{#y;썶O9Җtlc8mC`sFTFI]1$#Zlab>5v:N*1y(PX؍b_%*I9[>Z]ܯI&&7:© Ctc0v5vx K2R+֤!(R=8aMK̭:Qp)p8dq-U/%N8D`ڴ9O0^W6*z?=b2v8t:GSSҚ"0?car7oNd|Mf]?"$m QyU_v6/ȬӚENXBwՋI2rJ3ںvﴫօqHnĨ#c Cmo]*.jnf'J. ԣJ0Lʊ^Eg$%absz5@ zKJԎ4c-kujJsw^r]8,қU::s)BR@'fM6bai{ϲ6ͤy`т|0T8AAxUB'-)}ڼ /#lMvG|A𘭣75iDEYf~aSH9RfQimwNL#݅,]iztmݖ sgKZA+Y/-ò~< CuS*PJnjM auVH,%zSv5-&t683Esi7*v >~X[0@!=')mYkI7\=,Eoq|=){pȒ|ԧn51mVevV[菄Zv<ԊEW$.akDP s|l1'Y;=hZ aY rFTœ>uE8FR^;:iyH6ljz#iջ8޷MS|ǘXd '϶GgYGq&/6^hIH-Dޘ'h8LVYw0qӎ"0ѵshр6Iَ"jVjjy^mfO I4H50@84'O,e5xI4m]JR0-לKM UKQV{+r=Puy{7_:/-IBxiM—ܴMc}5ʙbֺGa,G jBPʜ>r=rq\ 0v}8f\_gʴxBqsl-`'|TZge,q6 4h|ݤ{!*h"䬻Ri>q|c|c|c|c|c|c|c|c|c|c^r`%Jđz'G=WfT*NxEƐ0SˡΉ1wrY ZIoL+F2$oL+F2$oL+FgLI3,h_m44;(֭ ize|Hޙ_7Wč#ze|Hޙ_7Wč#ze|Hޙ_7Wč"M~nDŏލH}:L[+ ƏQ}wK?z#ϧ[zd~=1c~]צ= ?V4}=Egҽ.տWI>mf= هaP%ve(ZQ#ˑ}ud|G.GQGˑ}ud|G.GQG˛0v$S!XlOGIމGlֽ04Wm/w>wŏޭOn1Wk~iHm5x0\&nV!*Ź@sB 'Us LuQ1!5NmRrVt蘱ѿTv.kAwvl>lz3^yX߫$L 63v%\UT'f/)V3aןuf"J 6)]ang?"~VґCSlJm˗u#[T,fb9LSMd+(%Ĩ0PMMq+MeU_ &\N9aZҊxōW>-)S@?# \&<.J*Z̗(!HޓC`9'-,jV7(2ƧɼŸM A ~pʲI]~Rř#5g&MmىjT.1-)K93 ϾڛS%77xGG[ h0ֵ)(+iH)y8vUMpYu8mnh]##Q 1>x)i 98 %`SkCt˞.rȔV3$&̐D[yE.!P trQjUFSae7xV9iY֓riY~e?E49EҜm7iwXvҦ_u;8RGa<Ҳ[j> \ezRՃ|HvZaMզM6Ut_?&4VUyb(x=B"z:lzYKa҉g%,V1B8枲j(~X^mC (6ZFeMJ0F*VDֳ*'侩%8*G&R,iii` X;edNz-eػ9se!F-6A[iX4oq4ܠq*w4<\]5IMv1f?'iA(TgAu(hxK?z7Zv]3 QbTP\RJ!٩Rfn%դJS"Õn^ʑV3nZÓ. ZG H40ɚ'šCvbӰ7$PֵݗVH M_Oqa[R.kAwh[weƒkvYʪ+&Yq 9NIE$XJ5|C` `GydL 'l saycja "uWc*Sے(|Q"܉JƭtXa$`gMǡZvJ񚥩6ik`wP|5=sWq, ~LL$k]UwWs0[4kmW+Y˚HJAtkiݬ [ݸTJ U&AJUZfa.?.KoU})qŅ/,YaBx3oMzZ$ +ܥS!'2.Q*)!'h/;/=y)ujm`V"=$>&̵0[CVM9-erJ!նR.ZSdWei $plV' TR1uvyyOrXռ׀7=t{RcMEӈ@ǪwCl:^H-ZfQJUPî]'ԦY?fW_^W M;&%^u" x8bJIj .ek A^R\Q?d3)?5[SATä%ImZө#4MZz:&v ȸ8HR|+h^,l2 Q199/hYrj5qОEs Y,MJ 4T~EʕraY PIЩ+D+/2ˁ-xWkH]!ih*-SQv̖DwL:T'5\8E&;=eS2WW8eҮ]/JĜ-umT5 h!յfDp 쥆.qPD'.bOg$WuZ̶_ZZ!މGlֽ04Wm/w>wŏޭOn1WkZJj(A EZ;|Qגy*גy*גy*גy*גy*Zd+ 4G(Nf1QqŪ+5LԞ:-uCS;&]`+pEֱ rQ;rA0R؎,Iֲ Pӂ *Vғl>yRPW8pE$]bXXk?4YsJE,ܚزnFψE%'jMIq[xLwyN6ѓD%ߗȁyV90\Mlp$DeN,7{V1*U.e4(I'j3)aB לUQ4D$UNlG Jȗ5Яz&,~oKZbG]GƛG9ތWc?z>gMǡ]YT12F^hy/4e挼ї2F]='{NTs֖zމGlֽ04Wm/w>wŏޭOn1Wm29vtDJI*K|MҴ7y_WcxǕ17wbYY|6a1TX6=*xWcxǕ1%XUT"a6M%AA8o,c o1AceZR[rfCswBl+1c oz?8LJB;f8 vM4*7nA\xzXQEҪ]SH̄R" ֮OL^Ts 7|ީ7_ōczXީ7_ōczXީ7_ōgh+@xM\ψ=UF7qnѻAj8^Rѻnw7q6ʺ8T7qnwT۪b@F7qnw7qn_BxF0P@ZۙV8ܺy{ҳ-i9KpY򁫩r^qnӋChP w RMbj7IS @^Nj3V)ȸ6تe:"ə&aJ+VҟJ ЊwEIB!-aI[Еq*Ra=*lclv1nwZc3b:w^a%f6<Iչ.8QK ĢLe(7ZpR圥TK-6b_]k50[ujqۗu[7PyG%*(J/u8`E ']+(G2=q댏\dz#G2=q댏\dz#G2=q댏\dz#G2=qdc#G2=q댏\dz#G2=q댏\dz#G2=q댏\dz#G2=q댏\dz#j)iI$\uhG?|gxX:O7Wɍc|% _&7Wɍc|% _&7WRϳluG? PZƏөW@SN881>t9K: BN+"Uf䒦]]NL9/6ZEDEya))=VֺX8y!I^sT.ִ+P+bΙjLZDTS 5#'1hfQ I>LOlq-w+Kg#3#2_vpa3JEHzS[>¥4'kC,ҥNZ )O8ZHu."]qXmdU2 enPVdiq=*oKu¶&v#b"m^XN*@הůIw"3Im5BF%a*Zp(]H98g\eZ.U.{bkE$m i.0>x+QjEYբAWxkd]>enWpDjH]ma7Jql,]FVˏ8l>rGsH/h<[ET=2ΉW^1.5i.ef#i-12.kR+^cɞQ ,ZIPyu-`~A*?i,_Mq]Z2 óeٷp2 F 4ޔӆ#~ѭ&_I*'[I I10Tz>어\mL mC[~–Gc~Um',em11Iy\IBΓ̯.1 qZPfZг l/֜SYw'^RG^i׿Te_Ş&4Lm^]R.'L>dUŒa?L'+5!/0xh%a jfc~-_돻3O@7i>8>/*mqUZr]GrBDYzOnqc2NՏ'~|D;c'߻=N),OP'~%L/Dݏ'~|D;c'߻=N-0 6 V?;=Fl=Eq;wxC w \ 6n7n8[}hĔvQZ4>0nd.j5<*U,Jf5{{a~Ey?g'yMEs1]JPsu ,gӦNBa36:jTIEi9ʏ Yb]cqk n1x(8JI*ǘX7MH O' |g'aEqL2HV>chVLvIQX9QE%<R%4%sXܻf*R'#P[6έRUյ<\6eՠtom$}OH񽶟{m?#GߍiI~7>om$}OH񽶗!,9n Om ?gNmB&kŏ>LY6JyeeFQeFQeFQe -9F_?-!1AQaq0 @P`᠐?!d ֞gMB.#P*+'Ď[ͭ2W0oS]rWj# ecZP9H@A™^u]Oت(@ uDpOM@D2`XVjqϤP&\=_h^#-F];Re2o-pْRY &<b(*ICVl Z&ZlpԐ;هjwdy&cF "2'gF6fIHF_d$w <Nޏd~yO|P5V0(ϭ$ck8+Nt? `xyMk84洹Mbm +H08գ _*;ے@$A*"ءLX0(8g@g8kgK9x58#p%M*khkK_I(bgֈU15vp>}Ҳ(`4 YK@v/RQ-|jn扈)yRvf.y;B&aI@[>B !㳋lf>`S("j4+Nt? `x#ı̙҃44 X,KJ R Zlūb(ūa) AK]৭~RjlP[37b wަĦLpKbf~@o Pmq] {TX _P AqkxkeEGf < .h; ui"&& $s{(ީ]X,MʄB2$bƗ)MQJUdgx[|^|nEvߏ|SHΊG4Ax`2&FM 0ٹ3p5ʦP@!Ҽ>Uj08Í1mlOڊP­C#8ZKr8xB53 -us x-؟ZFq;ׇ5ʵ玖pf W"wBd`b#z8DxW]xq>XNf]@\9ٝ1ss7C`00H8)܇`ix tW"ǩH0&CbRI*dn[:\$ 1LOt 48Sp,QW@(lFвE^yS=p~22DzD AI:HT n13B"qp &"\$IP'AHE[{jY !uUic*N d\Ej)+$38aKpSٸERaL ,ڐΔ@R\ȇ'̈C&X^)ef,`p›ZDyN;fKk=JA@!20_jD\alkW&k:6u8؋$1;Vu@JtHbҾ΅Hd .bz VVrI4o kdkKI.^{2!2mw >,J2!2H?}s3h1"ɔya=x J81tMa(Xv, ;F" Rr IN7]"#$GZj:uQ֣F\I>iKy?Xm &a.l MG|F4jիFZ5j&e|'8{DH؄はwm40un .@LmPffvFX+F=Qm+W:qaR T$UG'AeĊ y9Y} {SK(KT0'Gn?=R%xmlǺQÆ781h4tE8d/+ 2K9չLBcJT HFr!P[g2[ \X(~=}&|qVy`OHNo4'Ih>ZPw$C>ॻ+ʃs`/|# O_V֩GRU)pW,9d-</_7WAT+jbk p4~Oֆ #ں)МcgZ1Y#SFL}Dd!T5XiЧ]4ṣ5ZλVXN6|\*>)~(RBo_–/GeS QI0B3JXFZ=X25txAe {Tϐ28V {](ncx$D NAi330e ̈JOtD6^6̢ɵ'cdĚ|Z|V?ayar@} d w!cj6wYoα~OG0oF屳EX3\!98@,ZvʲkݞbC{@XjC{b|>^-{':"@OJfksX +lQRj+ֱ;Ʋt{Vm̬r͛gi{4wL^-8ʽ(UO< V^ 'Cl'+6G@GA\okЮ풋 Hp8g^!т-`qrjb$t3pį9L갿(^?\T0]~OV pʘL)h`/.n,4] AmVӯ9ˢН"8 T!~B&(?i*inrZpvhubY|ZR  ދ` 9c@V?Q*s4پP1FC͏!,A-Lt@G$R?LO|ư@$0 TECJ&*aJE>ʖ#,kUJM_z0!f Z4ƀp/-JIV1- @  r9 K *Āk$:˓<\kI^^{)2 @(9 1} 'X5#\\9x:T4L.N4f?xG^#׈u?чJZnA*Gϕ=e`ʱS4ʹa,p09<,IRݦ:{y)|LBPoT鶌O@\DjℹBgqc:VRDiRyJ+W)^Rl4P?jNa49Fkn\=f DR$xlf`gPXǴT87gcpHVqEճưzoV*6* * * * * * * * * * =NڟҨ-x;@\5YsӖ0ɇ$ ց&Z ڠ+ A%.=xQ+%" H2bp 'R]j-jK8 Ff$0fH?jCuZuZuZuZuZuZS%sLK4-ІD)b֝ZuZuZuZuZuZ3hgh [M1{^QuZuZuZuZuZu2u YmI9@A%#zuZuZuZuZuZu)psdc@fZtkiֶkiֶkiֶkiֶkiֶh|δ9^>S͊L?N }>_O}}>_C%F#-`^hJ}}>_O}}>_OhF.RQp8 _O}}>_O* 2eauflTa hk}}>_O}F4q:4g%ev_M}}>_O<ʔ/ 56S#$[zaCTͻX)ޏS`>E1r8J{{$>Zr^=6>o"^;lU^y]FGXtU8 پF|reJ*TRW b=ʃ^=6>o"^;z>`^oG5dQb{qh. F,%&hk?Xϐ_ّ̡qdL"d8y"BH<;?ǹ^7GWdQ_3KoXg¬k?UvE8ۇLq]S -% /"Xfǐ(`#yp5" *^YITh|vQ/bZ,FUf4Lm c#+-'vP5IΔ&*&W#޳Ez`bݚd(i#&f& $I&=[KnMq-b&-G#l!DI %8 mo 7^9xz8xOnqD<\gb49/eHDzvb,41i( ZKXa6Txs5 ċ1"`}&Nk(±=GȏH*OV d^S& XKފA;13ŏ(<ԭֵҷmS&mNJ5HCflU~ar4i;e OeԊ 兞1n!3S< "{5a@~YY$g2}4q1HviK{<')6jG*Çs8砬f*@ܩ`P ˞w*+bLlSqBr՛Hy2ZќL[v-7Wb(+e+!tE4/1ʲkqwËPq'c-E)_ ,\ex7I噖HFXPu:ceѓl -/bDeȢg. 0b1vO섒X%T^H!nJz M*m[up,)$DLgRG1z G9̒eAp"LAoXnccJ+j_j/CMSJbIȸ*Y"IY(bO$BA tĀ J&ӊ \|*^/FގaɵckAgwmdZ*]#eL49<*nr!YSnnkMe4C)va AxP"+ߌ{,PuβK(ͣp/7<7 -ݟq URL3QN ՘T$` -*T9b¹gm a[u78!2LhhUǒ,3MnpN=(L2Ɉ.#^rA#e ӊOaF9ϋco/ǶkKe&iRt:%?ǹC3cŸqg;0D1(%|vQυX+כxuaXs.L| _>mD$F:H9&5fr)`'3p<&c8,1b:.9~.ɲ6KrJkL2N\48I`=ؐ%,JTJ]^=ਊ/Jx_s5 y ͢bHFk(酥 [^c"6RKu1 E(4DpC.XLQs|Èܠ R0sfn `Ra,[j@ؘ\fG^B&>o"^;z>`^oG5dQb{5ph:r@9\B"$zd$H"D D@N:SZE<'gxmNٻӻON3۹lSzɜdA,^vl# ыz52Ro D XQ%r-DCdI͗_tyUPxD̡HKˣdF03 BhgH W$V6_>o"^;z>`^oG5dQb{qй1+n"KU%IjRZ-T,(Bݪ z]=U ;k}(5㷬?qV z5Tz~]vV'шi +` (<gxmOa̝Q] 5kAæ\#z??Oj}AQ$G:NH"$3O£ ~]MV!FR.5;dQ5 ~VBC(ny UNhec2ĭ>_6)Oh|Ю1:YΠrAkAQ/iWch`b'qGVcK[Al{CTQވy5v5 ~TĦ'$pɼl? vX7:T2q.i<5 ~_5 ~VB@@Tw7gxmO7*`6~BQ !Ej{iPŦ95r$pPFTPKvFQ !D(Hu,w4(lT(* iB)hvvfQ !A0 mY'.ʆ*4mڭܩ(R(P(,ҩ|ࡉPT(2mPG 6@ŗTJiU$f0Q !D(T3|6Eؤ6,40u75  "+7ԡ"Hp(2qCEB)҉^H[(p4C @K!݅bB:l(8b)|8&U㩭XIO / `jyؔ>iJ'8KĜG`BNg :Ȼ#Ԛ%_')@HȒ7|61`{<5փ[T?~mO]$4R~^!ph'G? p/h1Vds)v~ }ó@A& b^ c~iZz0IXwW8_L_8'1ѝCηJ߭߭߭߭ߡ?B$٩+YQjݦ&HJUfF$ɦG)+Lp' LZn:4J:pTbCN@WEVEb:pnb|‡%ҵIxXY"5wU+a P V91Cӻwy8 ֈOV`Ε@M#"z}Obo[n[n[n[.]?띶pBBlkmw+mw+GxVniX@!z澹kg޶}g޶}gފ}R P gѭF}kgѭF}kgѭzz(gfA ¼&&&&&bj)%a,Ƶw~2-PGN-,W׋N[.t7a`$T m2~j#Los=1 "~k@FJ~YMaCl QOx;?*('N\q8Q Pζm.",8p) iua$ܙ/04r)Æ 4bŶX̀^,,,@ґmȉlhu M`N%i傃!٬[|Gʂ0?jauZ/11z%}_dW+J%}_dW+J%}_dW+J%}_|5}_dW+J%}_dW+J%}_dW+J%}_dW+J%}A#'eT`Nu'06Yl""m=׏~ǿuߺx{C ҽL 6 @ ~x aco@rF\' ړt.W~˿UߪyW꼻^]Ǿ(0mQʋz]5?U.\I84A qThJŊK#d"!CsY H eq)cRK 1X BFc zI0.gb]DKDt6ru f$c(pk'VߥmzVץmzVץmzVץmzWVX(/1Wi}g* 1i . n5Ls0I6V̜+Qc"ZLxF A A3WHMA#*RnVT|"FlNδD]Q|Ƨ"$ДrI*AZPFQI9sƖ_P[õ |Yt~|T>w|0KI2%;گx( g jtiȸὪIh \dA:emW5ڔFvMBԜc*`2Ec'/x%|Ƨi`yDyίordU{R/BBlB{ԙxeM܈qD4F=ɑ,sehPzͩCbjX H'a22̀lXX 6@9EGh͕^Zs^ g B$2)H7/e,wp5/t:&ђ\F9 ̀1IYlj±*X/?d֡GZ jMGȫSb\ }W.-=V]B0&/y2)sD<ˑAE== (PB -&2Ĕ&ޣf*yĠjWX=)ضO4>TC"=) &5ɮMrk\&MZ4FG)MOIӠrJdtyh#AƋ--lU?iQQPU pF&;|gpŞ{Do?BR?k?Dd6DF.ktؔZ?vP 7"ʾ ,BKI)?"Fyw=w']+?.s)%)_dZ&Y +PYhVcb8ZUOZǞ-X`׫byDOn=W^@`@:@?#IHimI?vmBw{܁?-K6Dd@16nlPѢm J:)$I$I$nN:X"$߲ 1 IӋdH%OK2n$mNYa&'KH-H$oK$A-KlKk_I$OKc?}6 Km 'Km$mfNimg~j-d?KI$a RI$I1I$JrI$JI$ISKI$I$uI$6I$ bI$KI$I$tI$fI$ABI$#$HyKI$7I$tI$fI$ABI$'.  K $7t $fH$ABI$u&Uw6 t*Hf8Airˌ>o*, 6ot]f2{AY 7Yk!RI ~@7G3tNfa8A@B>nKkEI$7`t@TDf@$AB%d+$L3!ʖJt5I$7I$tI$fI$ABI$?J8 "uI$7I$t $fA$ABI$m޿Jh N6E|vMve6aR!3J?&v`4w@V&yqJ?n,W_4OgJ?RI lI?0mJX~KsD_JJ?UɹJ?^J?lWUgI$J??yOx$lˤJO,moamII$mD:rD1"?Jΐ\ a* ZIǸEJ?m6mmmmmmmbnK[5%,mmmmmmmmfn: 3&**?p'9?)?mmmmemmm"fM5Jmmmmmm&I|?J47A$@3Jl/J'_Jiq{ؿ:jsx"eYosʐroηʒ$Pֿm?I$۔\I$X{$I w4I$T01 I$Ci`dhI$",?I$; 0dI$*I$Ivm?o-!10AQ aq@P`Ѡ?a(1:Πh;K /y'i\K>v B e"N Tԡ "$mr'r-+HR.Ne%-o|>o2nɌLJ! }dY J)?1îI'_d] <}'5L4,D(5 A61M&vŊM# %u DnBQxKf ]F|Z9M`1A%H]a9nnCGpkmKXɀAǘXCM녈,"N4""TFD$ TGPjq5>_r1Ȅ/EcIRe8<fyLc7M3c_IԀ365$9RihG cDegEfTB͑ x4U6v$p~6] ) ~BD=AgN5$9Qi!]$Վ-tSN~#Iu! CƦQ;DS'hVG)dFvu`B֚0LKb`.Z(i?Qyz<#Lu=P$2GQt4л꽙T/ f obt: 2"Cb`.Z(| ]sD FOѿj.І\QBE lANi }a=S*\Xݭ YB@mXq28L jསSz:J]3ȱYs~_h4~oC_N/ޒ,?8(f`m7cW~_~r K4J#$i VaV՘P⚄"[=9>P[,X2Y-D+fA=;Q~h4~~сTvPY׊XEߦtKQpǸ?ŨL>K4q:7}Q;#A-D(\o07)BGsҕ81/4eRllwEcO!#$]= sЋ&%k-z)IX1]A1LGALK#1rDȌGY @5KO!#$цzJP-bCg b2aѧhý /=ذ??$e@K;᫡ `OlInFRt:C7l^3w @ % "8zh&7I<5 7#A2MPxb"ROIPgp#k?r>s/^5ٝP:žcQba_JR)J'\Kѓ(IGz-<-*ѰTa{}m t:c@ 2xz'dwz~Qx o*+5 kk}/x)d 0`)Jl83(2dɒɞOǺ%QIⴍG/pS,|J%Uac _0aC? J_ 2VQ2*)h#'  Rb1t± ͣw44so>̎Y(i3=SK DW+8_' c2T_x2C5Oj#PkJcw̜h^BF5|^0L!8B)yx> DoY:~JbDl/0^})Kze!D!B|!Q:w_ 'pɓ&L2g Z^}7'ɽk- ' 9nfB|frJĜ)p%0H=))y@-|!)JR2)JR)DJR)JR"S)JR)J6|R)JRGB8>n琉|!?|AŮ1,W+5g> |_>:(4eJ=hC>x>n瘷HWǓ X+ű$@ĈhYSGaԚl#%C:TEY%OvcE ֗Z\S' 2}0٧BlhN^ R+gB-1$Ӡ_IѸ$^i?LuS[yW E~&dF9؍2!gVa?pe2 U< ; Qy%Jݦo.IM9B#q'=!c>H%mя= 3!makϊćiЬmUyj 6nҥ3c߀>-d=j[ S(s`z3ax E)KzRVEO%cO_a(Nޘh1Q 2kQC- 8" BX,)Iטw \ C7XoGeqZ- QY+;F1q3tnbS,v'\wCM!MtشӴC>U&'x<=GX}ʅ6!{ Cko4B&ϩF̕,- C|V?=1&oLJ4R죹'V>Q( × '3(S0{!`yhj~e?aD6ѵ-p||݅F$NEIx [L4,Dȩ9Jc<|>qkc.y!B{ t7߄>Mc,eٺb2)eA%i,L&8 ЊͬN%l7hMegF*#^g  &GxNhz0/(x6FLË16n;`E㗃{F' U QEQEQE >C4|P jOUl,$/-MSPe@yTI6,j 5xI7`'FXON_444444@7־1:cӢ$\LGж'A3oג $CfjP&3F 2։)? őD^}4רJ:kllu#%L% ,?=Uy{ k %$b:8hb.ˮ-CE~È_3G>q3`,%R x V覵A)I}'\]Ɉ<d;wƌ$}5tv,4jAV6|-gF<㆏ "v'a; Nv'a; Nv'a; Nv'a; Nv'a; Nv'a; Nv'a; Nv'a; N4#HaŒס'Ĉ_?nF^y;_o좿T D]{ DDGd"ŏn 9dDv1ozA3~i/G JB,!B!Br-|!E"RGA;QZ_''.p|!Ers-~'-y4\}߱$K.yܝ;zyeYaeߞ >'>( q/35HZ(`YA;6]t E/s D ;abC!N_CM؜C|xiK_ !oA B/,N!A/Hy S< б떄24D}N;\!+io´Nׅ@0E NC.DT6[ ;<¼Z%U{fa:2!/ ΐ^ p=GOC-_F3Gz cBj"Pb4\my/wԼ$U&J{TszS ,z3/S+_r!5/BܖdI%w͏Qσ9>LƐs㚣\>JBPJ8-,kB'6!B! p'.p!B!8O,!1AQa 0@Pq`?e2,?@6OBVVEODC B ,{m4ј< r|AZd}n/\Rqg0 rMh_N| 857ڂOB|ͭȤp,FPؑhhqy\S-FDUyj)Nм&BGׄ$$z|8Frl2s'*0\ID$$z|761Yu-qFK-lJb'Z0OJ"hJSQƂChOT%F ˯8\YDpj <67ȥlx ȤRc-!tGS <dRm 3Lf&eQ`DoϩB S,O`%dP3csG՘r&i`Aæص QŸ{CrtBw@GX(&j2hjΌ M:@5 d+×Y:* n1ro)X}_X4].]h*T[lti:ŬAqI9MKf=N]}J) ߆}G66 &DJwDCb.j4eV4 >@',6F *li#o崆C#`(_qzkn R)Jdɓ&L =pY|Kd]+Ol/OѪ:!T-f7C: Py߂PϞO@q(<~"(PEv '#hu8LVXawՉ*)Moe9M93ezB)JRp!=0(L,TXXI ˋӱ8Fgj PÃ. yߣ$/ouɳ3/OHRǠ2gJR)JR{M&R=߼R)JRM%!kߥb$RuɳY+++++++++x%eeeeeeeefJTx%++++++++++++#W?A"eeeeeeeefJ#_  Ioܕ *o!**********g#a{Ξi߽~)JRw\> 1-׋/B! 6|26c߾^Al[uH-olĢ+JM&φFL{ۋh-bu?mV(a`):1Z0Fq޵tq!̦z5cu$l8+Y $-.L{M ] ~%?`x$Fes4CZ6\lZl[!l\Qr|(REwhYgA t6 p(7`]Kv .]lB3u^aP߫ !'pO,cҩZ_ 6>v Gc3W+ӆjYB먤}H^~q{l^_'+((7\hՉepJC}v$^(' "')K cR\R kC e)JB b؈B!R|>fʐ┥)F}&ᐘe=CR4VWfՕq[:7pS+cE{eee|ߠB ފA¬4&JB++++++(m&Rku,*|3c5ȖvpC>LՂ{2V nm8b/-km )loӲAX0"0LoqR..ޖz|>wLN m1w!_vb{ Dc3{n7!f8*D֢iؖ %U  DP&)_rn=ȈJ${n$1a$IuRn׳!,lV#$\KEQEQEcSrn=i| RhXYgED4CYHNuKA(D%t z T-IdY؜dv'a'akrlg|ȿMGA##?F~F~F~F~F~F~F~F~F~F~F,:8&t2Ho"Х⟑]HJ oqj0 mu`F̍:#[?䕢a >$YEyXrl!9DH` 0Tr0` 0`!Px` 0`٭4?{\0' VS^Xb27AV#Muf$GoF޵8F\_m (Uݲ>9شy~G癔ĶN!kųHuܛ>%~m%=1uCh%RIF[FQuЍ1KcdIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIDH\MFf&ɏc$CyJ  wNӦarI! и7"-mmmmmmm,##F]#nNܱ`Г0awg%\0[EW;MZo$,ఴN)JTTTTTTRߵ6wt~$kH'>>/z)JRrlh}*M=z_f6tbF ~~=rliע!Bۮ_к؝K=)&iPUS`l,eAbR{#BK \B̼9x9#!n <Pm(t(\Stlmj8%p\-_iSGOˍ;?P%1n~~z{ QE;CCzQEp%?Mjֽd09t,ߵ\B8B\I ?MjPHm̸4%:?M-lKimUXcB0t@&'u.BT=yc ?sƟ߷ 'JNDDfxPѦ0d[~t,АH46͗ڢc=g-PߧD}i>"^ }:}FҔ)KrLRc²)JRW-!1AQa 0q@P`᠐?;_>MW,Ep|0 ^e Ҹ(U9¡h379jH410@@XH%^yـ0@ZPp~xMX 0@&Y+'hPPJU-Ⱥx$@D&`S%D8(Dd,Cqx3U 4 @-[B,p o0R4 ]0`R0@)\POԂk@F΀ L\ ix .cc}oZ -P`U+v<,p oTD/0  U@6 Ux\! y|@ER2a!n@ġ ;`JOp(l1_hU,453 ă@&cfvì@k)@l!$@uÁ0 i`b P|iF@j rupUL;H@FW$!O?_8A$ @OI BF6F Ā h~@ )0vxAr \~2@v v*q9`!:P DDƬ$R1Hp'O&G;a `j6bz$g . ]t &o :PY["r@Nx" o`. ]t fo *00vB ba 0@nVgw\ ؠA^F|P@ ..1xHZQA ƒ3 9bFfcL7802@r &&M/"]'^S`Ie@NP2@n\ðEkWK΋ I;VY`%23@+@ Y&c,zroT( Z(%(D,Y&c,g6IB` XxV1&{8ލh6B *7VX0F8BE81$\h@ ˅Ӕmk,&U*D BIR'-@ ]4"s#@4HE84r0h'mUT@$P4b#7w`Dפ DE t@{tt<[6n:jXVLTL Ҹ#!lu$-;YjLf8,eEA$,WbΪITւ;28t#@"`_:rѨ?H"9R.@錢Q$oldyfW p({kTѱclN1 gR6n g!K,q= aa FP#ez`&mE0ab !-,&b6B@ɘ=vLk(@L7%MiƥA+01m|8 k‰fk̆`:vL*jĎ:YAPAH[2kb rبqȌFp~U(<`E4 a&. ~_J*-<#md\#?}nJ-"'CD/\W%1h"RPFmOTɘE WF~ P&s G\*mKfrIBv΃&)>)b$嵰!q6 XD T?jޓңjKvp C(f7]`!5%QkiXeҮPnIeDd]尽^=aސ=xIaeV"& ka:56/E'P< l!o^UUUUUUUUIAY"|+N?$ l*VeBP-dl̺"3j-2nE݄$u"D$Hpa Yy|fy5/ eD q[`6a[p RD$Wz:m2*@5AZlc|NDͼ)ǂwd>"3|Fb .+ɒa[ 4ٱI^uÀv &‚zꑿD ](56(޹L7[T[e@Vp$j0%HP(0  5 Ap X_١\bb*O\˺NЍT Ɖ!3=/:"d9BH, $\nOJVPS2l9Y`;"ź{4(tX/~.ELc  WHDY 1RD q4߻C""5 @;WIqo @(\6 Tj0Jv EoY,LU[ "@e_)`O6*H,"bXETCa'd,_bSmIʅm1r$2&aCP P 4`ɠf[v ޠ~[@)&ױadPsNIvFi6Zv4CN BZ/D]rwXZ"@RIcyEN(z#Pwb寠cUJ$aDpT*jd2p "0c J4m:ð(w&<PKؖX3ˀHQ눁@Xp@`(!p~#\6 HB = Sޯ&T;be٨*%3Rjd3_JoR ސPQ +)15(8K ۗ'wSN2iEI`\Y]nLIJK%Q\VdT P/pF+7S$<@FĬ#EI#B~ E "FPWb-MX!wvbG,+&l.^BHᦤ4k?l&)3XbD+ :jd*ڟP2|@';+3|<J2/Bۄ@Dψ <}:ad5/X9(2#AcQ\Vc&KIYKLv6CHΠ]5抽aD@P橉}:X-ڃ.dЃLwJ e"]\ #-D@e|>O2dɓ&LJؕRxUࡑll"`P"d}pY! Pv΂\`6Cd6X!wG6Cd6\g / x ăR`dxQ.˔ 8E `$p&llt(w-g- 6&Chm  0ap̘m 6DEL0[1^0Chl0Q4;6ӅۛChV4!G6 ,Ɇc[&6L0Z"# `O?p J>}(`}`is %889j)2*^KH [Eِ86u8]2~)@X r@* ^_7aS `H:-$KlCSF3jG찑,C!=D$7NPHd2J*TRmDU*TRJ*)ԨZ\ZRJdY,>/A TRJx( Q&H6? = 79$`?9Q`0VF /SP^A[4*aЧA0~/pIlP@ V"GHAY0)",jܻh(B` tZ-g<+gJ/s5 4op8R7R !@GND@|zH G4"U%?U6i\P@E9!`;*$N7<IBnQ_#L"*p"u *[ʐ40DT#£}fC L *hIv "BLx.''!:` = n ybVJO\B(_dZ 5 bNGE@CAoȷvM|3$!zDi,IQ|ݨMa2\2d%vLvHmd+u@J+n󄠁ڕ*T Tͬd6~7pMә h8@%D (rDP.%װBOA@p|BRL $V=$CMm[b<إ'n4>/N6XA`aj?㒴F9IC`´Y'Rp_hhPQ ,{d55IKnP1Y_ [Nˋ-E]?HFmjFDLOa|ővǫl 0HiʉHGP j D_pmnp%h'OTf*'УЉeԐʫr; BH!%q]8)zr2lR+{ ci7LX/&͢4o=laA*QlorF& l:ԴGTT 7m7q~8\>3C]pJu! +9_i8'c*Н$GꍂhdؠTnE/RF0HȣrQfwt#PYX|ѣF4hї#CknH->#87t`NNE0A=aBB/Q D"B!D"?_ O Wt\.lmlmŎg2Շ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/essays/discovery.jpg0000664000175000017500000025775000000000000022625 0ustar00zuulzuul00000000000000JFIFHHExifMM*>F(iNHH02100100http://ns.adobe.com/xap/1.0/ 72 72 Inch Exif Version 2.1 FlashPix Version 1.0 Internal error (unknown value 65535) 1024 768 C     C    蚻@ ' =OŁ;^VV^D@n()OKp_δԊݟUyT=bV^00dS( &B!2F1IO/rٳF\26t&;뵰gW;"MNusQcn*g'G6g3lI1յZdm @c-zva~5oy{-N͞bGL=aO=2㿭rܶTV|>P7d2ny>qK´rr3/?]PN"w\w ^pio_zƟs=Ku@)W:|6y K}sq?/vWrw/o7wv\OrPu>Lʽ:DPt='ޭUJ'Fţu51ɵwIߝys]_OOƼ_soe ΟZڛ.TH)W:\+6y#.fzɛo~_ncM_fÛO2`*=mޓIu]ZǛ^wcfzSHbkfL~0B|9ˣz^SPSܟa;~⩉unꋞO?8[i g?zyJ_3lV6ٹ^H/[~zf4U=%*z;'q37ӯ6|a.nBTcKnqT>H6lBgiz>)}>.[e.ԥ^owк5mi\7l͜mMRC]n-6^20 K. 7.br I@HdR2Dd% @@& @$H *Cz>x YGLdzN2-6yu^@ f޻패 ]ـ-Fڽ>|\_QSH J,k qk}o3ꊟ@JWeye}S_A`$$%Ms_S& 7K]P s~EO %+.wCkXX8,IcJ卉c]x6-}O ǣ3TSZ{FD$c^RϒK*~)]M}{ʆn{:nٶ֌=_Cg>3vܹȪ+ugwPls]dqk}1?@zXNʕLS9&en6 檊}*ݐ.M+(D7K]P s~EO %+^}wZst<Y[jV:?oi|¿1u gI@%Ms_S cөh<7_~J.{ި$vWW5geI 1kd qk}yb>]/)tg@%u?DKț  x.(zP_TDW8NG S[nZn;/c`F?XneeeKD[}>x@ "Le=TT[~#7J/dJj^q)ꊟ@+uOf yĦ EJ.{ި$+_FnJj^q)ꊟ@+uOf yĦ EJ.{ި$+_FnJj^q)ꊟ@+uOf yĦ EJ.{ި$+_FnJj^q)ꊟ@+uOf yĦH%Ja(z$^q)@]n6[0|mo9QLI2{aeM0QyĦK*~J?2EEU7u=3W{Z6v#k؈պ&ƽnmc1FkM=ImI%0\_QSH2vEck?Wen% RĐJjW|.y,uKW$כNa÷NM<BeL%=TTޗ_ ]3p^|ۯiFZH6TkV[*}3vΙW^y@/8 @%0\_QSH'/f广K\?]zcuZGKuS ]3p^t-iUz[wy3\պϕPeҺ;RjN*tw[y@/8 H!$I>@L%=TT<٢種onq5eCw.=+t:J?&?m&퍗;Ow7nOKb_*0s ~zBo>{mh5wl+eyʢ 2Eg0WҳɍL"VlݼIf%0\_QSH%ON;@%vV L $ X✑/8 9v"~s5Mwm5V6k+߱,r¶c]H^q)ꊟ@+uOf yĦ|Βõj׬leoT~mִn ݌ϕj3Zk{HJ/8P s~EO ]3pHST?8HiΆ4M7+󶎧ͺ#fάLm]@^q)ꊟ@+uOf yĦ%\iBX(  EJ.{ި$+_FnJj$" EJ.{ި$+_FnJj^q)ꊟ@+uOf yĦ EJ.{ި$+_FnJj^q)ꊟ@+uOf yĦ EJ.{ި$+_FnJj^q)ꊟί_Nn%5HJ/8P sޮChKX^l%0"S S_3s|[t13/?kVHz J A (S\L%=TT[~#7L|^n85mw%6וk׶ݛ4 yĦ EJ.{ި$+_Fnkϛu\M3(k]:;Fʐ:}j׾keOF|c5[uߵuo>RH2E9'(S @%u?D%vV?-ysضUAmXέsV>UAJϏHTJ# u81SemIHST9Vogf6f\A$%0\_QSHWen1my7ll}{uzz[QNHmײ6;ykGhc`[/-{U/8 x浪wn|l/-qg#^q)ꊟ@+uOfB e,qNHJjE[oJzxulܽzvػy*%0\_QSHWen0[~$c&Y1$^q)@[SJj=SSᲔ<66٪^q)ꊟ@$J?=T{nzw @tJ?2{brhB&5VyV @"MR ;W^fN5]ޜou:r%Ja(zDlkDiٲnyJkt.ײ߰,rt}mm|cqcw+uOf$;l 2ؐ!&&F,L,س2EǻYSb[o}ήu,ܺOGpF˜^q)ꊟ@xDm{==wQ!/Qd%fWenwk(~F~0[NZKV5ذJUw2E  L"ID QyĦKgd#ܠ/sk3 ]3pZ>cmyh+_alViU/ao̸W߽?7Ā yĦ1ɳZ'se>(S @%z;^:мKJHYv99֪wD[~#7 ,e}_K<5SaFSV̝Qg[Ӛ3 1nĠ$^q)@&X_DWsv ,[TP%0\_jؖ9yy*v`\y.lz=0|ڸzۯkڬ;|!WXyXWvƳʭg__Fn8 U/\Qc\\X5!2 ss"MR+]Mv7cNSmVɕx{L%=i:}IDy].2a!gO[ljuv׀fٷ:kjU;[:NwDѝ%G?I/<2ZJAbdIHST *~w<NީgFު%0\_jXv5uKպسʮuv?U25ڏKzә~Xw5[Vj]]/ƭ.uOm=o)追Xcakkʲ` Jji@gcHMv%TL%={Uo78ڝnoje1Եt[<1hba?UW-]^3ѩa~13WJ˳ҵt0Y iZ:V5VǶNm} <\OTT2EIag{^tJ EJ.{ި $y9WƜV5a=%\);g2gHL@"MRadbb L4ퟍɖ,D LA)X%0\_QSHWen5=W+]k}]=:s,}+3' rgd%5HsXqbgNUyaksdnʐ^m^55~k\i[QѳD&+^q)ꊟ@+uOf 30xH$$B$ yĦGac;ں6gfNVeucm}1,`L˵jzNM]=QQdaa3&Pnز w 65^q)ꊟ@+uOf>d$^q)@\OZylmw<86գeڧ_.5=-=ܘ=ko!;1bʬxzlbL%=TT[~#7$<>k:Fיt^[cRLa0dB/8 1'j#vbK3&1jȖ4OˌqfI`㞍[3jEhݛyz6&3c%Ja(z!9VM4EYut:I8չ쫥ŝ{]c $^q)@$#$J`"d#d1$@e.tyȬHQyĦK*~J?^c!kv'j[8L׸߿p+M]3yƒ"MR%0\_QTL@W~'7e]GBƞuiZVyȯ5_z6>%5yĦKMl.(8ni_H%02 @$70345@P6 !1$`27"%#&G3tCH}IRS`WM_$Z`wZ"Ӂ[P}'ߤMߞ­`Zw^~.(OڥMwL[{2~/KV_sg=rM,S:9[P Ե[)i&RLi'l,%.[ӵ@3rQ%jZw^h ~ʌ*T1'"qҚJoMY,Hkr>URy w* W`E̦fWSR7U|L@tDHJ&R菐&ERq"ln,!bвTaW'곿3g7GտPY֨$T]ϊFX]\21.V Oڲ6;h_Hp,PN 1{l-3w)kwH`{NSFC}(.'?էq??ʦ./_$F6*y',ݦb͖o1,yz3{Rqb\āB2V J{v:)~*OWJLe[rIUXPV33n4d3Smpyv,Rҗp~Z&Z13BxMCcmHaQ99tDL;s:\Pv;3U;VLȵ?Oنa,?2QG ^I vd7I峬hv^m(?L#z˫V+!a\0@wpa0%=qևSsO<)~! F).QC_2 e/J]nwWt=Ռ"ežL,n[F2Ogwa[~oӭuN:ߧ[~oӭuN:ߧ[~oӭuN:ߧ[~oӭuN:ߧ[~oӭuN:ߧ[~oӭuN:ߧ[~oӭuN:ߧ[~oӭuN:ߧ[~oӭuN:ߧ[~oӭuN:ߧ[~oӭuN:ߧ[~oӭuN:ߧ[~oӭuN:ߧ[~oӭuN:ߧ[~`c̙t5mTNQ:DUTNQ:DUTNQ:DUTNQ:DUTNQ:DUTNQ:DUTNIH@̋ju֪'Zju֪'Zju֪'Zju֪'Zju֪'Zju֪'Zju֪'Zju֪'Zju֪'Zju֪'Zju֪'Ffau}>VU繑?3-J}%G\>]H ҇1?q i~_q H ۫2ll:`/dc`J͒@r-P_ ?*|q`@FHV[+mUb!HeXK= DYWDL֍F!znƞ4pFشYrRٜd P&cuc}͚=sqP-2;G}#͒AX1;7f2(\&QY\`dm1XR]lrfWe^{**FRa,|X[2aqB%ܿ O1e^N XªgjkK.ƴkK.ƴkK.ƴkK.ƴkK.ƴkK.ƴkK.ƴkK.ƴkK.ƴkK.ƴkK7wZ]iv5֗cZ]iv5֗cZ]iv5֗cZ]iv5֗cZ]iv5֗cZ]iv5֗cZ]iv5֗cZ]iv5֗cZ]iv5֗cZ]iv5֗cZ]iv5F)s.'ʳ-[DV}Ŵ|]30ȟ*ϷofWYӭw"|>u.]_dOg[N3 ifau}>Uom:.'ʳ-[DV}Ŵs&Ǟ E,=$ڳZ1 ]Ɇfau}>Uom:! M jȻ#DUV`Y n~^*K(mgnX ^'(nӦq⹗-D jM>Uom:! ! H*Qb U\dOW -C?$u$(CW݈ f{&N3b3.ߖN& :L;2qŃ=LtMr3*Iɋ'ǕXa"Hr2n)F*cN ŦЍNJ4|]30l'8k+,02߸Gp&Ej[,o''ʳjtXKUf%ߧq]a]~b;\-2ߗvVDc@~Uom:zygSYF7ۻ˘{g^-ĸE*o:a0!loNWoyn7El.'ʳ-[vVlme&%_YĆXc$9`E2jI,gP|p>&6O5nQl3 i~h􈅁D$.'ʳ-[DV}Ŵ|]30ȟ*ϷofWYӭw"|>u.]_dOg[N3 if`>Uom:̕@rڑjV5X֥cZjV5X֥cZjV5X֥cZjV5X֥cZjV5X֥cZjV5X֥cZ1>g7U+RU+RU+RU+RU+RU+RU+RU+RU+RU+RU+RU+RU+RU+RU+RU+RU+RU+RU+RU+RU+RU)nJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJXӃrqi#i`yq⹍:.'ʳjtXKUf%ߧq]a]~b;\-2݋I\#G&i hJލ30ȟ*ϷM̫Dc3aѡ-4z_OkĮ'I&t'hVݲ-r)3A30FF+FV}:[;NŚm@*"LЗ&yGL]G;,F£o#ƙ[s_su.]_ٕVS%s$WB$<pnDvT@跃M\6ˉi|>ߝ0^Ih*2E$Y]7nFhLi8ei /}%l]%ݣ>30+|&( LPA$^+o/=4EH fH3 Ob JGH2ycS.bpmo'ʳ"lͺ;C#ߎ;8eOUՐ!R:CEF$](ez!`N{N`m1 E:Ze`f^2{@{,3 ^$7YŁȚKпfWeo}њftC>1#!2l*HWOXG^ԉ ӑ_eD 2HOd#c+ljE[˔G,<;#P1D<r/l@VHa"ϯXvD.I0Y$e>305&0Iˮa=tY$"_pp[ "Lf/$e.SDe a"]"gBʹ ]9OgKKyf` Rx'⛻Aݔd`V[vռ֝oCsSՓ] ~F; ,HmcQaOŨ#Ӥzab|>ߛ'f#c0,,H5&a7j8+egY?Y܌k>cŃRteVty:*p'ʳZZ@CJ6 UŲ^)G@ѠQc[Bfp(}᠎1&]ݰ6+Vf.:<֝o_꿿J]`mz`ubw" }YMz|>ߛ$4"2XG.`g˲(X=dx:@IM$,ͤGӭf 3-ˌK(*Ytz1z7>L0ĎV2]5J&%ȸ71Ts,`N @ema]7|f1$cV.1U $qh2d7N٬q>UoQem6:nm~? %ej7Iw,ynZmlvV}m\oJU(>(d/l}ؔ$tɱa f4ǥ.c)Dxe^91oe4ۊ& !@!ȩ KYJ *6[ۍic,H=4=Vz4'urCAXNA7?RXAX1i\0*Ϸز-Zɿӭ_uf>8TsO3A\j7GqՌ}Ś~J!s;-i& ]dsP(>=""Z18F'g r$k9/r$&؃!chR֙9 "h Y $e$vP+Cn=FoJG@5;-AQCUv G_3 _{-:߰^4|XYb) XY C8LGdj=zY$ ?Ui{bkRbgnyE)CGO`2y7ы.4b* Q;%.JFƄxL CW!&6XnFR3kaxEF.+XYm`_3 Guju-cH?r ̛;≯̡0#%Qޚd6fbxiA.*GDeCVc0{,њWk`(_!$R|?pX]jhxs@Ya9{f'!m30ȟ*Ϸ9b5-U9{~N9r, &X/f-Rfݵ7}oҙlɻ-N>5%4Aم6fݝ4B4TZXh d6Exa9G Y7cecAIjV~fau}>UoDXcϧnF%'0$%3@d87'64{ô0l})`-D%ʿfWY5a˟Z_~(8XU Pq#HF.נӭw"|>ߟDc@cR"\Bx%vYjv`$̔'׆铮FECӭwqJߡVaZhfVaZhfVaZhfVaZhfVaZhfVaZhfRPH+bSal:UVêu[al:UVêu[al:UVêu[al:UVêu[al:UVêu[al:UkwcVêu[al:UVêu[al:UVêu[al:UVêu[al:UVêu[al:UVêwC8!1"03@AQR2BPS #4a$`rCq?]nY~~RkSKK?xZUV)zȫ[/2'K-gjE/?f~Co!d, 'm9ը;YK "J TS"]EUO1W5 39Ő'$<1[̹ljB4Hr6'>QwͰ]dS\?ը;P;,W7<.)!H;j-lL.CII (&! ώX:&)(caQ=IPBX'RD?Zo<8ܭVm:f53=7%s"R}&_hNE2jK̎9yERȓr)F"HGJ5_Zi!EsLsB9C^m2fdjbgDR]l9D\bqe|nWCb=i2rht)۩2!P{,Z)qu }=Y7BGLȻvrai'Cáκކ!6V/pLl-DW4MSh7 ˬE:{\qSJڔX_2 1w-yU.Y 51-EܧZ+S<N:)Ppi>pi>pi>pi>pi>pi>pi>pi>pi>piARK"e8}?ӇNO8}?ӇNO8}?ӇNO8}?ӇNO8}?ӇNO8}?ӇNO8}?ӇNO8}?ӇNO8}?ӇNO8}?ӇNO8}?Ӈ NuMʝqL!LIo?k~*qAd_AKpTN(?k_2_b]k~*qAdj$p-S/ʦZ^e>Dì\vZu($^)+;Cuh|n"nUW̠5uqj\ sv%)a׵K~\'U=ӊ'k+Ejļ| lSԤr!\:N,1{/"dcKӪn(;ը KCR W!KR+uyn|O&jj"eZl#Z)Q63ЩlM]wB)5S2b(rwfIr?_P;\AR+ŦGC*D!EN36)AO "TIIe0ߝZTQp[*$Lu5/#1*2&dW̠52u`s0=*r[!SMV:[fs0]-Z-2,F1.~S82v Pղ.'Omj"l:qIZzM%T] T1@⮣9f&G7yZՆPf!uI;c \W"20F'ٝI eQCzw" JcbZbRѩș$S ܣU0r?_P;YTS2 VBll R6=#b&%K) 2#a~d&S*dP2kz3 cV#FѶQk#l3 b!O@qm9ln%O{NssuVaءes}[\>m* ~|Okeqe77CeS*%O{OAKp.\r˗.\r˗.\r˕*JP/\r˗.\r˗.\r˗.\r˗.\r˗.\tܠ_ߐr˗.\r˗.\r˗.\r˗.\r˗.\rb]kA˞2CK/:CK/:CK/:CK/:CK/:CK/:W8IJ8֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛֛w\777777777777777777777777777777777777777777WBY^lXcu:Xcu:Xcu:J&bŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xcibŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,XbŻl'U}D~آ} U_plQ>~*_(y~W/O?_'pU 8Ob'U}DhiBQѨ+]㩴~fUf)j*,G3eBʩu!Dz\ZRY|N~آvnkH|S=L%е%w2EHJ˴OBؗ^U踊dmJ$˲kwE)8hm}CyNKpUFp"fBD̤5Md-nί^n nP'k洇ȫr Dbm3QR*TaUUIT˘ܑ1S!T" \j@vy,"y'R wX\-TSA4cOE[u}1.T"7a[eKD˩+rSbIrdplIyvj'kCQHj.Urƃvi `cȩ^DTEѥ|T#YPl4||qW*J̍Vz+z$1Y">M?}?ʥGVʽ_p|ʪ|bƪ$+$aXΨ> Xl9Pden944DCsNO@)`I^4),ʊ%=4n\6t#"܄EzSeR<58OyaI:4hbh C˪GR19,()rcW/k3cCY)*ʝ)J#]FU*3bzF"= O_!^0îRiԩVԡ[>$NEj͍ZLYLC<5? %KL5k.$:=[.S ڊB.xĮTb_2_pvR'HR˦Õ!rBhI=ٔ"2O! \-nYBm5#~*_(y~W/O?_'pU 8WS93fo7fٛ3fo7fٛ3fo7fٛ*\?r˗.\r˗.\r˗.\r˗.\r˗.\qD.\r˗.\r˗.\r˗.\r˗.\r˗._S=t΃7: ߐ3~C7: ߐ3~C7: ߐ3~C7: ߐ3~C7: ߐ3~C7: ߐ3~C dl+wy,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,(,Xbŋ,Xbŋ,Xbŋ,Xbŋ,XbŋvO  /h} U_pK4HVlR"JܯTؒs(Ĺ[F]'U}*VOTTb:)adUAg!q,ӣ-GI m9D- s8|ȟe~W/jݔIcœs \-Ove/ȫ{2LHCW [D#MnHO&GS\*d٬OQfD*uT۳Q< -Hgl6 n|ZgD(iWA??_^Kun9 g:'Y,|[r5>Θy.gO[$Rebl%[{Su)VyX!5s]2i_*]? U_p{rzTyۗQ<L>y:rsYhUU#5wr.{FIu~|3Uu#:"XgOcD/ xrAV #sҵoq~dOG=?_]ԭt<4W-clYÑ̹u._R51OSkmPp3Һ&^mjS#TEJQï'=F~K\ӊ5tinxŬ뗷ٰZbʋbi27"E[O"T2nJM;a&!|rr-8U"䢑ӪsWNʪ ru )NGuzo"ͷ#ma26;#n+.?E0+LIb}ZFȶB9"bAy'RA^J1I>˄żmУz[HJqU"E#Ȇ#Q1d4 #Q'u*j5JiA.Q0W(f)QG|UEBE%sn)-sræ-Kt]RYuz++"lmI2VU/nxСI*XezȄTOо6f27_vG)%U.W?_1o"aKgL9/Ot+(cJ)%Y#qK;e Jv4L9 7q:1dQJ'FCnc<;Qm̺sδt\wNcstOE)*VȖ3#V7PT6($=MST@ʥ։*Tel+?TKs~IprR"X(*EzJuG9J5d}Q2CB[tR"uԚ,? T^[lvmZ5VT:c2" nEH[FXQQ '!r$P誅jx&EF%V2dAd8 ]ngy.$fG%'TԹB5:(ڨW/l nQ (nu.n¢TUN:T0"{̤ycڨ.b5p7+#IeҪ[_Y])6ctwDiEuIdI8H 3\V&)H)اdRybQ،Ze=K*7i-|-\ ifw!1QHoI1R\NQqHd#dK]bS61𯬮^+H5FYDC2oX"H#]%ZFr1$DÿbPtlI#mVtDa}ًwWƮEBZoWɖk*A:2_I4uQ.U]ʈ2_rUl'2h^e)o16ݺ괉Z-Fv5@zru}:`y<,*t OE;j: %)h2JDYfmpֹzX]bY2:-ʂ[*vV%;%)ez\V&E&/ z T@pR*R#dtg:ҭεԞbS @XbS02J:ZۡOLQIVOckuϙB*[y|]9͜WDVZjtb0̲!b*L A$tRc$zMʉ#ݺyupSr-s>'-bŅ X(/3{d6O WtziwkLg[KdQfe$vo5($F+c",WJHT=ޑ*)ŕ\J+7QZ㛗a#|*h\E: \~C(R=W>Q-d^FPV*sAѪ WsAƩS(IW*i Ԛ+)ĸa)̋{xOM17۲n~]QJ\cO"n~R+E*ڙGhrz,J9#)RkVGʤn$reGY iTk#rPjd#} W7:'P2%25@-C*$I[$'^h=.x)EyENd{[/"[><924U~W/DQ\*'om:IPutA֪Rs8,> r1\ޑZ-3̮(2w8r=b:%BHܵs̮1EcA:tDz K̑Bק2F9B5B=esV$i̤tw{|ܞJV*_ZI 4MI 9*uB=lSEFU*]*?_2d(ٞK)*dzUl(f2Y ug꜌($ʣrȬ5\gTAgwEz^_ A&u9I*\QW\-HA$AU [̫tjy4+5(,ɞEZ8dKT+|ЦZL-<+- ,5ܑVv'r |6R/r* *lXr._}Ȳ,mᰟU [S)*$2gi#1Ñ&܈ҪViHKEd)[ e+.u8O(UԤȧXS*9s4mkAլdv u ŚaK> dS6Y.DrK'>tq=O>tq=O>tq=O>tq=O>tq=O>tq=O>>wZE-[]lE2!012@"AP 3#BQ`$qD4a?mY:Yo/"4Sx*mcb Z[>ߊ\DF1bkKFW5!N7rr_ut<׭'"??߼:R*őltE42U5a cDj:~ِwީrvB&J.Jzd?'M h'j39UDG:8nVL|[dPǂh[% jEhr."ZbRjDeԦi5JFZ},h8h[.X9jv(wJ:QЧRĖ N:pX \HFVHT4|D,/oTP%Q#7y<IesqBOQR7E98ᑩqDtuj(FJ7B{,mc\}Jd _] 4*7m2she8i% FF޳p8j6&(XEG7$/KժD7:zU.MYiE(?YS,߭{.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,XbŹ*i?g f7پo}f7پo}f7پo}K+R7پo}f7پo}f7پo}f7پo}f7پo}f7JF7پo}f7پo}f7پo}f7پo}f7پo}f7K)sk  0` 0` 0`m½ 0` 0` 0` 0` 0` #km 0` 0` 0` 0` 0`$ROKgy[(^U/VWn߬ӛyTa[sij$x,+V,Mj*RJ%JRViSTإ !]4`,"G7~·ЋWN#GQ8ݏJtY8`HQr :MH (F+v1H3"3}I>&\98i/Q⼪_9T©1P=PiڡJJq2z+2iMI7ݾ eFq:ZfW&N Q}Y;2*{+ӛyTa[shȫ h\3$"qUAZVtS_ OW=3+JVe)p*܊"K$pHvqA!h^U/VqO$P:(ΡR;*\ʲUx.%:E:_7ݾ :&Sb|C#] uټڷJzsx*+~mт SQUju\cK$F7ݾtu,]3тޚN+ʥ ߳zsxM/UWn߬ӛ9i7nuF7QnuF7QnuF7QNcɃ 0` 0` 0` 0` 0`t0` 0` 0` 0` 0` 0`WF%&L2dɓ&L2dɓ&L2YUx*p}dsx*p}_/\+ʧ>WK7⼪}$sx*p}_/\+ʧ>WK7⼪}$&$cqwD]zקBM WO}>6rW> (7]n􎥺qu-";M].o^26єJ.]>˘%͜UX")ߡÿl)~WKHWseLb)HYVl{E\+*MEԐ9+ߴYNZ$Su>9rg|ԃlMVDagr)SIeetK)ԥq+V"tJJ\ RpRB?GiBsÓO}9r7rz Ӥ+".&)ЃFwrEIh}EY*MʹE.rI}b\CY;#J >M>T)VCKq/iԅ%<cQL'TV$7)t/.oBVPv+;ՊU>cɧ>HKҤ52ql(4$EYfnT+-GV: ӁcK.Ҝv/*K'}ӯ9sxBKؽΧCq|}c˴R,G`!6ͮbNzcq2 e$EQME6Y7 FO}TUiUR\r%$$EE;X˛yTIs\EDoNƟa)Qm.6ݧr4RtDnʑl5HmOWO}>䗇a_XWO}>.oSO%yTI}b>U>_XͶy={y={y={W%yTBz&M7o߉~&M7o߉~&M7o߉DFQj5FQj5FQj5FQj5FQj5FQ$Qj5FQj5FQj5FQj5FQj5FQj>U>˘Kx*pr"c˓>H3.oSNeB1܍ܞt*ȻDeK m QܑRzZ&!QVm$ʓjƧrQK\^\+ʧ>ʅ?j(iz%M:s'j8~11Jē&.[RWO}9hHjdxPhHͬ 1C7DVZua63䗄)C< h.oSOo_KåWvHtC#LX7?y?$:kWWGRVBu@E\+ʧ>;ŗ ?䗆cHxK~Qf>d^^dai?#ҪJNآ(b-=1R˦FW#8d&Դq7䗃o-sxâ8VV̇M"[*Sh hNצ̍6O>AtJ[tR8op"vUWPeU*{ޔ7w/53oIw7xRyRzbRUw@׹Ch!aUJ=((}.ߍ>iBCg &mFssI7ltB$ȅM̨RwQ hY#7FZfq+pq1S(exHG%tVpW_Y8^x=_>JV^DV/YRSZiJ%UbP֮FoC8b$R;EMQ)OIVw)V,p͒*պ!;IVA]J)OH<ӛè֎U$pԵ;/hS%48pD~?Rgp,ZYC5tXoK O}9$)bfQ.\R%V^>ߒ^Ru޶6B-/q>_0:bzEef0J?pV^bEZJZ#fWKKŪuEY؜o+67E?؎&%WvFBQ!BdS*5 SFÓͭH ; vT:pfCpxPGoE6\^(1V"m՗Wb)NK07p=˕ԴGJMdU]a`9)-5,V{(%J WF6DcO}< B&/䗇쌧!e"k/ sxSȎ ;aMs&Ai$FZ?^r! d-ٰ̊.o؈M'Wr%:$PNŋ\H,T-,Up>"-TM"q ]djh?'V> C .^+ݳ#Ra.^-!]5[\+ʧ>"t!-pF:bTM[ĭCìHD%oo?&߃+yTӟ$̌4@;QriuUENHգ"ĊzbY۶%B'; !._)ջϣ;5KKyTe5o'Q^?n?b]e=e,LY--Ed#yHۚ&f؅;G%?}7FvFfSw(Ӽ5 P*mR)EH'J+^ҧ#Oگ.oSO%˥qJڑ_E"aOn8w -%-REez*5R)+>AiuTpFpb; M!]Dj N*%*vrFSJsqi*/_^U>} U4{Ykd,DO*ޖz1"ܫXNȣN \⼪}d j:WXDCrILZzcrR/䗜qJ^R^U>E.K\q-bL#B[v'{ǁK7q۳ִ:mt&QAD~͸jLڦmS6Tͪf3jLڦmS6Tͪf3jLڦmS6Tͪf1S1_ƿ{Oi={Oi={OiKU !14A"02@Qaqrs#3P5BR $CbS`ctDT?ڭr2А WZc6m/9$ڹ+#f:N>>K-.6Is2+bWB~fqSFk`_BArqqʭ4NnWY5mb 2˜[nWQT25t _+Wwtٖ{ꌉT9"yE!qU,E:+٦[x%WyimI('GJ;!U;X,z]J:1˟v(T(d#ȝQ0J„O y,:ݭkeh ׯRt\F0F5KHnMߌVE JAx8-[߬gݠLM4ȭHVm9l*k?O+&Xs`CZYChiL KIX5Temnudq@4X Xe yWbm|Jkazi֟"{h|[ 7%QS-e4XZ(ǜOJsw$;dզ|z2ǨQɓotxÒr(lQOc[BZh[Ɓ\Qq)ul0t­4Q{5Ϋ H`)r!9.iF1u-Vsl.iB(%τgg5' 6|}B[Bn HU/+BkW))ݼu< Jzx!LL6mYAdRH>FsϻOg>>FsϻOg>>FsϻOg>>FsϻOg>>FsϻOg>>FuͮbRa9+M ?TpFsϻOg>>FsϻOg>>FsϻOg>>FsϻOg>>FsϻOg>>FsϻOg>>FsϻOg>>FsϻOg>>FsϻOg>>FsϻOg>>Fs׻Og^>i yK6A|c9iݧ3v}|#9iݧ3v}|#9iݧ3v}|#9iݧ3v}|#9iݧ3v}|#9iݧ3v}|#9iݧ3v}|#9iݧ3v}|#9iݧ3v}|#9iݧ3v}|#9iݧ3v.L/Zu+suIL/=YyŸV+?(eyNwn>y0G0/3Ss,)'#5(f }Xxe9ݺ|&,N8ڜB!{an&б. јV&\Eu8Ki.i6^m.BhaƘi 6jEHub`qHIGQ6& Jtyg ["BhI1rE27.:<̚KQ*An"zwJWv_l;*Za@fB %ZefQ4-0/ É`\<p|V/n4lD1%4ɨ{у*wW0@@bUJULuj>gPR,x“/D"!n}"}lIa Ruԏ9>qa5¥SE7 Wv_l;-J"`-җmv֎%iu%'!a:uQe8>B٭'NQ ˋΤqYU!m?|"c !_z =4'on yS J,/-#Cl# eq7"l)"fM2FcnB&T6QN0}J}X'-L&,ڑU -Xyg|JךּY rB`˭bʮ ,8Bx"mYMBU?6;T:ЉW1OjK "! ǡb)!.4 R:/M&1 v! ǡb)#%0wrd0_*RPCfNQ[YP/OQ k(A8JZ2ɞ46z)0(NP0rX-C`$uiݶR~?NrұQ:[ĦW<~QR|>a_qB$?:ܳ@ࢲSGOl;TW<~QD.cIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIb]RJB59YRՔLfc7Sbo/ئ3y~1)_Lfc7Sbo/ئ3y~1)_Lfc7Sbo/ئ3y~1)_Lfc7Sbo/ئ3y~1)_Lfc7Sbo/ئ3y~1)_Lfc7SbŸJK7$)iŽ3y~1)_Lfc7Sbo/ئ3y~1)_Lfc7Sbo/ئ3y~1)_Lfc7Sbo/ئ3y~1)_Lfc7Sbo/ئ3y~1)_Lfc7Sbo/ئ3y~1)_L!$ R|>ad+ՍvY^S۪OG!=>xN+suI'ՓV7eyNwn>y0c;,)'#VLr}X'e9ݺ|ɎW첼;ToR|>a d+ՍvY^S۪OG!=>x첂Ua5H47w FN,rD =52'-8)8$uC,-IrȠ+|WvOO&9^;,\WT&5:OUNy TSX Z75KcP'\I0ڧp^&Y̙mu0`v-*T/Y}[EnЃ35fpStEEuc[V4h\ W :Нz[Rr_n c44hyeq[ U3w N+sa h#0W3Z|a]MJT/"7.YJvI>y0c%B90_"DkC +`9 TUeǥ)zd $Tđ4qH5K"T ) nd Mh1IvJ]\]z`( :|Ҿ3w N+sac>1(%!*qD*kŒjmlTMkC/˳ZrdONȮ(N}ɉeTkgBV F׺V7QZJjN_cT;h R ]ĺH)tC` yo(;@VklOR5k\2oWd%xRncEGdytXm?brumRUĐі&),NcZfq,sZhH&}+@Ih}d1,cIJ0lQBaٰ˥VhUa,凕z~hx})d@zM8ЫJiDC͵Znމ֙,݋K.:2nfmB7.]M!ԐQlTa-NAeyNwl,rK_Ii'ЙYC[M$6 $oFa|,lɢ(9O&H,l!4+ cTÂj?=OG!=;"a&D,']쉌 B`quZ㩵.650{)f\dNXvFu[Zߺ&Kaӭi'\hF|*OdIr>p$]NtNH.!Vh/ -fҝm0vqJ eb睲/VAmi%gRzeKSLS!H5ZG[r细1c|Wv,|cXs_2c s0w-_\ܲ1M[mRcW. fS!OG!=;"aP ja PLY'%wS%vª CX>d%ŮC 834JOM0!=H $pR,$k'LmX$D|! mݥdG%򐫨w vj}AJBSAmMR 7D%m) eHJʁD./BԨ u_ XJh$V2imm)idOa d+eWaP>ƨڭbvlvk5ٮF֌K!-4 FKJL۠у'1ؙ`nCL;,ysEfu0{H`&Ör\@>"B^\}eE;?b{W'R2"b]ى)bH;&j^tf;,)'#VLrvR#/q_qό9 mMA"kJhdgW(եikaL5H;a8YգhW !ZMTmPP LFrB[ Q,-VZiQK}e8?mvf.2QIㄻ9>͝SS7eyNwn>y0cɕb ʱ!2Tt'e9ݺ|ɎW첼;ToR|>a d+ՍvY^S۪OG!=>xN+suI'ՓV7eyNwn>y0c;,)'#VLr}X'eo$j]11$$$$$$$$$$$$$$$$$$$$$$$$$.pC N%!b`OQ*3Fp£8Tg Q*3Fp£8Tg Q*3Fp£8Tg Q*3Fp£8Tg Q*3Fp£8Tg Q*=:)˿£8Tg Q*3Fp£8Tg Q*3Fp£8Tg Q*3Fp£8Tg Q*3Fp£8Tg Q*3Fp£8Tzu0Wne9ݺ|ɎW첼;T%զE)O#\yA]exN+suI'dW$E۟d뽑1CN8\u6bZeFfe,ˌ/δkz[DԩloR|>a c'↧TW%p9(C Ala "&9F.U߉Bmfih>L#0%蒲)yiĄe'IU?{)"RX!ω{lĶԙHQI֍1^i;N+suI'd"&B^61d>MN `/9 ( Ҿ)=7Pgu JIKohM^C7fu2ɵ`qfgqv[G0_B߯t%٩* O^nA6JP*l$$.Y!+*7]y0a<bUÆ=$wEDxEM0ٿžJd(ԶڀOLӎ$(5o[ encj,.UⴡtAXrͼhM1m(Z@M`5F$9!LcTEҧ^㦤qn WzUK\4]D+a-kG"8G{bo(`6^N\Ӫ)ԋ V xDlc*)[ZUɔ'*g$Pvͫ(-vY^S߫9`2n;a>h3(uԃ' :$oҵ:TJС )biJjHhHM 8#3 qD) IJhAI'q;,└)T-!XŪtj`RaL]JT/inl)W?ҍm4ߣ_qN8-z.ڞ+&v&z`.ރ8yHJ^ehp QiYKjW/ IZء 2%2Y4%p0y+ВVCQ˻jR@peyNw~ ]T\M6SaV/v-VjLEZi7V }RlXgC[RK&-mU4H;M2K0C4޺1jHE&!VZuZrKs=3DeqٯE#).0rNU[_EIys%*mMDܩEdPދƨ\o=0VMROG!=;6}/ QLqh yjȤvy *ڂҦp, ;4+pNVɪ?6f8pï`ԣjvjDșIsKvExɄ12iMs.Z7qW$'+^QyUj:jM0 Se%Cm٩}I$jY[ |Wv2Z]XH&~'mAhS!I54o|ӳ0*a*(kq\J1Wre'9T ?J ^w;{$O2LV:[\!*KJZ,h'|Z/Rt'ZqER.BҥT!(|a*[B =)5$NJr"(RU2cʍmR'*EH6;_"j{vҼB%W*d|#Lr}X'e9l:-4*!éԱTqwZ!i)ZM$z`ɳZ;Ջ8%hT\Zrw <+qVUr][#It\k7(h$$X|mNR}/%ƟpkVuN.]TS 3-̡8JҪ]߸첼;ĺ'e0\MBЄ_=0޸hix k^`ipq%֚6?)?Dkur.M8IsG*S˛:0h^LM`YnAIZ+ZW+ABzD&j}ǃ+ri 9 :"5!(y%GEr{@fܛrUuaβqI *#wrк()_l"=0(z`!N-He1Pֵ!*1G0;YC,E!f0כMJO;07eU- K$ūº~RږzD&j}ǃ+ri 9 :"OG!=;;/6ة^(S84)MK}3KTz4yem\$k V>̾2iXPc32@"Tra֜f1j뚱[L1Sإ:t2qTL˼ӠQQ} ffU@Q eqqw3M8 %6ooui^$ 18@:j_X`: h_첼;TmCa@ q[TL-pɶ)~oR|>a ܧ JӮxecq*־"y&&LP[ [:aM)6E q(qnm6)2Da-+~0a֒J@U$Owʭ ƘL.>Hm%G!މI9)Y>R')76?kxV[BlԫJڢ]B ]iS!Qr)0ec`QrB`!j,=_Սbjwn0ڝ-cIYd4 ϡk'$"Yo/j7R֠ ʔhH)RX92Ám-p pB֥zQj nZB5cXlZӽ r^a!4q\yҩ:cm97u[VE'!PөqM+ ;Su! ߵ}%[wC}uWC֕SbיN/g84qċ LbV`U1RISAMxĮq6 X /Ʊ@ٵ];ЇP[jJoR|>a XG?x궤"t^' a<)1| A9hnJ_39UKF:L1a%,'1 Dem-zrV&nC 5N ief!^*BoFiOlVL ־[ HZJmjL99[*8kw =QeخJV5eV^׾!ӺH˅ oQ>QirשQ7&A!t]IVoDmmz2҃)uЏJѺzIh[}M)1,Ĺd 1wCM:7ltB'[LA߉5GfҐ MӮ{}x c B -S[ mJ&jSvY^S۪OG!=>xMCJzک9kim))t!⦐:^Iߋ*QҾ$S 囲@gƢQEæL)TIFFe0v^+Q+A[ F5. dP q HxHuҩq-%&a70B]#M@hMC87!Jfբ)^"U, in)_!OYxi$S-M!bhELoY'첼;TE9g\GL2q!B1uk- J$P%"AmgV mn% ʲۧZaB@*〙y"Nbށ(BaZA*I7E-EAeZq!BRHA67Bk - d8Sm)qͺ\p۫m*uȽ'!7*- 6M;|WvON?LcXJ Ʒ.iÌASV^t+UQGT`2l= -MCTCMؙIRnOxN+suI'pjmb9+8|bX*ȡYZ bQ஑1; ^H("nn-ꃗ1 ^-ĪI^OaRSD"LZB6>&3V7AB\ $\E+{EFnQTf{EFnQTf{EFnQTf{EFnQTf{EFnQTf{EFnQTf{EBC) A Id- GLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤLzDǤL(ZR="c&="c&="c&="c&="c&="c&="c&="c&="c&="c&="c&="c&="c&="c&="c&="c&="c&="c&="c&="c&="c&="a+Z?.!1AQaq0@P `p?!VZMR k]V(z){AI<ϨHLc4/ Ijc+ '4_Z{u[#f AtbԚ%(ϊsW%L)m I.nK ?j`\r/6S(T7r?[lt}J0J5wD}B>fr^27_l3u@ ?*ğ4,v)4#AVLHkb$]Ȩ4L s08֣៸*6I؈ֺfGi0P ?11m}2XCIS 1NzBr!$tJM aATHMښl6iW-uޮM9Dxwւ²=iш!g q3 f^wO^&iၛX*X8,AgA?3UcI3\[Dԕ Br.,s VusHneО~w}M2IV6', S &_('A}C hjI.gUMZǒ!]'Hih]* )Vn_R0)*pyMLs%rMu] o!ށ Ȕq4*:t_o9tľ/աP0r-r}H[aG6`5 |\5V*`]<7ILܲc`.=Qn)d4rHly>4B2$A>Y Pj%Lڽ|-eCXJ@*B:қ.*̣b<=Vheu[+פ)ӌ CїRBi)Q3Sm_Ǜ@*VG$'rvU|P.Cł1 +/ !?w, lȚPeMB3IBq$1|#_*jW(WU]7c$e)gaR[,1bs x&c *t/tu |Ik@`鈘\UT}k>lPnٵ,(ku&n3eSOs>F 블[6dwZx"r;F<7Lk Jn.d/+ ɛ{M4 Ff4΅/612(< }3IRGYnGR*0FEyZ "4VTX !6͞>t4j:N]q\9P\nMXDaP̡?{?J$p *c6ؼ (yOIDLXfRf"[4Dd777a$1H$"EK'oR.HE(BAyH,#&!k?d "xe_9bK 8kWIh""h*dI! դ|3yOiX"dޤ(f!q6km'XNJa" -z෧92]ʋ$XʏV8fXIo=$65rG%]u6HPtBR5S6 24cQta(3.Sqb&dI4bIwRQҷNUTd&/6\ w qS NܧΧVq.T9N"sXL" n!Nfk \JdD0&Ꟃ, .b&Bg$0Sk0˘#&gdq{fW5bd РvL;6uhX P46 T2GzڏS_?r2&خO|S){=O|S){=O|S){=Jqf˙ bbVQEQEQEQEQEQEQEQEQEQEQB1~(((((((((( 0kbygA7/:NXgYsǭ{?GMΓ=kB>:n_t^rZP'?z׳|tܿ9cֽ#gI7/:N~mBjeԻ'tű*`%lCxeDL"Kx& Qjwֽ#gI? ٰ4O$#UܨhmХ8-E!˺9Ɯc 8 3ܥn] l3 iXs|p@ݙZL#'Hu!Nta/hbRl poL@Yt^ Npw{?Fl0n1s-OB"w:n_tPeA֛VN=OW"WIpC% 8MƏ1?CPx )|P˄:QVrO " d BޓbT,r'(N*Qfq;yhU:\baI.DIHA+Z#SS1Ⱥ{`\TH\*cPĨn2y30[L~gf)e&80֬NLA7&VLIS!r[^D-$LMRwI*-t3Az:u'B܏ jzEt .|'EV-0h>x~Vڍ _'׮5y"u2#Q }-V.IDu[r<ː (L .a-@0UɅ gIz]2}nLp#hu"Fh PWM w*cRQ8ᬹxE )2[p`ܖ;zJCfIIMmY8pxI\ J  ZL}ؤ7f`PZJ"( P(c(0\I*m{?GMΓjW JDmc}<⧊n%b(J>TBBO51 [(u$|)zqaVM+MBQPl=io(qy!x}ׯ7l1.0d5J$idb׳|tܿ9$ۄaυ<"poOnRMQhc4y\ )mdY5XimFArʸT1Ph b2%u!́AsCxެMf! 'kRb5DKjr"՞bea'f?{ֽ#gI n(A,L3-x- Y``ֽ#gI7/:NXgYsǭ{?GMΓ=kB>:n_t^rZP'?z׳t^2&خOtS)J{=ҞOtS)J{=ҞOtS)J{=ҞJq˙͘ RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRVD]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]K]DmYsǭ{?GMHtJ;&t;($GjE>CPx )|P˄:QVrO " d Bޓ=kB>:n_նnWs 5lHLjBxlQ.:-]V2Š+KbJ"YĺRNŴ{CDk5K&rp&(<PzYׂ*1^0jbngCYL'Zuc3 T2kSL!:7t^rέzZ*m&'WPڈpbfo>u=abRhސgr1;0G?耤$B ajz'j_ ;NpE\!9%oN}kB>:n_%Jul2>|#pY$TLƒlɠ'&a=ݐ%o.Eox/?XkX Fs1S)a0 ). W*$J/ΔAKp_JHi49IlPS% ^ *|YG -ҍT1 T?>YH=qh%1ƕ@d/ZP'?&A[|fp|;]fUAmI (["UbdtD嘾^7/߰Y|.?w 3N m鵜k)NdtVtȊLİ$bdL{ơ 7$.^7/MY t;ȺOR@"xƕ $\dese>ql❬ $PHX6@aZ1fԟ S E҅ m5JLR_/^3rlG|tܿ `N&iLDeU5pyޘ l9hDKr.b\Nסr* I@w!dve cJa&$z/k^@%esO,&21g] Isǭ{?\JA*ABF؜IF7Dc xNܥ ا$&,958|FV s(_<1g$vC0Fh}7/0"ԑX DEWN$E# _ҝp$K달ݰM"9xק> `bԁ-9/N4@@hH`Nda*H ɖ1JΣp9԰#3"a) pDey_gmz˘(L$wmRH6 pyq# $Ů) J$ۚ`m6[+g!a!JLͯlVI]$13% Xrlc>l[T{n$g`uYiޒ%`>:n_kWȦ0r 4HU7^o <\"R-);! Y7 !7sHABj<]9bGyPz&[ ȷCKc7'9< .@R5$$ڧ"G ;fרdXMl >aV y 1B{T[!O`(ɹ nŲA1L8c'[Y9<}k$}?^^H%%<%0CFܭ9G, S HIL^HN 2x/J懇VԌ!' w>|:\D,m._},&ΣoBIޡۉ`׉cB1rd7ͫN , ig25%k'D+Hx|a&KRBbe&ŜPBI!0&B ɹ^\)7.TwLغjK& yG<Bɖdr B cJc+=eF!,(b< BK&-qL ǾϤ1k : P10EF#$V9S P& &4LVCh$V)H)JZѽNȁr$&H(A Xʰå/Z~=#eJ3ԃJNDDREuZ(qKUԾj:`u/Bv<Q<ba7)uH,]v$&a =!cpw!EnD\)|@S6 b1-k(6A9d,{H0H#xVRbVǓoMM$"HqַXPMy3y}n o"I9$1Aӡ%6H eKp&p P hڱ4˚ .%z| >I(# *P&$+y}UlH`Rn2@0G|_kYZˠx?ֽ6f6|jcdoy5oVR\=Ċޑ #Jٵ\SfaKTa^`?ȡV}b8().YJ `B8xd&Z6XܪP"eͩ/vD2͌"nfdPQK1bQ -І&:@@#ܪ )$"OIua?Z~HBe|x+Jf55ʷd$9 mQ>嘐b-"nO He:NH\LƱYTZJK޾B)OLba4J]qtM:R~)K9z؅CMGYITOČHPC`7C|}D(x⏠焮y57gPui:_O]+W 0+Dr|)@N F,sKL@NFKXC8b4#5l a:7C7t8pY@Q!c3@^rIKj0Fu]4Ġ(Ҷz{d 1)6oWES7w;ce+ӨLKIsn"]#7 L1 }],4?2vl_jNV w?/ֽ#g\;\ K<0S 2TI7Fbg#JtF4'_` S^cB;%'%'%cz9| f)9@dP4'R1 wƃH)5vYc'?0i-b-# >$Nh3CAA, , H5X P_\,[|H !s :s+9h5P qZ^(;@fx(s s jBL$OGj*g?7];Rg6 #1&fb_#֕&`aJ lAwZw[Tű"KwQCVH*KBw V4@ZPr~[:NM;JRL[B\ O&5wr u]{?OfHŲaYɍh/oT^p/y| cT5reZ4@#AS) 8fNKVZgE+ů8 |!G!s*2N^$ɥ&і5O # NLKGTB*\ \gJ 54.m(u3# i)g[$Rö\ԷE`$G0,.F6LZe0pNxOQ%ȱlxd^r #Nm5Cl,jz4z% FrpއK !+k xi/{PhBk:n_XLm ښt;($Gj8IG/(\GIkEQ 0<\E9@@ X)Gl)IkBoJ/;HۓχTQ[,6ڙjIlچ!r#q;"%C 0 "˅tүAw SȶLIPp6FKCY`-vaֹWGFb@( y*x}>ԫ6oQn `B,Dsn|&)B)b_ zQ<\E9@ X?ֽ# աi?Ь 33g NR uk8wzw"(I,_(-ᄌ h)#|2 / Dt`;^/j3*f% qD5#Q4fLHޯw&2^ro&9mn'{`i@sq5V$dxV8Uw.;8wAdF\Е)/8Z9А@v'(f 3iCK^r)g`.$M3a,@&wEKTN@x>Hy 3cSR(hL#+"D/b(,υn$ UW3~IBtlWZֿu]kZֿu]kZֿu]kZֿu]kZֿu]kZֿu]kZ;~sO]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>)Ve|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+ϊgvY]|Wk>+jh C 8o꿫qC?}Pw2p1?VDxT:蟿V ''h_w6RuOH֮p]Ɇ +ڶƼ3'Q"/ȫ8?I m zmmmmmmmmmmmmmmh'Q$I$I$KI$I$I$I$I$Y$I$I$I$I$IRfmmmn[mmmmmmmmmlCmmmٌmmmmm[mmmmmKmmmٌm Imm[mmmmmKmmmٌmk.Emm[mmrݶmKmmmٌmzmm[mmx4?mKmmmٌm|Xmm[mm >BmKmmmٌmi m[mmL{1mKmmmٌm˳e4$ m[mmQzGUd#Ffs˸&699/&[?ڈ 50ǀJ.Cj!Tt"ø&u ]{^4??F!ђ-l4_ SܭUb;ɏLbfYlHhŖ \A*MknhloS h`Cv kJK Gm[^4??W cIǣU:v*:ǭ4C*9@ЪE!z4IMi(DdCm Ռ* &p" jxtG0*^:"J՝CIIu zlKADrzӞ5ȴ=Zrz,bVIߊ C,G$Cw(z͋Y)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)KҔ)JR)JR)JRd)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)K.F6x< gl6x< gl6x< glSq<灳l6x< gl6x< gl6x< gl6x< gl6x< g1Ff:'3l6x< gl6x< gl6x< gl6x< gl6x< gln}U trwq7q7q7q7q7q7q7q7q7q7q7q7q7q7q7q7q7q7q7q7äf؛U9{w#Ŝʷ*gX>}5'=Ɨ_}߾+7, X4EvYZs$gI &jDBG8 1> amre!Ʊgr+sp]>%YXfh>jS"ͪYF#Jg@P 7 2N>Ɨ_}߾+͓OAHȗ78><䖰T$k|nb& ˇ15׉}n&ƅCyETw2:>?iquN^G!,boH4i2aub Ҵ)JcRr&3iBWAZj׸18%hDzk%"5QcPdMDpa%cKr?>&)/f PʚlٸAB#6&Tg&,|}..H|k냧6GcK;`ԍ܍܍܍܍܍܍܍܍܍܍܍bo吅Gr7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7,ņ뎨ꎨꎨꎨꎨꎨꎨꎨꎨꎨꎨꎨάάάάάάάάάάάάάάάάάάάάo/xlugVugVugVugVugVugVugVugVugVugVugVugVugVugVugVugVugVugVugVugVugV7kױ介 'S;;;;;;;;;;wqwqwqwqwqwqwqwqwqwqwDT'"o^c9{yrC_>. k|]ט'/t71uN^owB!!A%/ JEZ-S Ql|] ?X$k˒GZ|ynXL5i<N bњJCpRU݆J]X'/J ᎀ;ox~MU8l 42Hŗ}ąKCm (v>kJqw`F1ț];#0&Ĝ;_3]%'Tڸ?ЊC~&Ą&3ZX[X{F = muP΢gMsg"H+YE'.zU)N*șz71S*ؐtC@Փ7\,ƀbc2M>_Ô4^u1uN\ %odf]oZ3DYdx!nLtSO7FFJcV>&dS!Hk_Df C J4ּ NMkcvj1#K0RsyfoXcA6 p*NG flh!9c)R-+q 1nLCF}BYˌ(m4-u.( ⡏rLMfN`8F$oÞUyRl!Yiaʔ5nWKa< 2'^T|>yPhPhr(H%dSA$*َf8|]!)Ynu(/ 滛榘H&/iρg% Ļ7x|]Ak#5pvCeJg4":DA0Kԛkt/=!r7]1uN^o"~яrC璖 =_k'/t71uN^o^c9{y==zwH;Xbŋ,Xbŋ,Xbŋ Nt>O5Bz R1e>. xk8icAlKbBIc߆fYN sbA(TOS-cVLp{CsjWU4oc߆f*COc2ݖWS@Ԧoǐ3H|L>C=־ͯaܗPт|ُrC~ q0Mgτg[ Rr93cD) lCL*m~ϐM؛+m  La,|]Ĵ&{IV6$6i,CZzT"z_Ta!Lo- /`9{r/^S"z(KAoiy+df&ob9~OIOzOo5')rEPACҶkTV2¦BV0sG:ŏrBBR}YJN1YYPס*w*6xoǙ+CFXk?UVHLOFF,h1j1AN$"QgW믴cVA!-19:dɼF bzԣRY\y!y*Ft&_h-/@fz&J˨L9 {G?rÑ !hd:^Q= RBc#-Z(@*JG,-בېE!Y+Q1~#~6~@ub5=Rc0l QZd8b=?A?ބP<V_N *vX.c9zUыn2..eE-|&3 ®m`M%_ߍKCi-D)CFцrj10f_iyCk65pbً5 "{ !-ܜ*YuN^H:p8FT !7L -j,YAy$ol{Xz"C#dBcC \?n,D@h EY&+q|]=9:2,PڒU'CH2g@PXX*[#z2$Q 55#aYaAk"X(@7Mh6%i2-h匞dӎֽuoAqWvqNV [Ib_頙5C#r]nCh&?棢NЇ(Y0Qŏ5Kv?)KZzekbI9ξ܆2ܓaupF%] toֆ+A,nӨaJyDtf;&87⿑kwas=HK+ |]?J>*~eaVBczpfb{˲(eEj\Y{ |*1^L~./fDDLR-4g^\Yknh>1TyBk]hE8l/hCed@Yo Dь̱:.TMb)V(2"iY@Xe$U_?d.aPY$^R2  )a;KTzUh@r2˨,|\CbQ1B .:C&Ԉ4ovHb[tyk!gG#l7㢓쎦7DąǪٰm.dhLly)Zg0} 2tKرuG 5C~>sb(Z!\ yQkaeCP%PUfP"JQ7;  2D17ƃdmZ#JWV4X'/t7rb 4"$K7ڋ ȷmPYF>ON A>!ɄMGZ1Й;uX5Rln3_7񏢊zd%D(,cM91uN^o+Z1s!hMm6ޥlzSrmz\hTa\jlG4jUz{ѮjЖ!rzT5d5WV6c h$).LHyE4jiuf% \\X'/t7*,2#Ml9A) !R:D-_A0!( Rm cs yrPfL,'7~GX8}fB[ՏrC`^f-# stcTW&~',l+(v ʺiLȔpsQ<)^Ț٨ؙ)p*T=Slpv&jBbtD~4X'/t7=ģZqsbIn+9ڹCɯbmWңȴ0`&@ BȐH1vb:Ņ,|] ŃF'N · h'8uV>..4i]"Vܩ352 *2J? 柭|WC~G(x⇊(x⇊(x⇊(x⇊(x⇊(xp7k~B!BB!OD!B!B!B!B!B!B!B!BqkR7Q6a6a6a6a6a6a6a6a6a6a6a6`ќ!B!B!B!B!B!B!B!B!B!B!B*!1Q0@AaPq `?\'T,?RCXv Q+}ƢLHK`7mn YiF&,%POrjzz{#um-;0})-TϷVbVuLQ7zUK-"=16%BmC՘,"aS,i,FGU>ı  "[d[L{c'B b=TK&$%[%ղCTbͨk}aF) <1_\0D$gbMWS&(n!IEnuxzX7M7ߪ=< ,!?BwģUUUUTA⪪LeC!I(QEQEQEQEQEQC((((((((((EQEQEQEQEQEQEQEQEQEQE 1٪=ECX}DzFGxJ/CX,_W/}Dz>l .,0.҈P*3&;ŮCz)Ѓ=ml]'D=40*2aD<"eTJȂȤCXBa&%2+!a=9X]ձ6b}vy e*S]`.V[UY75^bGLi#KN)=wEﶶh_А *HCrf'ALč`s-wɓL{L0A+YƨnF}t^kf}}E5cKgMc1lfV7$-s-wЙP YI0 lk{]٢=~[ v$2ch0 #]-xT礩Ҭ)4e/}Dzk/}[J4G|G|G|G|G|G|+*H#>#>#>#>#>#>#>#>#>#>#0+'4G|G|G|G|G|G|G|G|G|G|GӨ>>g3|ϙ>g3|ϙ>g3|ǸB,888888888888888888888< !C[AAAAAA: )JR)JR)JR)JR)JR)KB)JR)JR)JR)JR)JROj^NW?Dztƿ]٢=y:M_c_Ůl&űth^NWk[4G'Ilk-#ד5Zj[-wKf5~-{QVB VKh t%GUvth^NW׺ %(;TdhT$L ބ N!M`ĠQm]٢=v W z/B4>HzM]X&FM:Yc^ ـKTGY!ql?Y%'(qCJ#7zvth]J64A;CX*('2 U1u11rE/ߥ}~i9)3F fݵ-#ag,BF83&٠DYȝ%]!cgCk L"*WKn}wKfj)Q _B31tofH(V_ȌmSp(T̲(=lkUl PZRdm4CK yl~/NΓWp9Pcv*ƪ)5kDGJPʼnc^QI*ŧA%I ^w%E ]٢=v賢}I/U:!'V&w75,E yC\-NhAfcf`[4G'IlkHhg*&&Q ih[@9Z,2Dztƽ1YbS‰>үc#A4E})dU֙>j[lYՁ? x[4G'Ilk)'|O>'|O>cЂ          AAAAAAAAAA@QDDDDDDDDDDDDDDDDDDDDDDFa ]ɧK;?[4G'IvU)DQ{lOd<c_Ůl&٠DYȝ%]!cgCk L"*WKneAwKf5v̑Pao 3 Qm9Q(eQ:{vxаu-#ד-%T2ݶ=iJ-meñR1bwIT))b b4b/wKf5w%곖]:!'V&w75𞄫O/bZ""[ db-#ד2tE|'ɘ)ACP<-#tTU- +tj|5¶щ<-#Fd1EWQ & 6[F=0ƙmʆ30E: hlPPR7(ڑG0jZEMIQ#ȱ1-+D҅Ll"IP#j4c_P [7lfٞ鬈lc bbaM)#LXIڷ֢J #Ҍr.Bed' z.tpi%!aҟ =-#Uפfqg2CsbА!LĮ4ci5wLb#%27c_Dʶh{BBZOћ X[4Gf!iMB-C jI`D3p)ZC`y! z*bĦ{k3藰CQC~[5G6ы8!ӛpj>JbA2,mxfL2!bW'{*%n&$~jI`Jؔ,^2t Н˥:7]&b7i5wpa[Á& &l*1Ib)c_ !O]1-HE-F֢ j 3|t!()^Xfn?3ƍ94ƾ++ JG.|(i!<{d/xaYH]5FcdjEiHU%5ThJ`ul.mWk(bWhTN(E6bU]SQز[%$&U]0,}a &ȍ ?/ |&-q!  ǀNM&ŰbF6;0](" MY(3LfhF$b١cPșI ƥLG"F?BvlE5z=cL3(kV=ES!##cI-D.'F`Y"! 1QzNp5\ƍ^Mx+[4G񴚻ٛ[W7BO'JSy ŮCSFY _Ko'FBjˍQolk5BċB9[߸G9sc_jrBTs4WD'FMcBGHgLx2$TJM= T=ZuTAhq(tZ [4G'IZ!='MI_ELhgE^V0nWF'$9/1^Ŷ̓c4HM{yMzNF ChSpJ)th^NW.1JqH4 DBa!O$>cX禹/KgB(/)*` s_bUI4XC]2 _ȡ_wKf5w5P1r-DS$OcI| EJ%;}Kމ%Ehz}F0`t|]٢=y:M]_Ȫ&" ĦPGc^,JNB%"A {%-#דF6Ěg[C_ȽkX2OjP>+ƼYk?FX%((٧л=|O>'|O>'|O>'BTTTTTTTTTTTTTTTTTTTTUQQQQQQQQQQQQQQQQQQQQWEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE#!     c-)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR-!1AQa0@q P`p?^x#0D5 6|*Cl c1yAl"D@HJ z_Pp1O|wVLxQ4*H "L ` Bh.BJ  @@% 3  Zph-8P"0 " >)Z@A>2F 84VV`@xQ,)Z8rCt |\Q@C}܂0$mP0%'$:D v XVoDn T @U ' /˲5@,`Ŵ|X! 'KY0 8 )Bj@V*qyI AX0sD41  L*R ΀o@s @IO*,(P b La)Y[CssMh@ T@JP8`/@]1`z@z HRx>z`;SJ`H8  "76h oSA`-%٥x^,3FPR ^8ʩ[D͒  6a0QQD'AשV@JT1P0@wCpb$ G@!OD  9;nH  T݀fǥ g)`P@B:(5_Ƞ( rp FzC ,IuP" $^Ns=aV}x} NgL, f 6`كf 6`كf 6`كf 6`كf 6`كf 6`zl0l0l0l0l0l0l0l0l0l0l zf 6`كf 6`كf 6`كf 6`كf 6`كf 6`كf 6`كf 6`كf 6`كf 6`كf \q8w %DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%Q(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(K,haaYn/_s0BI'Xõٸ}ٲ8L$EkfI5HEc\=6D~"DR 4`B iku- @iE!qXðS],x"`YwXXĊ!uqzA Eː1Ұ)@ LlM\(L6Be/aGS0,| p$<|A vf 8Pi!Yc=58:Ɔد\/h9@3' h˧M%(7=j0&mF$4ʰVye0o,8OuqzA e%'QnRo p ۂJ,MAU@e<9ȀLEF =(9Cȋ6awɿnF Fkzt÷F&`+d'u!n(oP[&BO @&7]Eu ,`ٸ} x}6hX&`&i.; uG`_8ۥ@ݝhS/$ZA9@w 4̀5y#1 rw Du@ cC ~;&>d {[\t0! , _1mјXMF Ty?s+ َ[c @;Qg!#~Z! 'ꍩ% AbJفaH4 }P,haaBO p!Έ )v'^SCf @*k=rڃ]wf,XJ <Tx#r cxOadJ&H$%t`Axn/_ cGh]l^0AcC j{OiH"D$H"D$H"D$<@07}}}}}}}}}}|G@}}}}}}}}}}LM5BI$I$I$I$I$I| cNj /z^/_4<^0i{x~ `8z@q1KހcX Ba.c):u8 F=,7~0/^}K2T D_%c;@& `=lQu^VbFX@ MQ@_5$Z@/ԁ 0@Ey b %`CB0?c@$@0`u*Rz{ Y@@LBkI $`O-t 25Px`ؒ >Ѐ#dC 69YX0겁cIB80RĪ|U2)@PېgC@>Hؙ!Mqd2* ڔ> 1Wi!rFd^ ۰k7S W,@h@ CZ' @Ԩ hHf-`' p#l ^hC0P(~?]5@q&/+I+Z 0~%b/kKbnqۘ5ŕBLYH}#!SiFQa1#HM(Lsh ?Mw`d8zj  R$i*z<ܡVF@ "?![`P,0 (`(A=aR!\ }(ǐTUpj]@ i, t`y vW Р G!@<:k˩ xu,8Ib“'4Q@t4+hf}/^g= {J 2gOˮX9KA BK@@I"PV1$D+)0CT@(+Y1 @w9 L@@1 x~ `WoD 'a@r@,ބ5@ Q% 8G8yLx/_444 XPNΨx@P@ar5Gr>nvSk@:Ӑp8I@ю$Nj . (e +ټ/_4<^0i{x~ `8z@q1KހcNj /zr˗.\r˗.\r˗.\^qB (PB (PB (PB K,,,,,,,,,,/;C,,,,,,,,,,,E#ֈ      ; cʸuNj LBkI $`O-t 25P8zA\)fTa6ҽAbq@, 7/_h0k*'~7" 6$Fv%B3 * c,"FΚP,pha <^`P,0 (`(A=aR!\ }(ǐTUpj]@ i, t`y vW Р G!@<:kh#J <@Z@!} f.IQNj dd=3e]F.fQPUp@~ct/_m0h; NR&vszbdE157 N<~<^@?G (&bd u!i0l25 @`;LNj֧-쑙nXM;!I%aH".Ճ_QjFS$8,e1̴U$N|dP_p";]NjȘG/Å&o tI;BIv7"` WB D ]@'$7dɠQR C—8;K`ңB2Z`-@z#(@~d)_u܁v>M x@0w`{//_AaL<tBG0jEKHu\FMӡ{bh8dd b75ȇf.Fnf!t|:OV[d[l!B݀{ n2:c 0k6h:c$ 0]@!G" RVA@ 8@'$)m\X,MQWM08 ?_ A5p@7T ǖ 9/_AaL/'",ޙc1m/47)2sh5˥+>jHc :^(+Wt!~X 0JliƜ2+a`l,:@xQ _6A'%π̤M|d@ q )C B WN^$WG[#i]q[ y|RoQql1@:*j" /6.%@\`! ,XH)Cr/ GBx(U gW@ j il(qHp:@0xz A5|"@A;*u5b$/$ Rc`Dō C_Q>@nYjt@ E1Dhf % wY@/&sCx@>sut]I20EHQ~e0i^ϒEu ^BaP@8$XqL8h@L&3D:p?d1Nnh* %@@ wǓ/kfAuLgCp`k(M|gxBZ?@> (($P5-ؙVb'۟ . 0]$Ĕ@ @ HU8zqT;^DBE'dX$b_K^|߆!=edw0^E @6D>  '+6 EI7 3DSRƃ䃡eˀ,D Fɧc+0i9I@&>@sz#A@]< (QH{ē Eځh0 :y @yϡs8zAT뙘 9oŘJ2B"yKr@a;"GA#"^GHX3JۡI=+8=#zq€4s<:|쐠XhrH@w@b6N.1!NN!B(YO\@;ҔcH NXx'@d\'A~ŃYzt"{ eKmnD&tN6=]ǰH ?< aS>+$qua=+"$hO/#WM72h|Vll`zHZÿ358FA!,,雞0@f@ 8N`Pu]@z8 :j j g X0H$B[././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/essays/enabling.jpg0000664000175000017500000021302600000000000022361 0ustar00zuulzuul00000000000000JFIFHHExifMM*>F(iNHH02100100http://ns.adobe.com/xap/1.0/ 72 72 Inch Exif Version 2.1 FlashPix Version 1.0 Internal error (unknown value 65535) 1024 768 C     C    O.jU -RH@Oc`&I ?șA.$G/"C^gGu,ۇR@D>P>ޯ1B& ~[QC7g D$$<}DߣuO MrpDg[nD<}|+uzrn3~_.PߜzyYjNHy{nx~D؛5'U>xxLz_)qz5}=JbvxΞ<ϳgӻ;_'ɜYnחӝru6S<>U;JkC妫 =yQ nx wUyz=|k?Roս;YrroWg?{|uO諗<϶o_Ծrүcӝ,!3&+|D׍o ~ٕ(ނqqߒ_sQ?G-[kvRޯ7w_T{_;L}o}=-\ܿיݑaOuKq}Ucxz&x2Ca>i_=}'?x=Mn|ykki}1Wr{\={B#󶳖ܞ.g-px7g_GX᯹=,]ܿ:>~(/{|**t;Ώ>@L L!M Ab$LH9;{oѮu>tM6ϰBR翐K|EHYh;>@|M|%ꋏn̉8v}KJ/= gG]p57ץE^{.?@źΏ2&joK.(T\DudMwó^]P yި:<Țg٨//?QqߊV}_4)M;} 9،6ß˨}:<Țg٨{@=_aæ^眹l=|9Eӯ-&k^}X9~u5}z_)t_@%z$}z˷ӛxm3*ҝuwqvm\~YDx;>@=_y=~v}; ʻ˯m'o5N1$m3|}sY}>L朾||["kNfҞռ斲::MS2E|}GLXvK:Z[@^]P yިp=~Ó˷{|l$t孹M*CYM5z˓Wux>udMwóX}~'3q=/_g_Ee=O\rzex\//?Qq@lv%~,LudMwó|L.z~Qo&d>R~ KJ/= ?GԀ@YDx;>@W|M|%ꋏ źΏ2&j@oK.(T\DudMwó^]P yި:<Țg٨//?Qq>-ty5'ϳP}z_)t_@%z [bkNmP"oK.(տn8iN>vط(+!KHΜ2٫xP E؀i^35e .)I@%Jg(ZFxf E%)(LKH Ԑ(ĥ%^)iiᚒ%x%3~zmg-cjD VZFxf E%)(L8NOb]ۢג:jS9Ll9`gjH]RJ/HPP\C~/^Gr[`97>4k+gjH]RJ/HPyÇ~?˶Ȯչ|9ZwlJy\bp;ZFxf E%)(Ldm2Ǜïף2\S/FV|T4IJRP E$ I,aҮz{ x D$ZFxf E%)(L3k[4PH$$$a=O4IJRP Ey{t69L!#jsh<49yoRszޖ~[=@iiᚒ%x%3-_7"V]yь'7FwkujVvmrq_=35$J.)I@%Jg(Ԟ^ٿv@|i=vqV)0JŽ:9{!2W4IJRP E7'$IgjH]RJ/HP A?TI35$J.)I@%Jg(}Ƥ#)=qk͓>95=aʣԵ|"x4%DEI35$J.)I@%Jg(9m~])c9vgz~Q u#{[Dn>ݥR -#<3R@QzDrڔsږ'O/>ׂS|{y]x>t:ۗzx+L=^r:9w<7 ;4I,LD *(ĥ%^)։n^"kR[8w61s?lkLtqriWh{O'M'gɝN~.8 -#<3R@ϻׁЛo,,m58 g$HQzDr iƜm[!>*4I}3 xzؚYc\ci ]T]-^ߊ[%h67Xҝwmk=\x{ǧ暈QzDr_V/%lumF`$ F/4@PgjHJvv2w9}9z_ׇK+";c_?[{je}R̩22IK[Kɡ|ϡi ]RJ/HP//{9st$&$I)/ݐ9}% -#<3R@\&>W7nޘO*rLkk79W]EvM<tq8vNs{srL*g~:/b˂˯b[yu>e-`ۅh@(ĥ%^)*^?oo7LKcӧcJ~+)]iљRN_xsNNKVZKH Ԑ $H LL{{U吭P %x%3y=zᮖoWP?rOsC㽵TUnS%o=gjHCj3N3ߑP JRP EW^ݲvͩiaiDWeL=sgjHx Zy@4It#/xw&r)h֯Bߟb E%)(L%a\><>>6 >ѵ?1lg%My{N5D -#<3R@]8XΞ E%)(L%a߲'UFZ˟sZFxf E%)(L$HD%P4IJRP E$B,ZFxf E%)(L} ޅڹT<+}{G1ZFxf E%)(L9.zu^A';ٽlM|Ȗ6k壢Ş35$J.)I@%Jg(#HL{jZ]~P͊-.no~׾HW 35$J.)I@%Jg(9*wWrT8@㍀r?s+OZŕ-fGNf4ԃgR) )esYX~An7q5x2|7߂v&prRG}[yANjη#)%pdy8ԣoY_ɕ=g ytBrP&f!":(HBT꿹E7{AV*;dS*2|4m ɼ|ڠYJ&F3;Nj]̏'Y!4F3+-Sk2떗3r/j`M!$1)fG0XȆ[:湗qDCߍ])4S/+%.CO-:?fVZ̮-?㨁grN?^TWoSƃTw$,,DJ߅HN!%j?a6Z_3+-?fWo2qYtfڵ dM7zXcA/B"LFeiEeTv9xJÚ҈G [\}?~Mk&:&`8M\1iŶ6P(&m&q}t,rK'#0:6XzOaaZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺukZֺu]2dUշQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuN~)nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[BEf`b+y_ϙ]_W2fW"x-~c/{>fau~b+y_ϙ]_W2fW"x:]\_A &eK? 9X7`bxDr#QF㧍bѷO*׫30]~Q[|Be E8cn,?(@_9R"a;WAVeR7v5i;()1#D7xdӎU0/RH:h%GAhvc1~#;){vIG)c ߼*V7㜋[ϙ]_O.(3(q"ѷơ Go/=4EHXE-4{~]"wf}Z>yi yr=8-}8_}TXEKճڎ48!eEI&c/r ;H[1LvXBDà D;4ϙ]_O.(oOe(xɼ9WjoAig~*I%ߑ`ld}zw'xT@i8M+"xS]Ku XBa !W$멖_G&džU]}zy{3 7|W(Qmzj'3'"ac~UHIfI%}[_ m{!Q4;eB>Wy‚1g tvatu* 03A40m9FFR' j-H(fR͙e*IfW˧퇔:bxcEY{3 nWxq qfW"x-~c/{>fau~b+y_ϙ]_W2fW"x1NI-I)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmRtEƈCjRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJڤqsmhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊u;J[hZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)ւuZӭ;tz?1i=4|_uanG/:ީ 0x8Վ8aw(OyۣcN)Lc.Q=IY"EX`y@ 7I} |80H.YjFb?yۣcNRemD6pxYjmĢfm8Rg_18!Qkwd;n[;tz?1iILdvۓQ Ӂns#ĝ !Cx֐fIhl7QnG/:ު[f7I]`{Dt4A{7Iw-yl遗{œٚ ^v~bӭJXJ$io;tz?1i,V3Vhwc2#p7eX6hAs%(iʇY]\BŒzW394hiT視v~bӭ;i|-+"=E `k $Ə[RfK~`V".Uv/cT"[-Mw1 [ <1['`!3̗}Xaiq{$'r/8`݃@}%o;Y4k Q)"3)yy<$f@XH J2c4$QR E.kӜGƝnzt qKJ;<5/irB(IVȊʀҶcma8^JB$D3$m a|60ڤMyۣcN<=섑$܌\rY"`lrC#>;";qGҤuʽ9vTHfZB7Bhf0H*yD38JUrqy_ @~{4R lo h.h݁ /:ޛh=ML['^_z;tz<.\&뵥O[EԓJ# # 9)f^i ;9zi8Kr-IN"Meƭ'ᔀ l\̆\|L o#b5$ O;9z~^I.\r:ޚRmnJE b (,{,Rl^vys>#3RB6>7$q`01rɺ=79ѥ0d7R Z7s"ⶊ#~ԏk1S28c;Ⱦ&ԳN,MF“ZX4M!`l f s{ πpJ F|$TRф#a92ӭGch\!ӆ&f~%=,'RqŶyۣˀy&ve9Hqae}BJ4,7Oguű b ɠ E`닥*fٞĠ- `#˥) "a|l4U[`~= 3LB`5ɠs/:ޞdxv :hМ*lD#.QG 1#4U4h}]+nXԿEѫCDi 2žIWbvauşnm7ͬcd ߤG.nR܀`qrbH:qfӭH 07ZIFte}(ݱ(&f3#ɿě/@&Xvc |`O;tz>ZrOn&7ƝoJCrVeJM2g_x/υpbfcDB?ˏal -K,n?UnG/:ެ$*"Fb :ϏG\2UφB. 4LYE9G\^M"}"2_ur\(c"=4|_uanG/:0GƝoyۣfWu\p:UWu\p:UWu\p:UWu\p:UWu\p:UWu\p:UWu\p:Uz.ۇu\p:UWu\p:UWu\p:UWu\p:UWu\p:UWu\p:UWu\p:UU+o4!R1@"3AB02P`#Q 4$aqb?wU{-Uv} G~NVeYuWMp H[EOw.\7Un#ĞBo) Q@]?hXÅ{ءp 䋖WB ?]wE|.Zp~ >712g)可ŔK<~O$)#.LSupzsG>)Uk.CYkd潝~"'wHu Me^SO$pq]Mm!Yq 3EU-Wc]wDآ~TM *#9ʢ3E#9n\+ܸP({U]8 **<~"?E;&M@ֲ؟t\7UU2w[,Sf7\/ܸspX{E gB갹pƸtX)%rj%q6`pˊPyUy 0l .Ia"˝|j1qG GoXpz[^tsU=1ak8¸WT~HSۚl[u¼APyUyaCTJI %OE(L. ~z.GL!SS:\S~+޸j +0(qޝͱ  jGsL`bW PyUyaCTHSpC*YOu*˯U-X,ѿ#UeW<**%[P'e*:ʞwEMPa+0j7YTTs=qE,QVPjE9VN'vežq:룔uDsܩi50t+K2 ފW*u@z++,V躡:uZ+sB%͏ŽGa7rpS?TiUW 5s \ne:t8u8Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗Y}>՗GxU];`$5ACN՗SV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_OeV_O*kbnVUjZVUjZVUjZVUjZVUjZVUjZVUjZW:[7µZVUjZVUjZVUjZVUjZVUjZVUjZVUիxOrcyW1*o(/o8xOrcyW1*o(/o8xOrcyW1*o(/o8xOӷY[,g2\~]wYP`EXʆ)ؐ!=\PR!ʛ ֹBŏT(( V!UV jeLv AWM4p6L{'VW8xOtL0ܮ\m褪d^ӥԕlT% o2F踮<"]R6rz@=SrGsPC%TGYUMN[ EUPʟ[ 9z)*6% wzW Rعʩb/BUP(a:('QLEiļ}%*e3d*XS&7.+5E,a U'\3r{0F.L.15TC˟;g*o(/og[үYQщw*~Z[5e \=Œ*z#n. ^AUx !S? Q:,C @&EͤTTwU-8^>ӊyKrBFz&t/p?-Qy-W*' jp18ASruS]ez9V /g*o(/og[үYp:.$-8h%?V5hV\CZMᳶ"ZQ nK$۴^>ҲYkdME,jl7E4#AT<\nsl1rbZCʦL׃2])P|I*7'UC72Upx80r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳed2E`d-oܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0r ܳ7, 0rB:٢+YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYD]t@+++++++++++++++++++++++++++++++++++++++++++++++++++++++?Gp?.#pՔ2J>g,> oQO=&:W̾UMTڏIk5T:RgsoeKPSO}Gpj(Tl.eXpKrSQ+ދ07 R˧m`@$u;I]U-0i6FMRZ;{a= B^f"bO2drv;' ˈRV^JFZ*9QPauIkva= bN{eI>ܦR3fq N ds4PE#U1pRyT<檯US/8%Wt4=Gpf<*IhkntUrzl\Ag *FE(.RôU/q*w pTJ M¬bH *2a=Pcn+W/5>h#UU߄Gzx|IM3lࢉ!঱wUϥᲨ TqULG8UJ8 B:t^Uaj-p+ ЮPj5_g}pO#j!wd_p]Ho%ȆWvF0*jAS͙UD|*oީO0Ja=UU7xX%e*lʤc!KK RS͍RSsADz`XG3CU0>ވ@#vvT 2+U=QpQ)|YdjѵCPLm)\Gb'*q^"\#(VYtWW]{Џ׊o.PVțhB.u6P@9hK3!pqO} )OD,cbOR#k>q(Ӹ*- 84(*цVUza?UU4*yq.*e\#t:m61@B#kI‡zH'HӰV>{[MuC$`lPӇ4mz& ka/*(ؔ0sRG*$hj{*1i$McKИ 5AN UP@-F #*jA4n .S󪫁L2uT` U cnQ ^w 8vG]ҵj:D|(+h&꩜^yjT1QҿqB= $ Q7(5ѮD'F)8ꩰ>.0\B u r/88_%*\}[H?~'YIa Yi/>hr„{:y 0y EL56I#8>WN)|x-{u`69N〡^n,ɉO-C)K BS!/K;0vU;/5.ɿ&VTH+?>i>WV>;Y2I\\,Ĕ>W]{sT>)|rU9ʖOu[Uu&2=Lf-·R6ID"I‡bs:A!¸s\õ/r'<$\E |0DYk}"VAf ҿ >/>2od9K96 uJ/ *;sdaY9By;HyP$1 jn#ڟ uVh/Gps܌8UAz.QDN\f0â=;֊qSD$ ]\1g=  G ,*nZɁII8^H"2Dq6YڄGa]ST>YT42`Ms@mH*L"R?b\C l`*mxP㖞c>#\YGpkKP=jpJ};TVs"5EQZ)fMTMpr絠z*y ʗUR6qڄGElIrg-=.ꆆt:Տj#p˄G\#81!1@"02P#3A QB`C$a?yt~r_.]w2TC`%_Z5R_xtL^"Pf_ʈ'BE,q ֍K.CZ#'~ j5.~h2T,o =ٛ)2hvlnm .x̾CEܘ\fwxQ󛊉HM͕Q:~c4D?O`df5 LXŅ*af " 1HaIr<-%*D#TC& /_Vp:1|lk"#(o?seYeYeYeYeYeYeYeYeYeYeYeYeYeYeYeYeYeYeYeYeYeYeYeYeYeYeYe_cEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEW&K?3}f7پo}f7پo}f7پo}f7پo}f7پo}f7پo}f7!ч3lvf7پo}f7پo}f7پo}f7پo}f7پo}f7پo}f7پf9/W;T*ШI_R}~gOW|ԟ__10u'p|W~I==_R}~gOW|ԟ_],JFG$_ME#J"0S'1 cm 19F+C%'=`Oi!ճ/¼_hOd1c h0|WizMK:dNe͒цte˒bF'?=&zbD.`Oi%BS342RDyh7'f,=,=F<̈N9#&OWv :*·|}Qpu:k?FgC'QF.G%WJ\==_R}~gOW|ԟ__10u'p|W~I==_R}~gOWԟQ|Xjld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc 1bO62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!x:Weȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\,l\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.F?C+1|_̡e _0Wn!Dd{~ _0WcW1n?4DHQkbC/Uؽ䌾\b1J G&'x ٙyx2':VƻT1|_mc[ȌcDe<;FfD=LiK]*[oC/UW7B+IE I" }$M*1|_iY:_tBFI$ }cFF'|Y79%Ћܦdw$5h/^$!#Y7a?.#~/ixFľ3X H;a']azk#x'$=Ep91^cяĄkx2ܫ_ _0W P }|azr#$spiHJ]c>yjC3/1 _0W^dfO(FWGYT_K'8zi mu3OA9KMM<WvkW`/^#R'h M295nFdZ_멉Ӧ'YTqɞ $xtw.W4>,vbcq 5ѧRt%prD!/ebZWO$8i&LMLxidtؗ&o3ێ ^[9w_Ѿz#+cv=S҈R1Em(ýlЋO]m:dw-( 떑hO>ٸv\L+VySifwZc3rcr#/UjD1zj[Yfz1O3ZIB&80{,dkoɐQ"V^3bK qf#Bq_jՖ>s35YӴC%8ˆ0kR11L,S$ln4F YQjvd~Z Eredh|c1bl~|H9H|($a^3q$神/y&RmS! 4OJeS>ZdJt8!Բz~u=N5P,~/WWf|ZH?d:d\^}D-jVrLߚGI9:$vbXwȿZD+WICP"0KM$4tkZmd% f(luQ%rlSCuHIf8msbw+}D!]F}#'gDXŊ/Urt'M)J١2kV73ʑzxZKRVKִM_H.7r%jDRFg?˲CqB4?2K}oh4cxSg1FEQ?eQfgM+ɛLm)3GvHb^rJ<xTOzMx^ ̱3d<3;}D운cMvb'gOY毧Cl 2/^1|_̡e _U  !124r"3@AQaqs0P#BR $5`tCSbTcD?ڽiXͥ=K{6۽Yw nRq"Ĵɢ 6%ɖq\UNQ?ZTeywDAtCh+{?'H]EĶkOM4 t-;bjeu B_Ii/}H,׏5NH]D߄_(̞ky}2ćXY@ڶ׵" t6V(qp4Pk;26plkG+}be&Ҿ*R}kGf?A.["|.wb|#Qt>}p!U!r"ഔ艙stUBȴ+U%UZ\+ܰ0M`+8Q=;>Tiw&\llAU?(ReŚs)ø\<)ԉ}ŶTH]D߄_(̞ky}2ćXaVvґZS9EAh*}V+/*Kp24eo[Z[Z[Z}֍ ,wD6jU1ө;"kG}KڪZv%\mUV$m/ji٭"bD&?-<(qEz(+ ?8*RZQjj*F`wGm:W 2J '\e͠VUoHl֝CLR,,ӂkBZ>D\#DRZWF%5E&ULUDL6DUC $(IaidZT! 'Xi>[Bn֗*-Qzsvi!X= Jrj\K!kfӃi$irr7E<_/K0ȸP΂&%˲)AD"t_qq:,uX댱c2\eq:,uX댱c2\eq:,uX댱c2\eq:,uX댱c2\eq:,uX댱c2\eq:,uX댱c2\eq:,uX댱c2\eq:,uX댱c2\eq:,uX댱c2\eq:,uX댱c2\eq:,uX댱c2\eq:,uX댱c2\eq:,uX댱c2\eq:,uX댱c2\eq:,uXܾ *-iNvc3f;9َvc3f;9َvc3f;9َvc3f;9َvc3f;9َvc3f;9َvc3f;9َvc3f;9َvc3f;9َvc3f;9َvc3f;9َvc3f;9َvc3f;9َvc3f;9َaZX-!8wFsќtg;1wFsќtg;1wFsќtg;1wFsќtg;1wFsќtg;1wFsќtg;1wFsќtg;1wFsќtg;1wFsќtg;1wFsќtg;1wFsќtg;1wFsќtg;1wFsќtg;1wFsѝltg;1 !0Q:lOl|^UʞWIϧe~/*~exO[+2bs?2de򧭕s_ʱ9}^2S9̯X̾/|et{fWNx_lTN}=+yV'%3!Uc]'.p?KЅD_ 4PǍ7ԫj-R 6]ņz 662ANnlT*-QyX̼tnq`OS9:뮁D#J`XJij!wí}<T-KUK6mhC͋_*z]'>ѯ Q1T򌘿KKbQp*B+,o--&*ìKX0tEVJ[yi4Xw1y.-bp7ik-!|%uVm6҄\ݛWϒ.sH3%UaUa +KWMif/0óV+te^hBXDƋ 8kE*.^a\I15N(WlXQT TN}9 !DTl[??7gؙx.Uf`ԉ~EZN,;54WǜƿD샑zU. rS1-R'՚jVbmn@`EVZX)*v-ƨ&fwZZo$*6%w,Z+H $.ބEaW͛v뇹 mĻMZaH~Z^P7ҋJ^U#~G-}*TQ{E;Vz;Vo}TLtq7⭫`R%nb^Qk}l1R'&m$=tA}q? vDԊI_K|ҕJbKpطgִ^VWb\aEdQ&ˋ݆sp0Pn5EEꉉn~;V+Z{eRu(!QVh8aVTee P.n/=lNu2sS K KO .$0'Pj>1] wfn`-\N~^2S9XyX̼/=lOl^UʞWIϧe~/*~exO[+2bs?2de򧭕s_ʱ9}^2S9̯X̾/|Y_,"Rh;6Ͷ3mh;6Ͷ3mh;6Ͷ3mh;6Ͷ3mh;6Ͷ3mh;6Ͷ3mh;6Ͷ3mh;6Ͷ3mh;6Ͷ3mh;6Ͷ3mh;6Ͷ3mh;6Ͷ3mh;6Ͷ3mh;6Ͷ3]y _2KtV|fAwmm|fAwmm|fAwmm|fAwmm|fAwmm|fAwmm|fAwmm|fAwmm|fAwmm|fAwmm|fAwmm|fAwmm|fAwmm|fAwmm|+s{5uJEDP1: uF@ꌁ2TdQ: uF@ꌁ2TdQ: uF@ꌁ2TdQ: uF@ꌁ2TdQ: uF@ꌁ2TdQ: uF@ꌁ2TdQ: uF@ꌁ2TdPTN.Q: uF@ꌁ2TdQ: uF@ꌁ2TdQ: uF@ꌁ2TdQ: uF@ꌁ2TdQ: uF@ꌁ2TdQ: uF@ꌁ2TdQ: uF@ꌁ2Tdm)iohe[1'}lƖl[[p>oGioK<_dpbSӶRZ`L"Ա[ax?d4}ޏ͕@\4U[$~ѹM#dA\X3[}G :u-1Bv0ɋ"Cpڪ)d陶8pE8{σq\Qbbma)gLv }lƖmkZQNtStO8̅tbog'ڵVD;V'Y~#5Di69۱/+j>S™wPPu/t, SO}©^p3B?dziRֱ/?s!l͂\Kڋ : [[N6iTy^eW| 3ySI~Y-Xz֋Ul^% %p7Mo)MedHQcK5zU!lj-~$.h$ZdE: nfOt^U>[SsIDيw&MN-Q0X<@TR`xN(" $R\Qx߾&۽6J(LTQ~~UL*/"nu:K Ċ/48 lf4RYgQJ g#U+ve5v.u*M#8“DpTk&c$J%i\(\wBKᢂacrA֚+"B%(te U+.Y2î/Q083&IE0}qb`fqWjuxTpu/NdN>Ux}lƖoxY'phIGC&`[[p>oGio rni^Z\= !›D )()i{$P-)Q| }И*2T,oGio+då!_Ge[ \v\ˢSKĉ_' 藹_od*$,k{½ʑ)y0Ƃ p -x$cK0r~bޏ/oQ`f*J^<&ȴJ-Q1'pǬ^)tJ.*[s e̫iZuomeL+gNe}om_a6rrODiE#ca'){7d  %LPSԔ$ƞ뉧gG⭔N^s`B$VfZY"a֋ۢ(m& Q7(1B&{1Ĵo`\XS\U>˙VҴj rAT_nJM/D ПB*U"f8vX:EO2z{|P`qu{ r]8 KTZch+NG͎G2 ( jkL K5M=~qyZt8֭ v?)n&bYh(cJ֘ioaRĴ̤`'EhU{/SwE@]%ٶa%D7 8'gV8q.\,hDӓ1:w!wC@NګjxDVM:aA+SZ`3,Ccg$EQ#eB X ʷֽ+MmZ4"*L]QxR->lex^\Hx #:/[hL:zv/hUD^8hHFZ ~Ș}[ UUƫ%˛5Lpћ3.%D SpUZUj[[ViF@tU[4Pͫt][(\]4$6ܾei[=~50XlZ%#EUp^=(˖YFN2ӽVi930Xw"DɲEwu'b\N;6~5r'Bh@]KXJ"~q$Mpm/\ H.bgf.ˢZuaM\þ/jO48 bMt!+XF dD5Ez$5ii:*Mٍ-_+@sB"5EJCK!|0O2EΞiZvV_i Um"|KiD« p}&N O݉qZawD¢nZ|po4Q3<фײS\[+\E*- JR5DRÃshsԆzsCjDD«䫨 UO14RT() ȭV8Y +s}lƖh "Vr_b })|5蕙tZ pe) $BVkk&& qjUDD]2y+7 CuU:+~UVګڱVۼ#,ӪpDJ^4 'K"l) ЯED֐K.|$8kUTΒ05|4yѽlRy i~04/.$E z}ELeVn-D>ĭ+ >̰md [[H͹ -VaJB9t'ޞB Q'<8 r( ȯWZGva*w:qƽ5%}@H<-+_6󎾎L2Dluah \+d!J'9oGion9[ VQiR' +evb$z'mU+0TKg 6-38 s!2Pl ziO 1P2'e"ޖ*sebJ}bBY?~C~Itԟ7f4;Kr`u&ZOppX5Wӧ/G:ݾ) \l 4yN6O|(KLw,gq1.AK6[MHCxYZTaǀZqpa bۘAK<2pI(]i@l[2mċXcH4y4#Jx9S .ˡ$&:fMdaTe$H_Mx!fEΛ[M:(mĄ+HڹƾW 'ዞE:Ͷo@? 0$oGiod(`IEJņml(_wRaA|*k&N7dphb'A24g@]=LJ`H^,5{J آ7{JWyqklDp QfmL( 5´`kjM$a Fҋ аAK:ehQ9he[1'}lƖp^jI^.x=gfj欻 SS޼4}ޏO'C̺ٝ%(aZMh};94EZKE.djXWN W"$֦ LUz>cK9>nQQe)p SoQ("6`JٷDoGio%1.H4q6Xu'1γQ)^r^TPmUV\80jgѫhzU÷1j~t <`Q(G-ٍ-8 lf4d4}ޏͭpGl$l-#d'n"r*4_O4ٴ"Xt/"yi9t!:%E_;8 lf4d9f؏쁒c{⣴'a$LMːep -YvmʪNI/l& = EjgoGiõƀ%^$uD>|]uZ b~PQӄW'G]Owb_1rJBoGio`ViT++/ū-`ܦ>*P6pnݕ^&K:fTDUTZmZCU:RD7 E,UTe&"Z0t:kW"uͲGf+fÍ3[WT솛jD[J+J}cu)^q}IWVu*%>4}ޏ&m-8mu:w$Ju{4}ޏ퓀z>cKNG-ٍ-8 lf4d4}ޏ5 r(1 r(1 r(1 r(1 r(1 r(1 r(1 r(1 r(1 r(1 r(1 r(1 r(1 r(0*Dptr(1 r(1 r(1 r(1 r(1 r(1 r(1 r(1 r(1 r(1 r(1 r(1 r(1 r(1 !Sh-!1AQa@q0P `᐀?!n&1h=ج+CL7V<@@6 D%@fW֊ 63m?Gn]<I| 8QDW_U6bskOR&0Xy4=ZAH,{Љx o'P9B1 a|  UРg0% $iD!`Μh]EyS-OA/EG'{WzÏK5mؖ'{MM[$MDM'әܫhd'ɆDx]&#7Naa͘xUe9B4oס)Xǖv{J'$5kI3e+'%}|_b e.&SNX3*2" oO#-&G$ {n]9q}\bI +ҍTPz羏5FX zka|Ѻl ,"%XS}!tLpxI.ԗscnߴPk1A7fVHNN\/|dJ%eyRA! z˭I1qk Wŋq, WRē);IHB XyRYXi:(6m{jiK1Z95&Ιx)NXQ&]ەo' :2k4"ڑ!t!"pNT0dF~w 9)Z/lŃd@XҎKW94TzJgQ6zi! .:PlF ̈́]'zsSdcKPRDIH$`Љš&[we ]` ĘQGqmDwQsL2ܥUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUIp6$ U2ҵtE2#xC ][^mzk׭[^mzk׭[^mzk׭[^mzk׭[^mzk׭[^mzk׭[^mzkǤKK)Uڶ=mzk׭[^mzk׭[^mzk׭[^mzk׭[^mzk׭[^mzk׭[^mzk׭[ ?s˲WJ~v/eܮZ_.˹]+S]rWc=k~?,*c&A:i}+l)̵#TU` /E']]u٧B3bFs‚8k<$@z$ 8z('J!  ؅( A> *fe2Gd&<.tzgN~Y/ I: A@,zҲJ)q'4OSR Ҹd ( V!xM*ʎypIh4*JW!S9֐TI!8 ]]ܐQBKJH?N0݅k5vs"z~/H`kxgZ03K_4 刓/t4:5!80HmRe%ďjT}`yLz.ެx$L|jF b]mb`.0S ,@]]"K`B }4'@K٭Y ȍ&6L7A\ yR)r!arWc=k~?*D£FhS D=Q҈K%\qtQASʄ G6- hexL%K> vA)p*ڂưQ34#}?4PjF+s4Sv*I!:TwA%=_ L4k{D-23%^|R=VN cT-2*[N`Xb5Q_4DOl0u$J%ZFCp7:Q!D7-"泃Eټ]P΀* JYbȾN[`L+iUdmK@ow+v?sֻ?s Y"fE# י&EY+bEj< L -~Td G!, HH"6J%`$.H>N㉌7)FPNQX]7f}hBIhev}@`n( Lbg * >;.tzgN~@ɑ1ݰd2(2P Z)n%˔OzS<؁^VWit XS2G4W:fNeN |!F KP#"rN$12u;TR9zV[ RXO\T1 ǵ)0@[)qⶃ92iP78sNy/)NE@b)l%gEbւʋ嘣@`80{ tzϐ컕һ6NޅCn& "0,/DDH, ×U`]_S6zgN~P,DĜ<2ni / $žGWJ~LhyKIBcUI%Y]N*4bR8ųVMdag=gĹqVai4 '7pB}QQ+,calJ/^l&ڵcBq5A qdXc@r3c\BHХܤM1ELj%0Ɠ I,!hIpNu9azNR`gB D(+̃*t"A2V-&RQAȓd8(8&'5Qdv p 6(l^X mZDu`]h>5++.k~?(!,L @227Z(CCblR!lhA-&O-w+v?$q=Xj88Ё &r¡59ƂNNE 5=BG&.'8pN4St`´LCD(-ӓW1,E)7!"VVQ))-OV"t yBw0ByI4΋rRk"˩΅e-H$ CQBK<:;BsxMJ,F(yԺq/ғr`HcEg(b/NR`((BBq~^StjF GAK}S&? "jj L)."IdԂbd`|ݗrWc\<*@u0Eu⹬-@RDkjѴA35 @,H'вvὔ/L.K"&&R#2̳Y]މol2CeaE隈Z r.űA, ! ~R($babB֕ZJ Zcř-\< C1u沾0(eA' ,:-*  3_Ub@caޒ)M#*Ţ*BtpP *m&uRhAsX0/qËr\ p"q3br1I@MmiO]9GF˟HҚwNT|YoHqA, VP @" 0Mp F9~K Sճ!.|=h`7I3 >Q ͤ32 +u@؜2`i"S7 "X-qb~SWJ~3$AmcH&`</ QZ@ǒ]9GF2<#,K<\ Ob@ f|K*Wlȡql dd0f3>`Hs8'+p=WzD5310{l&%ЉZԇ ZJyN˹]+XhCI)R$̕+EQց6$QlO.v0נr/ߤO`Pc"rh. #rS٩9OjKe9PT/s#daaj$ $>p 3I)xNQ B]}j_V.<^ a/%G F#tNf9Sk=((VI SWJyC}%6A F0y`2Mzh`",n瞸0-컕һ]9w+v?sֻ?s˲WJ~v/܂2Z54<7,p-$XHdiHbf~Aڭ^l]]V/cFzFN̓&2X_sBO]*<)!8J6MdcXar| )' y5 sNkOX2 bAFF8ef( r$㊾χNfRR-V.DȄ0 YDF.tzgN~Xz,J M<@sxDXBsjrmN(#'@Cn)KK @L dL@ P¢@/O8jώeDBTx]薱n"Y-63~Kd?lBD7t:I14[SGyN) ܠ`|#rkh`{т "9ۍ`?"3-Aks[>I{f ɰSo\[UKjXJ ቧ|j~nO,E.Ogn?Q0)jb?p4{ ! 2` 7lOt-Y7fD6RX\| #_HG!6'?x#_g +MP%\YbvPDQNp()RPۉ7V\=_FaZ hőndإO뎔b G)MY/hX:6R)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JRw_)JR)JR)JR)JR)JR)JR)JRnjR)JR)JR)JR)JR)JR)JR)KEH 1Bog,Y&t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t6t67FBB~\9999999999999999999999999992!"5NDNDNDNDNDNDNDNDNDNDNDNDNDNDNDNDNDNDNDNDNDNDNDNDNDNDND*mAOno8i}~o7z~x4i?[<_w_ރ| /m : I|94iDsDeytQ6b`~sxB؛Ww&1|1 Kii`JfYW)x> /m!ˣ~bB=&r* pfPwQy/ >7* &!24v Өy6`JzEBR(- ^Kx5Xy2g`։i PPεExch kLb4S?bw?[u(2-j Ƭ0I1F{X%-썙|_w_Yr/. 1+8r2tM pdxL8WHO\1-6x7'xN4WҜLDkBJeS0M#~*%F|_w_!ӸX(#=t/3' Ww(,s'x''xJƼh9L?Rj߃ aXKP3!FD6Dc4oAOO D*j![z0W*Ahi}~o KV'z~ 7*^7Ky|ouM>7qno8i}~o7z~x4~DLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLt>'i;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:?xKa s$I$I$I$I$I$I$I$I$I$I$I$I$I$9 $I$I$I$I$I$I$I$I$I$I$I$I$I$4E>/7c^nݏ8!y^Gs\HX-Z$ (EF/ݏ̱?N)&ѯGai85ks1'D,B C(ЦIO!y QSor+٠_zdzIe/a+TSk1 nPK^nB1M.Oq%9۳S:?AL}bjiW,z5/7c1)51C@Fqau"Y!y $%U2T jXcdχ^n&bn5aGlfb%[(a e"ˆ^n%J$WCՉ#6fMi& 6bQ l/S9U(~BSAivLsSB&}]#X$ւ,]L ˏ)SRn]A^#d7=ˁ C[+h,!0'kl)In LLQ !y-)n/5+V6ޣmWQkCgAF髈E,4_?WO!y":ރt ´Ԩm'#PBFY9%14&($WKU+ i*FP폠2f[6XCdd'_ڞ9p LQ'r,bX`Z+HTx `&dU7aQXg6INCeE 7۵z7;n[g1c4CYo4k"ݏ!juO A& Ȳi8,g$%XHcb YzuU98`E A]+1ϴ_rf <ԯǙOO7 h?kւ*'Є,u"NWu0>T=:"=>_㊨YT !ˑdD3nΚ >Q!@ѽlXw7 5T "'_& FbvZ}^&A$bEaO!}GZЋ>(@5Bϱ9WSmS'L1m!\? IY0bAcc~$cA5%F(ǒfDȐE 4_r.9A*J͢%JB&(]uvt6I`IF:Yd ˁS-SxuEiThdfXF+"ôkEWjsE:ud=z}Ⱥ봒?F !_7?\<?"h03 !/y7.뫳KEf h9C&*<FRKE;!DΣgf+X7GYF*!͉g9&g$<㾚뫳>I {1(aU 6|xcIp3̣AKQ,}R܊e%Gm(m! Ț 6S U鮺93@B&'MeHCm&ĿDDCQڋ^Fl% Aph5{uWfJYpQU 9| &%'iv6/gR뫲'9g)QGZֽ%gmQDՉl 7|@sNv=@_LEfTe{}%zOy}l-0P(!l$A >B֧-(IK'jYKDýFq&%LfUAB$[|ӎ{N7돌;f @2-@gCOw@8` W.H1l!(  +")jP Y XJ 1'Ky$C UHk nl[Y08֮p wـ&(_EC xŽg$ Hy@ ?Z8aqh .DZ4M4M4M4M4M4M4M4M4M4M4M4M4M4]4M4M4M4M4M4M4M4M4M4M4M4M4M4M=ԡ 80 0a `0 0a `0 0a `0 0a `0 0a `0 0a `0 0aD`Wàc `0 0a `0 0a `0 0a `0 0a `0 0a `0 0a `0Ljx %DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(MAQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J% yѻ^P(+~+jA_;7kߜ~nݯ~pVvZPWi7w^vn׿6fo"&EY$$PPgkJ2Ja#8*vÈ!/FP(+='K^T&Шt髀 Er0 BH'( 0:#ѻ;7kљ7 zj8JYGc3MBƼ1  DRx,yz hc|6>k4}0f H NH@N? nV`3=P oY &K 2թ5Li) _$vL(Q2][` C`0Gםpj8@dPBeלhpykٍpM+F&C ,w Ђw%`8 jp.jF+x3R#pnrf@ 0VYbrmd(K; 6D  ̐@,%\b*Z0 !ب( )肠T1^ILx z0w^vn׿wm)/8Cn Y"@5v6a64A҆m|Pܩd_n?#S TX㫪̷xh @KҰ>Poo, Rh(\($jhK`` OD<(  c}dtCG(U 8@jH,/HY#O$0$A e3)PO eX@H.y JCj$0EFK=ZPW|8M_퀠(<;p4J9!!HkÆ^Gx@Ҁ2DT2`}O9/? @`2LY4 p:@Kюr$hsH'M d܌[ VYq:`,7( ?HݯTz`+T ߵםAkURsvZPWjA_;7kߜ~nݯ~pV,1A Pb(1A Pb(1A Pb(1A Pb(1A Pb(1A Pb(1A Pb¨=50 Pb(1A Pb(1A Pb(1A Pb(1A Pb(1A Pb(1A PbiUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVjL uUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUS߻ m|8* p.jBBtC޻|t]`D՝3:` @ v;z 0֐Mi@5f`i`Ԙqh5B~R!2_t 8>5`\R HA3j p5DI oZ9 @85 }Fӊ.J`O 5PG"g@a8Z1T@A@"/]=`~ ace 84EQ pׁ@`x L4Sm Š-mAD.TA`р;HT8&D/:xa @4 aP{8>@d@Ԉv]+- |F RsXvI@8tP0>8bGLk P[lu^^}@4V|`@>p0@]@ؓo@ !ݓ~a{m $syȉ dj%h%@X*u;Q8a{ | 訤t'|U0KDg@./ Ɓ @j0#B`0 v]g DR@ @9@@E ;`%IW~&o@|g:ddL b0;Ҹɨ& -AchaM|wݢ5@( E9>rA`lL0 JKcq P p@yZv @o/A)g"G uTO@`[Jo0@&  p ( _$#׀|o0'b P¬zـj|Āxӓ oz zC" {AS]@[!ƕ݀e@`)~* "1(+54*X0Di`h1-]%R7 -@p8ĸ 'V҂5@0R@ ,1\K12DRKQ@p( Q/-i@a oXm )$6T,Eà8> GR2*Q[x(!Ue zu$̈\&L!2 z!p_ ~K[EK@w.^`0_10rm8>@\8#  l@חq@^A` ^'X(hphܞEƭ\lԇf 9^a8(rY745j[8G-GV_d)O@f@ھ<OA@,8( j`@P0, )AH?/Nb,,nQ|>`ٍ<%m4^qE*^8`=H@"A@$`ՅHј*65Bx6|K破ȬXƁ $BNG8jE5^N@qɺP"@i`0}4jUid. P^ L`-UHSpo6SclC@47(=y*|@GU,q"Z ͳv,JJ/oI> ʄfRHLpD6W@98g, %ȧ0=dw{$ύ à NYwo$0Ղ#"qB֞V Aوt 0(t7hBh 呪Pa1ۈZnˠsN6 " G*!Ԡ&Z) WЃ -&K *>wJ ޔb^#/%cHȢ 2?#@xXq fr Mm+Ѿ(1 K@} M#Ә\. pv9& @ M!` 'JCGH \@(: +jy@, 1gjcz1eŲ#P g ;|ՀUYT(B8K`ۇA@(.;B j (0€%XC-jxqoz-ݾq4.$᫱ qm JcUQ@Qmzd @Ao@2 cc +@Bmafp $6 H*5Qp6 o|-^#{o@?`Hw8A[R#P)3so@q6Chxc@@Ȁ d(A @ . }1 f zYV=m@H@ڋ@ z^x7) /كRP]ϼP ik]Pz` 8leDC@6 R>8\q^4p8$|8 m|TJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRaJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ?Z*TP././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/essays/importing.jpg0000664000175000017500000025150000000000000022611 0ustar00zuulzuul00000000000000JFIFHHExifMM*>F(iNHH02100100http://ns.adobe.com/xap/1.0/ 72 72 Inch Exif Version 2.1 FlashPix Version 1.0 Internal error (unknown value 65535) 1024 768 C     C    O.2ARBe&zyz u90eDTJJYXDO>{k_wTT!H%O/m$V{vfuOvsdӚBqגԛ>%f"738&:5׍Jk%/8yOw|Vź5zX7jK2 f>7콷mf <:yBm5q}Muؙ]9O"/}_3_Iszw;|gWV_?qcy>{yy5߳]_1pt,xhV7Ws e9(:|o{owy|^^ybн7{, K~:>s$u'tmn|o{|ަۮZq[xF^M^MO>FjT s/=^woazݷvޅZ<Me޵wߜ8IP "8>kmA2Щ`@ BЁb}ǒ{T]z)(`~ uaxݵz>͸UeY?ARP`"yg>ta\_J㷟N.=>gtQ3|>ںF{h]^:h9{|}>L]^.}h~7za3gBs_e@Cg^5yd:Wr(_@&s: |к\@:oP|3׷^g΅ܾz νj>&t.>PH @Cg^5yd>V;s흿?lOf馤>>R +΅ܾKʅty?|EK}$ A Iib~IXPuޡg3oϲ z3 ^}S˞CSZܼ攄߾7cۖ.?Nç:Wr(MߞB޻~{ Ciߒ*A`Mnrgoߒgvr*?lCWjܽ8rrgmߒ1!hL:n}<;8"@Cg^5yd;~9T^>Ww>~yjJڗ8|G nloЯ;ɝ Ϲ}= 8Y2Z&AL!o(,ɐuy}-+SCۂwNߞ9O?4˾?>͋g|論˰h~7za3^~7H\:[rk ;wgeݸ} ػ<,+v.5sGW_7|ǞϪ@΅ܾ~cϜ?AKcsۓ^L4+^|OjoO|}W?Htzn_R6ǵYƍi_qݿwxYo7fsNOTh~7za3ȿkn{3̹bOš79'?j,`ۂz|J'/>L]^.}oGᦙ?!5s~ ]hܞ I1}\^n]ׯ6?Zgsj=^>P9=T?ri~FI޶򥭖wmd~F]@Cg^5yd>D /_&t.>P{o5 |v9t+-< H*J%$WI}Ph~7za3@H&t.>P#}HhS|$H:oP|3׷^g΅ܾ"@z νj>&t.>P4=_0LuW@3ux/uޡg3oϲɝ Ϲ} W 9{|ɝ Ϲ} W '>t\_Jw7 W]|5d%{?@#e %xZȂ(ˤ2'I%xkL%J` $If'JRP,+n~mOGb+w'-'ݚpߙfmYt@Fky@(ĥ%x>o~r}-UXaN}ύj)vyVrF]'ĞrJ.)I@~Og>mo1چm*7uxv9}|w,O #5< ]R :m 7 RsY>E:(t'Ke If'JRPi!xh(npH9ѶdYt@ lUf'JRPR'.<ł $)HnrN $@Yt@ CgI`koDIFky@(ĥ%0^_Sn!IGZtzoZvmzb6~ $QwJJ`_Iߞ*+d"@ˤ-׵0M#)2sk9|?QR@Fky@(ĥ%$uʨ$ 2< &$QwJJ%\Gjѷ&#{fQ~ HYt@ѭneؤ$ĞrJ.)I@9GasZ:~ׇLEb+Z?_1PdeyAܾnZowYCdbNc'PbO9%x>?_ƥ;}Vkvk^5k~r~zn`2< O]w.4_CrL=g O?mNmγG0bO9%xm^};-n3gag~ʵoYt@S_Kx}XScyӯhԶc ĞrJ.)I@$(k_e$A$T #.$$V.TĞrJ.)I@$\-T JШ,O % JHH%3XB E%)(,kM$$#3k׬ 2<bq}hߋ)u#.c?[2_WWP}K$Fky@(ĥ%x1ǫ?\ )-6sZmm/pf%3ۗ[ #. __[tcGcrhdcqѶir/b~jmz_ӝO:˥&v ~CFky@(ĥ%o}g6Iw 3k:÷gMGΣ[ #.3Mpn~^it1~wyG|9DZv|/^63_fNzeǣ=Zxd ĞrJ.)I@gzvm+Zϧy90ף+գOˇ:3rny #.a촮/\-ʴ wi]Mq0rCXty*=xҽN3XB E%)(,,b $U ˤH~4HdA J}_@bO9%x By0Vc'If(a@,O Zzۆבzj2LKKէjbO9%x 1p}ɔ9Qži!9 dey+de;7W A$\^_>K@bO9%xaz\8;ki;-u tv){_,O D\A֙^h(fInnҗ7ѻvӽw;ybO9%xaᯁK4ebx}ӫ̲q,O D\b\ܝ mty~~{]yYu=ia͝gIk-.Ȁ$QwJJT㛂uOZt/keb}K>Y\F]'&*x#m)8xW-x=/+٤m@GG-k_,/F@f'JRPɡ(D`U #. '+^~`LU@I!/GB{ntP@ˤ"IgMi3XB E%)(^mG}n.ddey6{lߟԟח?]mVX#5< ]R!ga/ KG^j,VZf*2<P9u55 y}(ߓZt9w^I! ??pߝp鷟]z8sty #.%Tǻ= snkM~]>*a3XB E%)($|?Q?)@ #. ~Pp,Ϸ@$QwJJI,O  HI*f'JRPCТe]~- Ӊָxz:__U癌z4ڗDBaXI2ڈjXp1Q) *W];zgF١@DbO9%x %嘭jz[}XoCՃzOsGek2<@9^ah>o~f'JRPLJ>L$$ F]'JIFky@(ĥ%uU{$y;T3^o^Zn]Jz5If'JRPJ^O{94vSv9vw5©OiJtEyk[yHIf'JRPLWpkս;uoW /iHQ2okx㮧WZtP2<$QwJJHkeK=]S6ӓ=^vyuٵMxk ^N}3t deyI! C8ӅthyIdeyI!@eyI!Og 9 8035@4P67`!$1 "%2A&'[űn<}}ch3%l]?;j&NߟEmCNJdv dERԬVb+lE:tIwʰ.,>. iz&X9v6$N1C̲)v%nF@3jf{c2Voo}"62]vaqcFSb̞)XmCYX^Her셈v+I9mی"g\ZezMht,aER\ߎ'=)q:Z(+,S׬/ǫ0? ~;S?WoCS%F9 eyj-̧heNdv=fGs˞͘ݓ.faˮLzeX<`0AI[!܁V3mXmCYߠ_V`~Av̯U2ҁH%(}\ u&,8 lsL>(m>%ҹfC`b́\ysٳe{9ulpACܚiX#TIQJR{d" *צ GF$Feze5?+#/AKmhM_.r9xIKW<%t]),U\M")HD$Z fZX}ѹ"rs+e&[ck@V`iܽYo|dW9hLcC ^/~_:ÇnRk]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:NӭtY:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:N*~'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'RO?DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:xE2s=o}y3~̜y_xwNd{ߺ#s'=f!ә97huGtN{G(K.eT;'c^l2.IK[;2sten. >zq݉O!vc.$NC I /frU0/RH:h%9u #jܕQg XT fz'a,d'u2N*a❕UX鐗WíȮ=rnbYnWklZk#{u~[@lK5۪NT#s'=cv=Kn/(uZ޺Gri5S.bpml fY5GO#9kcpXEKճڎ4߄ו] s j'|a,@>4:lL{Ŵ69U'pV~C/pVQ%%%0DBx̢lWQfc5z9{LiO1}0OCS_tO,$XeWLIY(bFͪ}*9cBy+~Vwq(ً̮W_tZ(7Ų>"BY}}S dϿ+^wߺn89јT=&@RHYxڍF|DXQĎITs R)f|s`<*Ă,c3ر\KUUϿ+̮KMקrwƖD|dPy/3W= rܨGtN{GہΙlW6R2Fq}]d[tYF VBm."fG3A#:N;0:e+*}?zx\~NJ^YtZqվ\aHq2ym0rr)Y~`3?Ŗip3A_}^0 pÅ:NE0D΀_FWMSwYɋON(G^ә97(r81Bk0hu]fpƴ|_/cwNd{ߺ#s'=f!ә97huGtN{GB;2^WJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kR:xE)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbT\+ϴSE:NSE:NSE:NSE:NSE:NSE:NSE:NSE:NSE:NSE:NSE:NSE:NSE:NSE:N)rZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhOԹyae awx|)vD=Gty2Bܑ a3.$rY/ڵ^ի~7]Xx:>C̿CP2?}Ќw"a kbTt1 #ZZwlpromY$$C0'B0 )?n ԤS4#_F"ErJPUϛĝGnk0c`B~5m/&dzM&Lٍ>M %CYb߹3b?+#Y 70ŗ\ e/MvE,1ط`re~$Gt|[4A1m{r1e1 p. -!_eۤ4?aaevm9").Z y7Dq{4Q[E&8Zgպy:<]$FFl8;99r8 , I>ay&6Q@d(d^S3w095GnA[1&Y;#~T zrJ 3 va/*Xe36o^=+m?n_uHavcΰ?n<)4x:>1ɗ=RPN8A-Lو7tN\.ty?ABqä5Uh&6 И8)v1hM1+50lQ&u_lუ sQ FEhĄK)2Bu`G#\#/x!_GtymmI˵ߢ*1M(O ˛_ãzHLd@46I:Tm$מ>p`e.XE!hl'A,~iy:<-ʈ5,Zj$Q_O%;|8OM*a!rK2w

GH?<_k9+^\v GbKF')6 .)pK.VHy2_,:>ѭH:28S($2_i*밲Zavll$KHڿ!ÔZ&؃gZ|beǕ7Y̶!'.&[z,V*lOႶc~$ௐãWU\ž]Y{~ro`%FF3#!HtyܹtyF.S<'.1ں?1P$dB?$jƃ 40'jyznL_9`?q%-l Ĝbݧ"| QUiP|zU=lʉ- f0?!_|r p^6/1S6F]Je̱ &.8q35trQwHձӓ[{og}2{v`!0 F Gt68Hh,"|EEVRtЇn*:>cChP&AZ>c$7&wӷ^_sI )oj(06P}́ny xu₴ C̿})b<]]:<dy1iGdHt|;*T̕:e;snj`~92_qiJB.[g؇ROp6a>JOE$o$  :<10QY$χ0!_|r#_" !9TUXILktg*`:1 8hSaPfVf_D6wfAlq`A2_SH\5@cwQH+Y 7Oa'+ o<GȔ(H2.|e-8௓Hty/-߇:%Gr p2osy63G迒C̿}|;Sty|G5$aFX fW2tᣝL.Fuᯌd2+nE, <lfom_?8 .‘zž2_ϟp&Ja+wp~!4XTBdA?拐XбˌT:yW _;za6*(q@<%!Czkr%f+7$g/ `Fˬm=G \ 6\).^r2҇"&e &&f1V,HY".gOQ3`1'%[LTČP1.]Nkfs VPd&?um˒cҼX;+x9Dv3ty~+',U5\edS2esXZ׹]cq{N v}Ecoae*ID ˜?ʧg.,+UJ6f-y:(%yA|C@] "go&ev譗TQT!ξ#X-ãV+" c/Xt}G=;Z@ɫ1#ӫ=_뜙XX ,/m7cpGtyEأrjI3I~W9-_$ `.8KS'~_"qaOW!8&N˕ d>#/eLY!,o/ 'zzYҗŸʛΘ}P~6j7s+)\6-1fae"hS01[ s`4+.$}GsPIc[}LphBAdae;"F>c/ã:[pW@]Zɂ 1e"5^b ?^d ?⿲Rz SbqNa!E1|\SC6gjj p^0tE}CIBS|eTp:N:4֗Zػ ԛig637:Ng +//ooA)=u+g{@0B򙴃mDIL1[t[g%S"6(US)0)y @.*:TQ 5e~ʦ|~ 5TITo-\cЭ -;gE[C[/֦9?hV(eeCJvb2ɱGNPD͸U"]WLBBVu´bv򝪬alZVӪl%mp~2Af8 T3E`z_P⋼@h-.-o^ A5+fVn+gj,+ Lzq\eԭ*r.P{V{[/[D 8`-[(ච7Za \\S}?,#UalB~#lqmOKTSL[7f{e;l7?߲Rz V9Kg!W~C@==^G oq f mԊX[R.{N=Tq}Э}G RQ?>ri¶_[?[SM~E-D]'rnOe]RU[b$޾JZURouRח-4*Bm!Ѩ t+2Y !TU\Pt\֚Žk]nBܶʪm麤rn ,]VU 2BVN(T /֥Z#p~-~]  B/.)J nUI{rٮq}ӱ {@8#1Q0/O-=?WQr|mo1cEe#b9UU*7xҶkK֮ \w(-ʢs> Oࢢ; EOHꑼztxISWVJP}.WSSGe:*br\dYSEX|;4{W !aNG6 dSckgv]N#OVEPHQSkDž ID4wi[Nf˜Jٞht[HZqtKU%ll&:уu+MUڟS@GR&n6!6ιJgʪ lxVv~r޲QCfSHf㲂Rn=j/pJ1 AB}T?LyWoQ\W{- .( D+f{g6`F#]IYS+pQESBVok7V\-CDu_t⸮ Q:ˋ^ˏӂ*o̻V­ՇOPC~eޒg~ھ]>EC zJٞT?ߙwퟙھ]>EC zJٞT?ߙwퟙھ]>$r;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܼ|Puܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܫ˃⸏Z7>h| 7Ls/0>P#Զom ]psT0h@D[Mf=@XO@Bk,:n .6*P?پ3*> bjn*Q,Q1B.v4nVлKXO- UC';Krn*P$lABbujFnY>'5D7AJIshUBF-R:YQgĩ) UocyR⢝N~I%5ʩ0Tو& R4LxCUc[$"N9NqJ4>- ,6Qc'=BnsTӊ&ZzC:vͷU,.+ī`Jt$ T޺ʡYG&PΊ(JTF2"޵{Lra)I7KK4cWSC$Ni{C#[eb|O |TgF|!o,j]]920RuU8<&b^[bl; -\ WsCvdfMFͽU0 V*M|xo0[C+grMxc. jLlU arɔ9pT~UT.J\kj  19UK Pjי@:@TOK1.[7 e?k"-5UT:SaܹACx*Wɔ908*Ζ;?Ha$O4IS>9a0/}!m9-qiK<5W E2zq6GkZ: ,Dq^923rtj-#+|I) uJ]pyWAŞ\_\V6P ~| QNgTr/F%Щ[XuRAf_(rGuU!hQϏnܪs n/zg:g7HRS^nUE?-RAEo1&  t^|oJZQ zJ/%@ki.fVl( ԕ=<}[*zGϨkq4XWsxPԾX,Bm;U0RULrV/EY6ceGCʔ9zMej$HU4⡛TP VfsuPv`TSnƷܛ(Grsd~&B~*RE[e 'SzӏT`7*CUц&5:pUI /TսyTҲwkyR/N3[;Tvک u4E(#hU4COxzp0>!^EVaQe{y~+Rxr_&b^W M@\n!b^S|j"ఓħy-~v_RpZ(!~^D\̺|MбE|FEQ5ʼIaɔ>ɱJ姑P|)HMM.UT*6CX<5WnG/B$uC"gUxhhVgF rST3x<DZEOm2`jf3) 7pRAj#&IM˧&PUǀU!k)^B|E;z-rQT-lm3*I?2TtbqlT%TA6l霥x\)F i?},P?zXbFpUT遄||( $:\FVMSᎏ *c\pAv<)yUvkhXࠍ*.*8Fx2JR*vUE2|:duTD=Q:7,f2 C@Oh)E5SI+ 6A[4]LüU/i H4=L1f1lӋPJŝtzU)mD>ʵnZ[@|e_W}^[T(fH)jw P:$~oHznRZ ąp|onLg/HRWnۻb'c Ik#U~ $ۣ^*xTɾu!Sx7Et:9'z TϿ .'5RԶMU˾M*g)@sE\ 1\/WǢЮ n__pɔ>:|^%\SD4yq7˩U3@#boÉbіqC7 p[od l_bMc'I. ,>  w*mΡA[Cm+vy'lݢ^pV8PY7GaWbm{-lDX$ҁQۺ>˯W7I+iFU=Kg)BPX&pЪgke AVl>U^7r.Pz*V]m&HP*Jff9p誩-#8#`sʖH5CNCzphQ6V*Z7.PBcX F'i?'Ҽ ~h|ࢗwH 3S`( RQ-S[Ee ~,+J5R5yr2Mt%;-JCaR"a/R(4>OTUx?۷⏂*sGTɻz) ]r|B~[C`Ǘ(s46i,UM[v%Y晭SHPŒxh|U![AQUy$U '5㊊S|U&')9h*KBN(b܋˔99UѺGcTw:ʰO偭_4>\.y24Bo7T$ T\,sCb ]kkP9KM(`ljQm -pUu3`dMm8XXDR40q8]UB#ĵrժX~^ˈ c+"C\uV! ϊ4GT5Xp_F&ˀ"tG&U͓B >]U |T˪2ZWMUdQڀ1# ZĭpU>lq9I,c|nw :Ȅʢv15ALeBhPτBqz4ڇ/hҼ7-O>CQA 7βY .IL#,m%޴cMSŻtk6UT,P|AǪq'>Ui,JzaޠI}gPQP:LJU=ʫ*≖UN0=x.`b0iP_Tr+|.=J&xxNqu=N3ԋ[FWLғǁJ^.*\U|?#UC6 5Q8 OO3M}_=CCZTjOK+qTMnmnRQOk"i,ݵ[[*9n )⎫E&6'KI8TS1ݪ]9rT;;FH} RIj.մB8g겧|tFp]’`a kBJj!E4&3UQB&4R2)*ɛ('+ML)+6s>27JSiӗ'UA0G.JWF473HˢRuT >H'.28Cc6x'f0 O 3>o9!jm{lQ8~DTe*G(}*P憄 q(ߒek">ݏu ˇ(|+@CMTT{2z,F)T9pދWW,C8P_t:\.'`5^ WC(| _|*APo})wqv!['iNĞgQ6CʜhO530o"7{ CZK8Nl4<\nM 49S hb[> T \cu[=AqT/\] -u[bM#-,"X%p37&j#E)PX(cGxN&9Z6ݘmЏ< f4fo_GQ2L#7C~Iyt3+L$}W'H|Q%H,x#GO3FvB|"SHMF(T/)2$|ݕQcn& Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62L͏Qld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!ld62 Cc!?s\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"Y&\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"\r.Eȹ"E/]E/]D$? Ī ]>__. dxyjR,hȞ7_QfkFN%}f\"%;F5xw鑍LJem_THCVW)t̲WcQLF!G+Rhq>'|_UGȪ]>\iD\rv&>Z[Yޘf5#ZElZUsHOTlcJQ!GK̽ ĿCWք Ԇx[ʇJcHק>f8٤t<cFȌw'?.]o1}$GE `1cBؗouvd:D]u0f%Y,ʭ&bUْ[˹Їf7%rR]}䖘ًj:иy.;iw,/DFi />suvyFEy.R,t.>QC%pΤ'b>LsBzd%pfQtFi&F{S']L.Qr&h?tcMY6e GK,N e!vɶc_qm vWo^X#V._.v~}J w1Wi~TI/~U:+;t.Q80;]17&F9Bz1e=G+y喖tcuʭef j#1)YD,sFquX̎Y q1dw(ȥI{ZId^FPlDs4OQVCjzĔ#+MDd6z&P.d8Z5"\/~>Q}q,# 0<7D|Z13s vfj}_ћa]5=bleg!Q,r,I!ܢd_fx*8y14:I/azuvũ"  thyQ^ AQ y1Gթ1WqrP~]\R5 ouvoY YN]|Q-da H3w2'w#R^Dl6!pAzIFC}Ļ?/JSf*diD O-r99F@Rދ0 о:i"piWnGZfYj{bGA^],Nrb}Ļ?)CAbz1CBJɑQAýJB/"cJl]}WW X*%C sԨNaqeY(CP#ľ.;w9w2pR!Bzw1WnG*&G (Itnr9)rdw'LGA `X1WWDKx^>}wrVHV<\"e&7kˣJZ|1J:vnNɌ%+CGQG][,Ҹ#eZިydu4^=F9jFrR,~ N':FUK7 5tC^tJtY,a; ctd \NK7=MdF᨜ɒTJ% 2r3$F$+1Ԅ '$礃qWc14dGb&bw9Ni3ʡG<"0Ȯ/7&AV[c &>݌K]s*Kcuvuر._]}fCeL/,Q'_L=&T3"R[55ԔnHEɘk&GQ$Q ܈I1_L uȕ#78[F835}?L\4ףVv}8Dq#qi⍪">pPOnTEBdF=suwnsCsy~?R !12Qr"34@Aaq0Ps#BR$CS `b5%D?ҭ@B =Б46Ͳh +"jo+ Te T0ꂸ6.OPUM} K+][]בaJCzbbiWJZ4k.MDYT @+@rϡRyR: *P[y'beJ ?"'F4EA?aWRbS-zPMT/29B 4r?UCvD% TBeIL7?#|~[ "feTEBV.r!JU +U/yXi&&Ѕb;y-g"OaFb~ZG?#.-,WJCzȏPT%Jp:DZK8S1էU>`2E,)W=0\?fڍxɲ)?u >c ؒWF1I>1iRN+a7CiYԋ&8⬡"GBRu_~Kʨ@lcR[RHP$% Q~SsuaU-$ħDU%04V\}mP ˒lpYizɦV1 vHPhD$#|MqVlkA_SyS T/(דs#'l[um0}OM+zVP[)9Tw1Zi c $FA#ekvjT 6$"{M< nfMߪWDzL8GO?hhTt&SD'AZX>O 5Kt^+)#>ܺBސTm0#":. ?^(ȕ 1(P OqS EN2OW;a8,hMz|aI_SyS T( Jkj }Aj~?2aWs\a5ˉ?fr*, JUNQ(n( :@ { NA˦64HB<6_|0RС IJn+( _Sy&w>O&@iZB\}VJO]%jh~"JP)I"В^?_|aRE$BeRjw E8,򐥅TM2 BE&{!WT8ԣ%䘒T<66W[i v}?doR,<?H:a-ƬI?PF[SiRh ]&0HIp+N*>č6ɉmS,2컌!N0!SjZ+2H ›JÁup)Cv}T7fZ#RaUp!o*JFIF4T &qp(a8$Pn*pz|oqqS ?RZX>&jif%̽*PK Lݠ#* LI#R @"RLJIb5_N ſ0W+OQZNgd@1i/'NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN:̪ˉJhi_N>wG9Ӻ9φ|4sts ;iN>wG9Ӻ9φ|4sts ;iN>wG9Ӻ9φ|4sts ;iN>wG9Ӻ9φ|4sts ;iN>wG9Ӻ9φ|4sts ;iN>wG9Ӻ9φ|4sts ;iN>wG9Ӻ9φ|4sts ;xiNmwqh-R7sts ;iN>wG9Ӻ9φ|4sts ;iN>wG9Ӻ9φ|4sts ;iN>wG9Ӻ9φ|4sts ;iN>wG9Ӻ9φ|4sts ;iN>wG9Ӻ9φ|4sts ;iN>wG9Ӻ9φ|4sts ;iN>wG9Ӻ9φμ4wU,}F;1ziR>ezeR~dٍTMz+.'jkԏ^wԟ>vcU?8^|˾Ǧ#W]'OO=4ש22?2|ƪ~q馽H}If5So IxByCN.H<]+y%IG#WǺx H wԟ>vcU?8skߍ>_}Or{S#!ܴlF2=cpupOh)\[6`IeUd̛O(*ܲO;vbE.5̋E+j+,8Ž@H%vˮ"D.QnRtW$,AȬy5]_mLV^ש2̤γV~M-% M*"0?ኖRe*6"P*b3rd.m΢]Jqƺ(RHX4)"12Y; mM8Pܣ yC-o82TZUJ7mS2Ĥvf]lijeO&ReMsTVCAJsOX)p"ԠwK9:OruurSz QB~NbmS,i#Q^,TˀpSS ?'1Ю"@[)e)[jc K*Vy[BAB;xaWRt̐AK ?SR w0C,.SMm:ه FEw D`"[U,O"RqMP@Jm+ ;uN&p %QMf^HWihf5q\]Aq82i)5 $lԹXDò-7T+LTAq7}as2۬WV8Sͥ,mR~dٍTGfqZWԯnRf%ddq">ز.<IT"nm!,M}жRRc 2PL`L72ͦRBV*ۣv_̳jС}DLG()6K9oURn (S l}. ,ꞮˡojڔRF& O#W:"qS?djV )Sꇰ[ibcGʸrβ":s.VS*,$WWt;10O:m(gQ߉a cBgmi?PDï<$p2].\iT*PxbzT67%td aBI/˾b\꿪%q-8Btļ T|n]^|`^Qh iUu `Y>IT̡AqP,B"Eɔnإ- W q&ka]uԄ 6!oδJPhrvpfImbNO xMz۾DL̫a3x=~63}= !,Vi- lLʸjZ&:A0nnEJvG|KVOb-~kNțe$T aRrE*6%!RcudP \o9Xs-j_%w@L K}( Xi!.E*ҕ톧?ڳa#OjS-"b]2\'٥|0bC>ZM2S5G̯7uRfp|lf( 5C;{LLٔx?JW+4^x"cl*~iS_h 4UHQF.4 ,.J e0?1RȉG1o#ad1Bhv][)*ڕC\%77,Ҋ϶aR>A25Vopx#(0LV0*ˆ-H&K8Z#JBˎ,RjINɉP,Vuژ$VBlSF6gj./%̗Īu4" aFayqJ~fm, 5K"ՕۖQ'[W! vrj{`߬cGƐ-D9<۾Ǧ#WSlK)48\`^_ dgXk0M̡vcU?8^|˾Ǧ#W]'OO=4ש22?2|ƪ~q馽H}I]eqIMixN"w69ͼDm'|so;xN"w69ͼDm'|so;xN"w69ͼDm'|so;xN"w69ͼDm'|so;xN"w69ͼDm'|so;xN"w69ͼDm'|so;xN"w69ͼDm'|so; .11ͼDm'|so;xN"w69ͼDm'|so;xN"w69ͼDm'|so;xN"w69ͼDm'|so;xN"w69ͼDm'|so;xN"w69ͼDm'|so;xN"w69ͼDm'|so;xN"w69 bZ)o[333333333333333333333333333333333333333333333333333333333 R qHy}4u25ziͺ٨HiiRzzdkyz6_L?xfpbZ0_6Y 17Uuh܁գ?;VoP9Qw5t:1lܿ K`ĭNƑJW@X[w 1+RlA [A!K8rHk0:6/(}&jqaI("al$0s W"MKXż(eX?:KJ&y68,4an^u25zmmټW9ze[i_ Fd,`NU]$J$x^yN3ɐ) eiʅr e%$*YT-ifHVbk^+^.J| ptFEdV֥S U6s鑭[*mąBIIRiYR`.L6 D jNFoW._kn@?%\$[|*iȡ=4Q  ₉k\nf_ -T2c|-pRh[:p&K4#B &\Z&Uא*fM+.*]@| t8FJ@䫶霒(DG:j\-4)4LbV:ʖEig-! !*"*WIc4m=]dh<(i;b_Y7E:#iyi#.0}AUu 4ii$%F87 kZRz &fe ,ܧdJd ҄&umA7:@YE@&$ -^zFjқIXۢg qRz6,nU :mA sA^Bmge+i k8€}6 U:hyR@(Hh [uO")bMl&U>5|.ubg* i _)8C/>!YpҔ i-UUWj{ :p.R>T%ؓ(]>'F/S6{Am!5= kyz,ybTVeiJ\^t3,ci$r.pJn}W, ofO$=\a~50̓E"]Cwhx*qJڨľnuN DϮO5heAnHDd5$KAxn]6ڢjtwjCζkfR,z@w\m6"k ޫD'X>?Wn-!hPJAf]I5i KmO#ߕe勭-J(ʖP.ꊉ j@[ηo6[9RQ[KHA#鑭[ξci*>[= 4&NXTj Bv\|e9VyiŴJTI Ntí_HMr\ %,eE2+ˌ dۮmg*Nu^5,l5 A!!/GpU I'vQSiT@=W\&858Z(}bgOn 9E :cHjYiY/spE$f#2dLd1+9yrA`IopœLIiOuvCm}B'q1M%\g/^r"telL=0J.h]t'YN6U_A9[%ey}bFJD_2le#)<8Ɵ4%|)֥(vH9+,/ dq5"KSa ӂLp-i |`V+_5/*5@TF.-!6+'|.S(7hkۢ܎h i]ۮK*ZlV rȗOhUgI3et槺J&C9EiqL#%(|)\BUύo:ޯDϑygRӂƒas˓RFH:Ԩ}'Ӄʰ*Oat ו\aw]?qbdyR*{af 7]t)$g}`0|(SQG&MAeWA@sR*[ZNDJHltd5*Q센µ֓RJEtKJG,n`?|>S,- (7<â]AvMAm(Aʕ M`I*H=G"$>$1LU'IeGFu6LNqm'T/\bJWg|#q1l1..RaD!:p[dh6+?SN'&34{Rh4+TX,ř,[NDB<]ODģ+C@)-O/˾4x 1/7KM8^]%=oцoW~uuPRmOXx"e8}GdN fErVolp4Y@SMG7dpzNu5rQ6=#%T6ܭ2{aW<2Z %GE?Q(I:(פn7VHS,**DU:ZC ޥT2gum+.~ G/h18sU ˒ :Մ|2-qɧKU0ZP7"^q}4hS+j^QT \L8lHBJzߤK3,3>1?J~KT_|,>m>ɲUWDu^_|pJ%Pl UΦEn7CҮM5 lWdVWPx!|9RiP !&G&PCSAJ DGB[aG:cZCs$Op&n&gM5쥑&:֕P '.X8K 'ݚeo={ntmwFaiUiW8 ~)O[0Si,+,6"}4}(UAJA[1?LO"q!mP‘()*5b-'tL*U9O@0KJ+E|"Xp8ßqUn9 "iTPI0 ZG*,iHu(7tK:JS`\nۘSJhb]cY"& L$h {MʷfQ5' o:ޯJ)P(A/B_٧'IpMu^dh_¢Xi-ZC Yקnl9k8Ӌo6JT O|ʝUUHX8{)Ts𕌊 o:ޯHB'%CuG#VM'D=bo2BD ղH k텼mUJ=Qfӡ?&-AMfgLX uЋ/8luUfr2›d0֕]Q?H-OEEX'&UI3*yr̰J 5z#Ⓢ?x4C>pm!YUvCA^8CnoeD̦P2!Lna -$~=-Hq]c%%R5H}!&*H8e[:bu 2H$mH:&bj 8O >]Q)I9{N虙C%-J4X3grkMmZ#5=501ݢ u0ăl^\ENZŴ:OǤo:ޯHȬ!(CvNB{䩓1": z &g.JHa OTQyi4Ĵ%e{a,mTYH-7ZP=#K T>+BJFؗJ* (%$i?³B-'Af%fYFwDxE*xqHZ}=WߗPV[ wkt`(*AK +D7vQ_85m*|lIˣ1$hDHk; MU )Ry8*8FQD7!P \Q `q9E˦0ĬЖ} 5RhNvo%UO}тK_R6I85zZjAViW,˅[]m-ZLp!ԷjGp) 548V-Mg+@f!|V2͚Ӽ<$/*I ɠy%!S-*/tΈL 6mk]MU haMIY7v0,)iD໳0yaMpZ1<󆍶RD8J,a8+ ݭ}coLo:ޯD{ן0o u3ײ%eԉ[5⡵hd4EahĴHT])F bfRrvY2+"{~"i`,0,d}۲Dfʊtpޡ_W# 6 GwҪYrȦD[cp[Nu25zbZՌj -R|P0hkbA&ҝԚ,7(wAvFurVư&t;TQ YYfV͢һ(aO7 GGF(A/Lڠ }&d%{g%<p&}ADIds'ZX9F\}^n}M(<4J4ҁ o5+O"'18 sèqFYMxxm-P>bw=hDD@8I;DÚt0j%k2Hɚ/lV$Q0}>Z$\6a=ʂI.I UzHQ2 xS!&\kjrM $o>%b^zI."/" U/t{(?@E~sxc"I}b&- =ڲã%>U/pm@$CD6(6YO]MH> +&-Ykk(S@pz/x_ZB<xS^L'A$Nc_j%(pr~)ğ> ΁y4Tku\<_qkx,Oj!MI#nCq 묽4ʖV+Q"/_{O{e3_^?(-!IOK7ԿwVizEdR #34  HA;{^.ރW8UrчSɞ+\㮿w47^,!ldbmsZ&$./\[b6T,Ts8rN ]7xAD% p  мTXAёsZ]mmt^!3ELAeC za\$(8M+۔DCb,o<ĉaNPC"l eQt%"Aф8J^LjGʏU_O ,+ (H"\pCMCLU|W$l‰-֒(2^ Jd({)tȄѵ|#pYdBhvvn$@HfUPJ 1!8Pш&?^jŜsC EJVӄx<#7o~syQ̝Xxâ& !}ҚDHO*=!_DPbM5]}nM'7rc;8~&5 hI"aiiiiiiiiiiiiiijf]̅rM4M4M4M4M4M4M4M4M4M4M4M4M4M%V,@C`̏dx#ř,fG2(|z2 z ":!HsD͸LJ1u?dA\`'ZҀ*/e*B*w=btBNケB xerƑd:C< ]5 K0 L|Ճh}`o(jѠF-s X\$-,->ûJohI;$ vqEbe½CM/#dp!OV1voFk3WxDvf̠HfJzE !35 G9*nTOQR-,{̓ddԻYO$ftN(BF1̩\)=p) rGކq B`a1 I9"#r1 Q.}xyGh MϨLnoZ̙;i<ҳ~7<$`YKx$ж퀞n,eduYiޒ%`C0(Nqʶ'`%F,SJyXU qJV@1`b0"f4`MdE=]mVM @\ݰ=:-D+-6JZ-h_,.+{8^ QHf7 ;-MAA,!}O1 Fȭ2|pҤ& ,X }.5NEc7 %+SoU0&L XJC N43%{([ qN\k!"MVCxM ˵~82|Sx@hD{h\WC_&4IE!x"ȕ}!D0&}H/pPQcj!|SɊPnNV T B٩[Baܭij(/Ҿ@,x*C.e맀C aȂt<׋,2'⹱ #zA"8@֤y95Z%Zw \x4q !z^mSJ?>T ^gPM/8|)F{8pf{j6ɩPr[t?κ>_x0m`a΃xV y6k#Y;W: jb!1odfiRa%8![zT z[Ka7Јf.8PH[[Kx@ -κ],Y N >r@g/:TU` Hѥ!@lHxD/D2DùRBK;QX4bRX)# ҔMrPFT, 1S38>_t?κ>ei4Thݘ-Q.R%~V`tp,o3κ]+c$"%9%t {2IxI,9Ќ6"$I7s,Kao+κahE6_$^κ>WR*^fX$KF]6!2Sz,ghigbWF~֦t4 >ŝ@ƛډH5t8<MT'4G52]F^!0!^wց`D"^ Wt4 S0r1nTӣeaf3F\$M ZG!2{~ Cq3sLa :ct/:Q%IZwh[1@(CpvZg`$`$G E0M1k=\Q81-u,H *.4TG6: Dbsz'ix:`6MbQ 7y^u?r\&a"2572`8jZPJf9R3 ]1\_1˺?t|+<-5aĄG,W階 ]XJ^EkvVdB `}YHۍ>gr1,P 6Wgf {F MSo o9Cʹa1eqq+fx0Zp) .^u -<&)˼LL*Izܬ8d|/WnIlnB0 w U UgH&m\ߢҸ4;Kk/{QI`H ޓG;0je[bmC\`N^ 1~IhkubKV~,ǨStSx(=ܩ~%L8U2R,:U No GմpMc#|.^uͥ𖣃' NţW0W;JꬶIcґN )I_ P YoPܐB+a'jauE8w 8VR!BP_H\򋦺E#xڍ©&PmV_$R~{aV-{_&ɶrTajj*pɼ!XD:(6Iኞb!=5&K6xJ͸ynu! +L(sbH5)iLz6}ہ@ BHf"4q4[%Bo%u 5fItJa $ b$1 (˃,{ ĖwG󮏙nzd<.^ut?κ>Rˊ3|.0ą-$#%Z~GZ0؃++RDQ4֧bj$ "Z2:V'CU݁> 3Š6$+,$M'4 wvPU]_ JU3l$k" c[᷉DǫLԪǙκ>Shtk'"A= &l9hij-rCvՋnEcMqV{ePG@)iBo{f≝g5Q0"C8nTȰƮHIVUfIE?fgJI̸9n>Vu A AìMW\!X+~àxDT "|U}Ir~+IVܼlJ+-okc @"H̄Ƒ& mfA8MƝňiQ`0J䭢k_+,YxԄI iB "KV {KPgxf](.Ɵt/:NJZt@& 0!_H^x+d#wT:+Wz>ܶ ڐ,_T=()#S xVCj}'D[CAM2 !(֒ݰ1b f&EU`GZ`eW^YAhF@OQDt _TBdޠB#&jЍ9lhqft~bz:Q*0΍GXJoLhn cr{PAIG[e< sۍL.1y],9QriW~ 7}9鈉1Om\^ɞ I+H"ְWS)hsdK4wK@M @)B#'@|(Q$K -9IV,$G#mh"]Vm9CN"΄KRbHZ@PÃ?ȗTY;0A=h!I ע(PDJAz-]I$ ๴%8z K,,ѭ87`CSmDn!xp]eBhut|7d%tox@JBug2_czF^}r]C5>'R1\aq9K»֨smc]1zfP DkS]֡B󮇔$K|4 _a@,~D,Bik퇨R YZM|.^uۗ E ?O,M 'B:*-d]3yC]kٌ0$'WU)TC ?%I_lB㮹7Cr]14<;;= #mË)b̯}l+-K PeGdiDeװ֟2Lō)ܑDA<% sXݚC mHMQ@N=Toa!+K{|蛱d4 lGP}ի BP&V׍wQB$z+v4 y#%&1'A"PA2q>")+9}JZ}\82cd:4t3}/(\>St/: A!D*LAӭ 6da "!8f6--<]9`'M0ȂRw@12elDQČ7?KCH34Y#HM=\d GM ׄO TazQ^,b \1rQ,((BGvK^+S:ZNu+Q] k01> I!MڳJܷκ>bO>Pǂ{%@S, 1Ss8$>)sXM%"(Ȕ(H<Έ{dѼI ["2F pÙ+D$@| 'zE80TNxS o$$!TDf8yu0$%';ZHmj\J!¡$%x`&F3#tFS0κ>c|%KhԾKu:bیM!a`])bWQmy H*7 \A&M/r ,L QDuwpLX2^*s_Q3LnҀuˤJȲĄF/![ d7q}!TJEg$B LVI$.$~hIm#fј$U\{ SIiY}<+DXo%xQcT18M^ju=P=r%NRԙjXfētĈA0fv@36^Y kC~)$ ŖMBd2LiI3<33hڡRΓX$ OX“I ^$Zom)[Hٴf. 9D/f0~>]j5%>htpBl&u/"`\Y^-SYq+> @ʼn')0&1OW+]hy I&\nĐS{76U ثn>Aڔ,"IBRa\D-ҫK,Fj_f`^*lf3(aZ3T+M@aqՓ-A6 ,QT udDTZR&W&-M3)HMb|yG4;{jwt?κ?sUϪgvY]}Wk>UϪgvY]}Wk>UϪgvY]}Wk>UϪgvY]}Wk>UϪgvY]}Wk>UϪgvY]}Wk>UϪBfgvY]}Wk>UϪgvY]}Wk>UϪgvY]}Wk>UϪgvY]}Wk>UϪgvY]}Wk>UϪgvY]}Wk>UϪgvY]}Wk>UϪ(d1oC? R?v(*?(\B'U RzT 奿(X˛.9+ a(YhshQl%8h(t qRJ_EHVE(t+Fg,$Fu^I,,DHH7 mmmmmmmmmmmmmm h$I$I$I$I$I$I$II$I$I$I$I$I$I&іmmmmmmlO[mmmmmmm+mmmmmmm۔mmmmmmommmmmmm۔mmmmmmommmmmmm۔mmmmmmommmmmmm۔mmmmmmommmmmmm۔mmmmmmommmmmmm۔mmmmmmommnDݷ[mm۔mx&۾nkgvmommo+cȘL[mm۔mYS/sQqmommm_DTmm۔m4uM7^momml (~ mm۔m&@ӒMTXmommmizmm۔mu;J6{.{mommoiօmm۔m0E5mommme-mm۔momm-mommmmmmm۔mmmmmmommmmmmm۔mmmmmmommmmmmm۔mmmmmmommmmmmm۔mmmmmmo$I$I$I$I$I$I$KI$I$I$I$I$I$I/[I$I$I$I$I$I$I$+$I$I$I$I$I$I$H?mmmmmmmmmmmmm{sM{L { O{T` /{P{l[,?{ =U7{[8+_ {pbv_l{&:D?e{8mQLNY{~?! ~{-2cl{2X *#{׈{acm=={ea2+?{"go{ wY4{{E8{L +uw:R6JL{ Xs~/H{D 8  &L"{?ptw?{RS8'{o ֤El}G8{aNjnI{d _7Y{CP  Pf{80BCW2_{=_{2I{> GB{J{ﱣ{߲3'Hd,*{N,?VFH>+PL0'{/GOOBy L$jc-{ D,SXD -|{]?c{H?o7{> ;{G(+ͳ{0ꏘy{($+&{|'{mmm%mmmmmmmmmm{mmmmmmmmmmmmmm_-!1AQ0@aPq `p?SY0;2?B]f h(i&_I1xHh<bY lUSi~]Bf$*2"1<hש ̄ װ- 4d?E4h'o! 脆hMIh6nPFSv!5/sLnt"۸ڞRE[CSk,EEhjq8?ֈ g̋cZ26MLr.hZLBAq)Ő_q/} + =/J! #! ='AOF%:BQ"ٞ$j406͑AqwIhP'N?k5|=|aMdA;G@L"qム:j )q p~!Ƴwb(Aņk|>0\2ip>nXgxh4[$~q0%3 :2ܽGޔZErS†5bxCF$0yǀY ,?0@ؙ\@#(CgIGq Q_"^?j|LRI=;kUn@F=!N XEmkL}4[ Ȭo"2 _%zMj+92_c0c3h#;-e)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR/)JR)JR)JR)JR)JR)JR)JRR)JR)JR)JR)JR)JR)JR)K歄Gc>lllllllllllllllllllllllllllllllllllllllllllllllllllllllo''q;Nw'q;Nw'q;Nw'q;Nw'q;Nw'q;Nw'q;NANw'q;Nw'q;Nw'q;Nw'q;Nw'q;Nw'q;Nw'qJ,>W.-l| ZZ_Y<>'ktykc|}gO$'=_I<=(ƪ6ԭcƪ@z\!eiC-cfJ $6œ;] }M2A9RDf(C. 孏F pd3 NcdmI 4:qeCE5\ ;F Q]j?E'_scZ3'(_TSHAOHexד!p4P5CJ<*1(_!"d`5CYVTV"6A (P |孏ܣb:}_-/[b uGbՐ[(oّnoOܢew6ĄŐŶ 2μ(B!%V >F)IJM)~_f4w@5OZ_ka p]Gv(6*[M.WKP?U_PQ f{Mҽ#JpOwo??DFh閯=+>0Bt5|!`D 쎉źIm ۣV;:/Ȕ43EfE/YDOBbCNkZ_sMS#\^L4͒Z2jc`BTgP踎O???E3/z6c9)h +bv 5)hSkE9Z.=M: mGԯ#!׹:5 &&孏Agbm uDi5!B [eb+GԺ;\ !]2+ ؆Yp] !;Y؉|w߂~P nDDE蛣[+?~}tykc|}gO孏??[[+?~ֲiOHsssssssssssssssssssssssssssssssssssssssssssssssssssssss6;_c33333333333333333333333333333333333333333333333333333331R`wDI$I$I$I$I$I$I$I$I$I$I$I$I$I",'$I$I$I$I$I$I$I$I$I$I$I$I$I$Ik!,{Τ_c5.;Y,`lt  lӧK [rBT0N֊mE3 Q~VVMN`FI w0fA#SH-H5Gl~:G~¾7 - ׷2+.F(gh<vmSBFWp|?K$y EV(^Ocq܈o cŰhP4GAWC8aBnZ|?KcVh$ho2Bl\+~+Xƈ'hhئfR|?JR0؋꜈ تaH@^80U%7$"tKXl8Q+CE0Z#N1qkTP][V%j& ʘGಉ`uK!t0b;* W:>P|?JnPS zi)%\}] +WP `<Ą&FN]"Qy[`;5+BŝElMZ(΃ Djh&}Nԃ̷6? JBrJ'yf[ў du\;Y$0;ixkdD P 4?5 _ǥY zk\F-m* 0U XMuQS xsC$aQY$$pBكB dC7 ApΫ L|?J9)$Zvنca$Hkc&NhOzh51/B] Spla5wixߞ|?GqdH JSAddjXc}WFK?"P2H2cl/옳1=3T}w]H}L6$bM􂬿hS-ag26&u_-``H_M F8iJKoPwgcPca g={n[Ke45m ?r+WQ%WQ#M,nܢ)?;-cV Kw$FtS)4"|?GQ/WKaU7H*RKtHq7F1{\Izdi#LѿCAHIŠ"erl luʈRPąLjQޖE j6g1 (m,ci6/C(MVQ$ BttmP|?NqFvfOq! -4oD3%q/quѣtVJM[P|?N\hP*9$C;b)Z19E)+OD p.sOY*KFؙi6,h_1dA >YBy2T- ^l~S6GĦXA!#5gcmB7%JF !.iO C[5?d5J JY٘7¢dv^+Jli_!j0"Ԛ?!" ,6WAEVlTkf&(" BvfX,uz6r( A?a/p(]G"6b`?Ak#U_-ϓC9< V,XՐ Xچauȩy|H!Ci(GY{ 3RĶKAzdn…8&ؼb-}hJtm1VL_P-BO8CQ&ɅRj44tϓ*LA<7ظF"C _]s3~c5Em53gU~8df=}QJ2w|z($A&^W_lbbzhvtX#t.Ȇ+K=aRFŽog2)IkOst:dLu2:H(u}ضco_aANkl~ a+O;weXw ii`iY0D5 _546/v$:]@tB!at>d!"hШ]`Ptdh|?G(TZeAQ4N]ohB:3fCS>߂'.1a'fci@'AN@cw*k.e!{Xl[i'9/A/*Pl~^cpr ? kc5B!B!B! !B!B!B!B!B!B!B!B!B!B!B 1y!B!B!B!B!B!B!B!B!B!B!B!B!B!B'*!1@A0QaP q`ѐ?U!gэ9iQ65|_.C֍ B~O3BS#h( >Q ث 4IR B6%z~j>O_gK5闑R2Ti Ŏk4ɗbV1+,l1Kjv„Y?a JNjfK63i6Wdjnj0dtiCH[FZE5SgHHY?* > O/SXF+YLQ/^lx 长D̿GnWB4 I3O/>:hey.2$ޗ|$+x{~h^ƿ-ZJa%X$0#PЙl[$Ն?a*,^01hCwK]bm+!JJl/ɠ5[E|AQ(lֆ0 Ǒ ^Cb;bxQNB}r^H C=ʉ~b~f`<_~QEQEQEQEQEQEQEQEQEQEQEQEQEPQEQEQEQEQEQEQEQEQEQEQEQEQEQD 3޿5sׁ2޿5{ׁ2޿5{ׁ2޿5{ׁ2޿5{ׁ&W|VF3:V'Oi 32|'m&(;%ɓn~jDBEᲅO^[59&Ō¸#3BEM#C`ZliZZ={o!Z虖q0dYZ;4xBePr'4SZ$)C(Y `<Ⱥq4!+0E}̙ѩWָ y7N4 5 A*4t/*0kXͿ폧!D>LSy>7LhbCLPT)߈!30[CZ{e}zl$uBVj΁\RJ²CdXgOcln AH߲i{/%ddH(h5'{nb㓅t϶YA6`EC\v5'.*}QH\z;!#qz-pX k٧1~FĥT"WSZ ǪՀR_fIٖKqָhXfF|,jjQ5 <~u٧u;!ŇG%i VeŰ䆴b2h Ow\DlFn_B%C ސqKC=f:!K:1"D؜ 7z>\Mb_+2F\>?3߭sqlH?3߭ _fքʊ********************************************************)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR7-1a!AQP 0q@`ѱp?Ė60 &<`u88k]+R)1K } "-# ګVH8 X+@)© Jט]@ċ(2hIӀ LΕ`:|!{&.X@` B ؀imU+S  ܆p@X u@!P4 @JJywYT@0 Dug;\cpfO( HB)x;P T.KAI0eXe@ojZe@5K_-,$8@_O}@ oh ,+$,@#[r @)6B`.xmP ?!z)D37ڻ{UvRGz;ϓظӷ?&O}2`%ƶiZZ~o4XS#PSjwie$w#=;i k װ@U ,'#@pT ϙO'a?-Q]wQh'/}`vmSƒQM[mQW@e1 +\nDd*_s`҂i # $byճ@W<I<+|2: &`zPZ@@@F)'=D(EUk^"z̀?m~F1E77#Z@!$!Q +=E>I/~g DQ @@,*W܀1 hBiiiiiiiiiiiiiiiiiiiiiiiiiiiih\`0 0a `0 0a `0 0a `0 0a `0 0a `0 0a `0 0aQ 0a `0 0a `0 0a `0 0a `0 0a `0 0a `0 0a `0Г)J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(oFDQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%!1u²`qu·[ӏ-۬vyng#4v9n[Y+y'4vLA@m< ȡ#D5D@ "ĉI1?v ) D؅I.DU" IPD4$B Oa D"HϘӏ-2@Ko|f䚀9H;bW ]khN'cr.NcM.6czD>$oHlQ@%dFa0Xka[jajj"ovU:1p%`rƆ֊]i!@,IW-"` ]cF_$t|L!p`&iwB0U8!n ݖ4 x@CVZ 8ݾ%-Yd ԓf!`h1?ZAj:܎*{16͊Hbrmd`.Pvl:rjCV<Xxz{ PC!se7 d4]b QAeR&*؅2 Ȫ-%j@bj`DH+s= qZ.C3 ·n C!/bRn)2 =U @ 7#@=+y:>4UUkCc6$]^iPPu& VKA*5Ț9մ.Fԁ3% k \UT!Ĩb!~F `O Sۮ䓸@A}؅e<c4 G2y8ݾ#r_Q'c{`C[ |z&k1uïk@#& 2l.DCVH|6 &6unҜڂL iQw q(<<4J97!Da[B HL&j <44ϵ@N|>j7*X~@١KX-CDW" ϐjf}A ,mzb -`XWa`P@`$XWD&_mI Pnn\'̰HLXFŁ+j '8EY@\ 5֑'4 ! <ӏ-2!4" &勉@r2FK%+蝅o,V`PjIGր@] 0,!ό"/~HWJȕE.G zdkiǖr; H0z84v9omI[Y+u 8ݺGa[iǖr; lN(h@A D8 (̏@n Xhc0_Sd.=0@ J]t}?px `!.&E[!L➂H i@@bL@Z ,nAAG f4Bݞ$4tgg'$c|Hqf!n; @Zo `g͞<  F$ `eF Po/(Ep`)j:b'B 󌆡9U!,Z6(R?~g#^@qe?@Ak-ȠJ kd@`ʹ g̯ dJ/R @h!eF/0HDEPX R݉H@H(A _H>Jݚ12cd q"O8REpj XHpB#oc5TO@QDgxЈ@6A+]Pum?ti?UX$= b08lje`D'U.v6 DT Ge";DsP!ŶB"bM vD(-(:v N B܆%TbLQaz=}LE@^| @W2l< k GdTҐ @2v4 =`(z. z$tH='|C Eq*Wrdcj_t (>1v:ր@ @4゠PہRD 0:(hHC5@Xԡ+T(`. ҥ~& 0?j$$uI1c`xܐ!k̮"pE$puoX 3@t@a4P@NG.= Lb5S8;{h\Z%2L ?  A5@u;v@pr "zЀ@@mE6=7 o A`DWԬi@`63: "5|`&-LP6E,%.qIѻfU Z!@*; z$*aX5Z^rqJCV ۀ6  i "Կ!C_4F/]= ĵ!9G$.  &N!ŖGAzPe A%ͬ]C d^ pixA[=@ @XM8x6 J,kgQ #SY8^ڗdd֩8OCXtPsX򢂈! Pv?@ > q r}װ-FHp`4ۂ0 :h 9P $=o aE-0` `x + |^6h}3džCn:G@0@?b"@@huې0靳\#.L 4/ɰ@ A(?$&J 5!PM#€` zt ŀ,0-B  paP) 0 @DJxh@A3)U A D  4L`@.(O\D h $Pn_VG*+W܁XHl mwANDHNR0>z2!=7">(^Y`JAD%0 H3@S=_ ڀA0y<\\s0A6 }AzՐ! *l׼`  lV"U䔀0 \D@R0` TR =i(~,(*P@h R 1"0E$#1 т 5i h?>?ހ0o"T<Ar/CB-:hN0!I069ap$ps@ $u@@?t /4+րьYlVCus z@5=#$5CԘfb0>\@ qRE]D.\ԉ-HqT{@lΩʀhHLJ"O  S 6Hj``x!$ft]d I&*Pf}JTD+)3&̘-lz0G oT\$$ /Fr0?z~@O(mZQ PHuz R?.ڝIbw,@Dž8HvڴDL=gm(j08=z@45h[ %(U! J*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRNRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ:v././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/essays/integration.jpg0000664000175000017500000024023500000000000023127 0ustar00zuulzuul00000000000000JFIFHHExifMM*>F(iNHH02100100http://ns.adobe.com/xap/1.0/ 72 72 Inch Exif Version 2.1 FlashPix Version 1.0 Internal error (unknown value 65535) 1024 768 C     C    NP$@Ҏh[&i@}ͽϦ_"& @BҩbV*,y6m< )m/AoCe%5qm2\jv5͙;:&jg&C^3qcv\?uR318>"p[c݊\)#'53c`;6^yǓkn.L[F}FQumodŋS&=n^򵶏kZtg״pz~yޗsZ[\]SO/Z]nk259iAU[8>=5H}Ž .wSV*{lt- 捷Ujvjungom=WV^'yս_O7WF^FDW,ͫww|]xl7mkW%i=OyUmow] ];tp(Ikݗ;6^t}߷z> =ߵzmwmߓNhw ^8:WSxfG+].kLmF۲7~/d<&z[|M9;}MbކG}Q~g_Q|K[)|˯5֭ѷ3ʺ۾gq~g\ O9~_Bs}ӻϸqw^y\Z<e?I.Ѵz7T!6:QiߕL[^o7u|P Vd`Y5%Rjv }~%6v ԑP Vd#^o7^A fC6 ǯa! fŴ y~5,-%{I %0xByK^{TZ~rZrés&yK^{TZ~r$A(M-|:1PHP$p.P y_Qi$X;jOms=b.G ITM-|:1PյMcmQ|PJT &$o/@%~E`q>(m^w/3}6Zf-}ik_T~;+8=[Ƿƫ:Y0LiaڻmJoK&yK^{TZ~r+'ct,= Yy˥kuwM>WM-|:1PW Cz7"|Ե節kDkv6{`6ytvGWچպ} ^R%@Ưt\NmؾLɾѬ1oX({.ų5K[lPxw6mY:ַSm-}9k>e3حލǷGڳ#C;Irhi_` ^R%@Ưt\$s1$skqLbZrés&RxB-ʼEʭE+&yK^{TZ~r@ik_THo/@%~EPl-{寇S*8//@%N:ZQ2mrŪ5 հl CS l@vJ/=-?D .{6;JRP y_Qi$_]/)sߖawq E%)(ި/D0pZ;^{TZ~K\m8-rQwJJ/=-?D .{69(ĥ%@=hFN Gw]RKzO yK@# @J.)I@%~E}t~Z ӂ @@QwJJ/=-?D .{4Vv؉;T m8-rTݘ;f8y&گд35me( B@JRP y_Qi$_]/)sߖ fɧk[{Fvԯzֿ6Ӱv9\D# @_Gkqp%wgKMLW+Û_C6@%x޿zI9óՁH, _]/)sߖ vO_Rsc_^LֱLJLhawqdu=Zͩpus㤭kɃPӏ9=OUmyd@^{TZ~ͫŞlEhzmw6HB $6K\j}KW/2Jmz'׊6:dlW[=h1nFƍ{ mgБ8 l:1Wnʿ3Q ,7h-hd)[Es_ ELW] u+HoߟX69YRv}eAɶlkz^J%x޿zH$>L}{=h?0zK>ks+ N:Y#V[Żq0fyz=?:Ьu=|kc7+D-^{6 _s1Ц\bܱ9S# @5.gw֘:w&nMQ/Nom?j"@]RKzO *yK@e .sxϲeӅųh,5[^qМZ٭Fug.kX!Ybpv`ZTe;7NDqWѿ[Wjͩ@69LXv3`ֱ֫i1E`m޿,%x޿zH^R-@IM&f< 8Q 0pZ;^{TZ~K\bFN Gw]RKzO yK@# @J.)I@%~E}t~Z ӂ %x޿zH^R-ihJRP y_Qi$_]/)sߖawq E%)(ި/D0pZ;^{TZ~>R-# ^{ިy _}+sF[&e+dT㥡k`f @,hHk5ި/r69(ĥ%@=hFN Gw]RKzO yK@# @H & JRP y_Qi$_]/)sߖawq hlڝ4 {v&mH$I 58JX_q^{TZ~K\m8-rf1yCt-~]zgz6v;=;MяHӵzV[+wO?ok69 w_mNM+/51%#9Wee@%x޿zH" s0/D R&^+Y.͛^ScRߞRa69 S3'>lgss*nm_.2Owm;/?Q64t,{+ E%)(ި l9u\IS /DE^T⯫%޷yYm8-rJV&~}w;ñɥgͩ_N~b3cp}]4 E%)(ިҝO'OZc2-0^Jck~)P_]/)sߖFk&>_wMi7&*Hih5FM..sE]5;6^.{6~5IٱvvQwJJ/=-?D^*[s;˧n[\Opql~14ޗΟrЯpSO=h "thVNz0pZ;b,4;|m\w %x޿zH%Nҵl;^OR67]]su}KPz|龱ې_]/)sߖG_IN>RQ %nihI"Q+B),(QwJJ/=-?DWKZ;{Y}Wklb6>n3j[uq4{J2\Sl/D<}-3۷ĉdH$&tmކzD0pZ;:]G/}@p$1t7 9)<={? QwJJ/=-?DƎNNm8ܺ2dl&jr/yK@ZƷCDlM"lljzۘћSNümM662cɃ$5r{|D FN GwR<ǯe]mlgǎ2##.[Wmǭljx}X68JRP y_Qi$  ;0//(p3yK@Ϛ^Tcf٣bgl}|tn6w,>7mNl;@693SYZRRՎT֤ Ns S{-oJ|E`]RKzO yK@@Ў~MIîmf6qk.igblۭ1Zc'~1n @ӂ /m_?s6c=mm6c]jRbl|H(ĥ%@=h  bA5Eʀ0pZ;!1Wm -TH@*J.)I@%~E}t~Z ӂ }lEQ(ĥ%@=hFN GwXzV6^DMowuSuVΌfx]RKzO yK@# @3}gPwc]>>Ybw%#]͂,L[P^{TZ~K\m8-r Xͭq7֔nKܲc5pt t/\(ĥ%@=hFN GwgKV=ڵ~_jKwqLQ}1dsi"JRP y_Qi$_]/)sߖawq6l,FvZ]RKzO yK@# @(ĥ%TyKfpZ; "Zm@]Ypp})I@(  I9403@56P !7`$12%BG"#'d;*GAFynVºj(q?m m;r`l '@Qssk,NJ2yNJ*[mPlмr0 06`3 `JuJ]#1:VRֈZR%$,ɓ9u wF逮 Y.֢ **!i~ Ф kVJpW)jBb..V#$]kSßLlr|1yh]6^St9܇jDTZX \ٖ @Kiȗ+:! LW+0p>@X;D",y}.YUХlerGc .LVv%\s>i\dۋknMʙkL\ܥnv²"R̶(W+qI&IA~\UqbKNH(*5kK+T͕m;^c}Ďn}ᯩ3T-w,0M؋i]nWj;-thdam+gt.I~haޖ~ޮ@KnEܕ 6p |{U5żYFL}Ďn}VڝNx\[Z1n`\=ĮV#?UOܢAIڰ]8kIK<J%(4C\C܅MhC-4a. _SxnpL33m'UD:̛ K1Fr=,֚Q,P̹|ܨԥ9"ˋ+]>US t28vd<$Wnהb[tѦGzWtMqzFJ)*E;7GD8=SXj5G$۷+p^I['C{~QIKeO⌧7G}qm㑕02%/!R.*!Rk(L[PR;ët:W/x2qWE{Qߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7ōc~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7c~Xߖ7 y'UMf1jsf1jsf1jsf1jsf1jsf1js Nc593SNc593SNc593SNc593SNc593SNc593SNc593SNc593SNc593SNc593SNc593Snjsf1jsf1jsf1jsf1jsf1jsf1jsf1jsf1jsf1jsf1jsf1)y$s.[EϬiYW}e.WEϬiYW}e.WEϬiYW}e.WE 8Q䕜^٧e^ghPr$5Í  ۢgcnQ78 Tj)\Z0 xtӍu7[UjHB1ش߹ʏD9g S5Y-=Xoo=YvK|aR$cKzUkMݼ4Ⱥ?[! 튒8ӛͷ>eϔK殌nRr`f'TˢX9uSW`~mJR67VR֚lRHlEKF$[ 5Z 9V[װ:bJot|˅|3((M(e~@897['Fv->*lWCy)uW]pF޺%SeRՑ%Ҿ:>OTi_00"Sg\ZBVrQڣJG̸]^;N -pT682Rk\m}qf7J _(yt/iYWsq7=\ּi qvpy+ 3'd Q:ϒنy\5d@e&ismp/}cOʽ-p/}cOʽ-p/}cOʽ-+r!ʄfD#2!̈FdB3"ȄfD#2!̈FdB3"ȄfD#2!̈FdB3"1;E'[C\(lŊ@ {bRAW\.oot}Fb$ǣK|ut-.@[ &dKZ,ꪘ݁z~{HQ>Q%{{_IlR$P 깽\Mze$ƥ^vq1̎HSfE\Qs.WK/d^Oeot}_沘SH!ʋ92V[5R8j `ۈn ј^=?>%q#Lb&~ŇaIal\yTf3L밯_̸]_ mIdݦA 'BKK4Ҥ>Ņj)@E=^I2qUQ"ֵ ^#K!Sow_`wE)DQ)^z&Z;>*YPئtQ,lF(P9[ϯ_̸]_ kY C+ (1 hMZ$Fac"ILBO\>tu{[RKCUr(MKy&dXa$}2,~T(L͘Hַ/_otXwE9[C-ׯ\.,rҥm\/7.)5|LMN0Ų?K_upxy\;a*la2 8wGtQ2u| +S%lDE=Z{u&SqDhɲ-re"6o.CGzv|VS~RÖRt(BݏuŚr(%óL[MN$pa`IQ(d\(1S8cƃ_̸]_ i¡^0 |1 Sc 0cNR+FE4b]5 )Ÿ{ AXmZXG$oԊYA14)1lsĦ4[Y8I^kH+*gjͅ96T 1(\TA]1Rc$D9.GO&CX!D<3F_6rJ 9 m(NhHKw $o"K#GG}Ka2~)p*{Wy #rʽ2uyԚU~k{Rf]\ f"cMinaSe#*)اGl9rN$oїE M5%LZWÓ=Yj*˅|zDnG˅ezeGtQ2u{{{ú(Y^paz_̸]^=?W\.ootXwE+.W?;OG[ fD#2̨FeB3*PʄfT#2̨FeB3*PʄfT#2̨FeB3*P܈L)0p˜8S `L)0p˜8S `L)0p˜8S `L)0p˜8S `L)0p˜8S `L)0pWId]ep˜8S `L)0p˜8S `L)0p˜8S `L)0p˜8S `L)0p˜8S `L)0p˜8C%ZeGtQ2u{{{ú(Y^paz_̸]^=?2G'=Ss.6Kg1N>7#nezeGtQ+9w+ْ%$~0^93֣P͘6sDD$%n$Lݧjhg/d,4ʛMGG^paz~e>2`C/q73ѭmo)A)o#!*ޑ;\^ 2~4*׈pt@Ѝy+GG^paz~e!FX,.9b SgFRӥБ(=\8~H o\k=ezeGtQʋYV$KiRͯ_̸]_ܡ_䷺>"&DDZ}<0ò;O͖1:-|ęEXάQYNJRJ^(p(0ˈ{9dUəz)GilJάuf呌_(/%G*oAͯ_̸]_7rxq>3r|dkzc>Tjd>`SLn?*KPnb"nj=bx0F} *z{q xٝG嬦=<'`gpXW\._kQ8o_GԙsLao7JIDMseeDLWZ~6G1)5莬pϞaAGaz_̸]_WCwn&o{AїDi1LYM=[c[.1:j,Y"Lؐs3J#-p fEƣ >k}m%h ]-.(Ss%|owEK!FU|AN$*wί_̸]_>uSC <b74ȮItQt0*<*.%H14a-HA:ЕJ a.k)^\O(CT"ƺLZbyHc dURjUMM0_Ub\#jmkD&sRL|D߉e&fbڟ_ -2:rT؉V(oK<:2uy)ԚUs-yŧ?SSK ̤/.llW#u+| K]rԉZQ5m?JOeKSowEKm03DpSώۘD\Z2bX?\=euVĨm ?=W\.oot|R5[6 74ҳ߶s|%rq^SAXPK}3DU65-Me3:6t~™sMxTj3|&ޘ iև[nkE(QZ1M"d2 kΒGs!`bί_̸]^=?`T˅ QfRmzeGtQ >mb$l֦} M3bK$R8E5a^ ˅N>!Ș(uȢ([ZU:\b9NI(clG tXϟ^paz~q8;6sOF;ϨpJ\>{Tw=#K05KxX&y Gc1h*"gjBRPiC@[kRV2T0$Ql)XM?Yӧ))\˅NOᇖ(bk~AITv5 G˅ezcpZ2 dd# F@22 dd# F@22 dd# {-Tl* ¡l* ¡l* ¡l* ¡l* ¡l* ¡l* ¡l* ¡l* ¡l* ¡l* ¡bRӰl* ¡l* ¡l* ¡l* ¡l* ¡l* ¡l* ¡l* ¡l* ¡l* ¡l* ¡A: !1@R"03ABQ2PS #4a`$qC%DE?FT|!EO ֪Ka^ףCB [~ttw)~U-D_5QvUwXDAWS 枣rz ]Z'[n]└}TVAй]P.oNbܾS|jѱ9wbi{Ƶ%A;!IEng]>5n}# зC#Y7I3)1O~f7ise\t2")hɪ!ER "ʊF{VpF Bt')} /C ^]I+2U ȃژ~:nΥESrj13'rL?+"^$oYJ+خ]}%hBZ)bne0,ļҖmaJJ%]Q%#K9M:Nϧ;>~SNϧ;>~SNϧ;>~SNϧ;>~SNϧ;>~SNϧ;>~SNϧ;>~SNϧ;>~SNϧ;>~SNϧ;>~SNϧ;:/OCNؾ"DNϧ;>~SNϧ;>~SNϧ;>~SNϧ;>~SNϧ;>~SNϧ;>~SNϧ;>~SNϧ;>~SNϧ;>~SNϧ;>~SNϧ;>8[0xK*R`ĖOiS)A!KpҧRCǿy.X]#ZmGԪZdL1sas& 榩J)J!_:ԧtj*Xe%ק_\'?6G ;ҧRCh&e۝,<ďK(sw1ԍȪ#24,e0,yli {4xؗ>!oye-gX_ѡoST5^TJPyzڗU,E[55^񸳝Кy.TJPyz\'] .\r˗.\r˗.\q=йr˗.\r˗.\r˗.\r˗.\r˗.\r锩_RBr˗.\r˗.\r˗.\r˗.\r˗.\rˡy- .{#܂ 8O y}F'}1?;/p WŴ짍$#PK.lxRP_ f:=ۅvƊ"(A;Фp\qOrܑe]Tܢwop oi߂iiЮEZAtaKķ e[jnRmVUkwS­ӁA|xV:6^σE)EcpvqhܦhNTd2K+V:fff-:ʄF:>lIw~E"Uz>PNOSy]0:U¦jWV[z{ղ[ЎtU$]1"Ċ*舆V%šIJ*J%[JG~*N֘{QSkRuҡIԨ0$b8z|n1mQ6gRТmMlrQF'p(TNF=%nvlVn5;C]jd57M#nP_9ܙ%CҧnUUÒh*#wkHfFNTʒL>dt e]s} jW F46*]*qD_ɗ)%VhٕE;dV?Q%<9[kɹJ:tU+5faN($H/7zMeĔ994vbe"$c)hLAu>XVاl[^'~&zBͱ7::~Uq+HR#&*L%c] E2!^+YbRȟ!&?CKr EjFe!P\5Qޅ**$f֙(#fz=+iw_cTlqSFнzXm֩XniL^4C mܤIc1lι}GdVbi$aOj[ԛɧYZδD aOKԬlGɸWHQ԰$nSndA+Qki dB'\IJ,Ub7zuʾv" d U#V6[rL14{W1vi .u2GDh94"XDwAxubni+7WOYS"uڒfOU>#sEA7+TIu<48O>}^ 'b~wې_>#܂ 8O y}F'}1?;/ps3\fٛ3fo7fٛ3fo7fٛ3fo]\r˗.\r˗.\r˗.\r˗.\r˗.\r)r˗.\r˗.\r˗.\r˗.\r˗.\rzv㨿3~C7:ߐ3~C7:ߐ3~C7:ߐ3~C7:ߐ3~C7:ߐ3~C Ȝ57)bŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbźbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xb>1?;/pnA~Or 4CyEñd-swOr ᪐Qq٭csMF_-* ڋa>#܂~k6&=0%m+^39ntC.\d\m$$H&\WzdHʼncRA=Ť5S>%6SVOr ww@SR\QK~m5t+j]҉>G>JjI+#]vhԝF>Or (qwʧ"S"!G+V-ΡDRV.yQMQ tUFIk$S2uC} Dl vR dڞV1?;/j:s.5]]SS7-oqU[.Kq; >#mWRkK|4_\MDզ&oO"kQn) dmO"ѣ mO$R/u84ŦVgdһ+c&BhR8%6ي!3Ħ:pׄ Eݸh̭@ie7c bmQWs_J5D)i&l+5ʅUaMF{ʺEEln:=Fae*2.*:]uUR4s>-YuG$n$"xOu=Dpxvp"GF%%*7\e_ÙG'XtvE*ڎhJ՘W.&E39QJ6:zQm5r551UP=]Ó-^d1.|kEO9JuFRI/ΥTLK_yks%˹V"-%S-B-p]S>ؚV@QSNO"BY),,5Tg5~ Ɣ.ij#k2GQ^U_Y"UG#r΃$nT9,*)$UdR2\ʹRI."čdZ]ISfEZ/Bg1W^1)\ƦQE)jL1 AgīT$F]Nj֐YXTU/퍨ߺIPb$5.mYzȲwW. E8]T?n ^nTU_SD)'k_ y$̯*fd‰/}RޢB7Ѕ BJ*֥QF]j0XblgWƹCRZj~+OKP~"4Mmް=kM\jf[ʶA|U-r7nSDYN3 wUcKZ@[)d+_4jiL6.QJjS"m]WoVȃRzEF$ǍtOOS4'9&Q8m >iMXY}O#Wqe^tYzmeOnj)Xjw򦣫;UM7f/yMMR47xOe22SdnENee2'OtQ*ȈT,[Yn\flǶb`k鸎z3.\69DWj$;jS+df*b:&ȅ4 -Z;q⠾,JBjԍ jnD*o(k׽(+)z$ Er-LJT(XɥV ѻ-!EQ L XVg~\]e0rtKIl n9"S१<|isR־Tk66OaFh|{3;3\P\.jLn%uTD(V!ǧ5T#XVzzfq="b7Qz;S^HPeXaQWݨL?*_gO񣭑aq *(%W:_ukM+b4riMk%jʬvbiWfu{2ΰ;Ig[/qUQD7ԡeVMyM6nSR+eFHߛ)MSj4biKQrEnW_z{d^1?;DнзOkM CԵˣE.w; Hwrۚ ]]A.~/ QJJQhOig3A[O 37W̾z$/TLѕEEB,W}F'}b0K8nKgpc[اtYɠѕE]V!%v˼D7-SG1 Uq1qO 4{BfFYê*PƭSȮRY:,=4&jQ_myMU–!N E"bYIOr E}L{T:I:n+lҶ=uG17m#IxZTsW}F'}X2cMEpʹbLuk/]NOr 'b~wۓQ,;ucs~_:G19Qucs~_:G19Qucs~_:G19%Ywt]k!d7/2!1"0@23P A#BQ`$a4CR?MZ<}~ዳnK-Q<8QLO&!)!š~j!!?]D'[ rз/c:/I4GrV[5ob}0BW29)_bwV6J 2SȈ9Uf)@%QMWJcbO%I J(:4\E#M6ESd>47bU4 E[/tL7"|la]W){DbdR`Z,(a1e>F[fO1M HTT}D8Sd>4WBUer+KoJȇtL7"|2Imi3EHT Dj:{)QbVC^}7UY|2+PV[S~K'1<|r'KGSƢ^ ljH=Bʊvɒ1|k֗s5Qݲ/*Ƣbw*|Ɗѹ3EJȭ)?iDjYqHO(mTc*C%K1"+*%VRqVܾdT;oWGN!Mt))RmISi3I6;_JVXn繲6++;n_rt3I*O*6˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\ŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,XnJOYC5ٮvk]f5ٮvk]f5ٮvk]Ҹ)vk]f5ٮvk]f5ٮvk]f5ٮvk]f5ٮvk]f5ٮvPWlYPk]f5ٮvk]f5ٮvk]f5ٮvk]f5ٮvk]f5ٮvk]ԲܗvVf%Cccccccccccccccccccccccccccccccccccccccccccb1J|k&#x⼅k&#x⼅$tHعɳ2pRr~*TK8]FK\2c*ɘzW{<4J\rF,Tn,)R_8bKѴarU%9)24%J6!,1VBš?' *wmޣw/^vmcR(4 + 9c\1vdP7'ẒSR%LJYbwR&5h،lWKG+_1 =0>c rB*>ӫW.LG'뻇dJ?gx:e zq܊Sɧzp ^В>HrEH5ޣw/^9܄RD1 w \Ov; caVRȳPT*8ԲSNd7ޣw/^ޜKX.u \Ozޙ l!+2zW{>pRr~Io|"]V)rWhݜF5QTjUF5QTjUF5QTj6666666666666666666666666666666666666666666,XزWK3ssssssssssssssssssssrb|<}j֮+ȣ֡j⼊<}j֮+ȣ֡j⼊<}j֮+ȣ֡j⼊<}j֮+ȣ֡j⼊+wwQP_FBYޜwQPDFZJ(,vF{1;ř{AEUdd$qwq^E>-zXf،rDos*{mbت:iQA0=DynRwb=$>⼊<}juYn8f%WrrV[{R'hYo_-"忞ȹW!wwQP^ϮT\k !-?|jwQƭZ&#M^L _W@r(r뻊(LDRDldBa+![;F71wP 鈖VDPdnOt̥Hf$*E8ywq^E;oKCѓ<𿀻"Zc5z_]WGC)F㦈̒.+ȣ֡umb9EXܨīe8ޚ(Vd(禇J?.+ȣ֡%d:3"r*)Q "C4[9Rho.+ȣ֡zVbŲIWFD-yx? Âe \Q2+⼊<}j֮'ȣ֡Iqf3JLҦiS4T*f3JLҦiS4T*f3JLҦiS4}ޛ'It'It'It'It'ItP !14r"02@AQaqs3P#5BR $bCS`t?]LۘAXumZͲ [kKVE$􎒢gP%9@ܥJ6RzXuAZe'x*}N%~H*&yɇ8Ti:H(- )& \ꇹ3Frq<|UpKJ48/ ʥU:%CIi?V$o8Ku3nBO F-Y^[+X1:j#UN0G `e-TRgA?…ߠ7v_ARJ@' YRS& }_ pB"Sk4A8y!OqaJ&USNEANd=2f@X7偫RUJŠ0%ơ&6/qrBJqW}FMNbXuFp0rJ/FCaL|#m .`Kڡ<*h2܃xF9j^ GCl,)AX\Pq Y'?gH3.V1V)BP8 WaͧM$VHIr!VZ! B@#zڅRB8D]JZ {zhc\H˰NZUFtzyC;JjtKS#A. gh;>1x|K-wM$ZGϬU¬Z+7 (BPVm*ȥO >i,nӒ RPJ4\xVu085ΫKs>0>{Ъ~􂧓i'CoKZ2%C,LJ(Brq߄O,[+z$^S'ӽ?g}晁: {z$׼#hyZ@J[?nan1QU &i T})gС lV⦒mtJJej<P\#Iiҩ9ӷtx&bnahdޕJȘC+ZJgu_F[LH.V+T[PJ%~6>Q_ H,a:J!?7NGIQ3>sL)V-*W^863+ [P+[*.eYwJ;*IVl%XBSZr}WlCJ“+ŭZ @r^Y~8P Raj\6kyZa2qI!JNbio!qX 'xy_laCJV'z%y{=Ì&oH@u}PD RLS"!Jsy(y0.@gn;Xcz$tC~oe d$|<Ì+nŒ~#_ҥhMv>K&72#wZyML'\z!t;^SȑPyDQ ac< caI@zҟepᗗS&,ד$c?ƄxP/_}e@Z1XqM$&Y!NT*Z[qfmw eoO>6(k~ιP)-$W5CKMҕ|qO#7910V8E2.˸Bd Ba6¿$Pp/ApyF[:ZŰwՀgy JuUXFZp( ix4ŒrWq%.[$a#"kT-lI^cKjJb,)^?D Dθ''ղ|ՒTǑlZp@w֟L-b]%Y^~tI/Or鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcnۧ6鍺zcn`L.ڗkZ iN{4Fs٧3>QiOg=|9f({4Fs٧3>QiOg=|9f({4Fs٧3>QiOg=|9sjvt%*.3f({4Fs٧3>QiOg=|9f({4Fs٧3>QiOg=|9f({4Fs٧3>QiOg=|9f({4Fs٧3>QiOg=|9f({4Fs٧3>QiOg=|9f({4Fs٧3>Q,-!n*,a٠Gg=|9f({4Fs٧3>QiOg=|9f({4Fs٧3>QiOg=|9f({4Fs٧3>QiOg=|9f({4Fs٧3>QiOg=|9f({4Fs٧3>QiOg=|9f({4AraxŇT 86Y]'<7Dy?g=xF+M50^hZՊe&dlrbD%625Ĥ\kZ E*"w<<2e77kȈ$%?[R&SHaRo\WI ?ɸ_z^Qǚ(H NL"Ph蘱0ĄV'%ЅlS]+0qfZy3UTM $I٩IRf%֏7<3IiIt 954ke'{qz*.0mN8LZyX$moQ5ĥwfid[u{ѯBWRGLbf@^T?4QJkeׄW{`# >I \ 6L]5+1d5ADFX Ts hSfIBhRr\WI ?ɸ_'IeqnTA0#,i)(ozS(];C$#-bPhxE8O&Y4"(XJrZbUw69["|p=ѳ5zPpb 5ZjOO)5J!` XhS8VR[*P lT=J]xщvgU2n֨Ŭj"s tpa9n!|_@g\[X%ݰ1-pt2B丧SQK34 ԇ;З)!ցQIY>ٕet!|=S UG4 %? zjP5B&RF3{fTٳ$#o8KQ:߲b)XD.4ҔZ]RbkLy~R~ReL}@{c 7ʬR'~$-RCjߦt|!PÒwbP8˽5[J=z]p[o})iI+T)@qCxcSu4DT7. ŝDO5,h8"yٕetLJ;|e189*ᐘc)oXV28rbA'dn7o¦'>!99!!5ÔJNQjVuALpG6:iqI=ѳJyQ=賫K)fݙ#yFp a&~msv"G] qӈ+MĹE(Kh'HX,$Zq9K.^Ju7Ǡ;,IC5p&S8]QRc%0g7y?g=xF+l<W<{estO{6OGxDf=ѲD.cIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIcIa`I.p@hHo/Ԧ3y~1)_LfJc7SRo/Ԧ3y~1)_LfJc7SRo/Ԧ3y~1)_LfJc7SRo/Ԧ3y~1)_LfJc7SRo/Ԧ3y~1)_LfJc7SRo/Ԧ3y~1)bX`):C@F9YRՔLfJc7SRo/Ԧ3y~1)_LfJc7SRo/Ԧ3y~1)_LfJc7SRo/Ԧ3y~1)_LfJc7SRo/Ԧ3y~1)_LfJc7SRo/Ԧ3y~1)_LfJc7SRiBMM;,\fFvY]'<7BsFvY]'<7BsFvY]'<7BsFvY]'<7BsFvY]'<7BsFvY]'<7BsFvY]'<7BsFvY]'<7BsFvY]'<7BaKEMa.!AhPPDMҬdҰUmµ қFLmژKMro{?69P䄫zg$\X2۲<o5N$ |12ƦՓ[et tn,1,dMV :֫r1?G82:QSHd<#("~ܠ((H9}𙉜 asO6S.Ԣ~~V[u- 0p[0rO29Ms+xCh:TE m^9iT8j#TV6 0~m{ΧExxy#P)a,TqHJ}{F(L z M8NoGesӉk-YFb>qjjQSq=Ѹ{*"mk1='%6P"JFڋ/-d8w?, skoߔ"]К"G W+ qjAܴɗ8?MJDb5K$rSpl>lqp[MoBtH>BТ8옐݉ ]_a ;d$F #4ukB¬n' (1.\2eFu)O JAdb Ó]q˾bvql9n oeZohu 5(vŋ@d| f)E!&Qu%UMA'?>2V'2ڧ &2hcżI6Ǹ 첺Nxz2irε@yH! 1T=hԚ B RKS(J@^_ٚU!c6MvUH^ZܞpRe핊-亹)L3z5 blr?EjO TkʭRWIMwx/] wE.=S*ejC`!7::ţ]h"j}qKHEVnM]S;b:%&Ūfp8;[+p J<^ qVk*KAZF$%Ԛr߽HwTˋ2']TֻLH`W1.)dd˽e.Πa HՉ8]B2p+HoT;/(ŋ1 ^RH5.je*Q#(%|R[C3Vk}y<+feJK5i˜mK %X]|a8RUV5<J` -M q918R/-+.K>R9O4mڳJY4?%PVݽ"t*X*RʚP|0vEӮm_$4ce p1ˢ7MhYPҰ-Nfɱhlh&)eF)e?YyըQ [ڢY ʨoU Ż'x<R?6JSLDvoUK oGesp6 ż JZ@vy{6BxG:ʶ$8 Rqc>lYN2 M!זeUrn$5S&J]Qi yBQbeYh8 NKjy&0/e4&0tKY]ټH)¬%U:+(ɾ>0^zZ]7D2*pYT&}'^9VO@7/Lg{/ĖFX%ԧW}X*P&H.釥-WyK]B6T}̚ wmI%0rk5,4UwR(ɨt{YyI>)$xޡ0JU?dR.r$i59r1!̧X6N&ӤBYdkϿ&օ7Ta yaRO|^i˸et t~eJraU6KaN El+Zenan!(6,2B+m\bfT-H+V2bt8ԺPZ5Bvآ5/0x-r )s4EpIvML$?@a/%;.BAA)C"UY9K' D˜S˴3RE7y`<Vj]m!"a.;m9G5E?iVƿI1 frF 4-@!>hJ7\PXEe@10QqXX 9mY]ٵ Kڷ@ER731ڠlRpU$CCXYVulY'_&}5K\1f^g}`T+C?eAA68=WI ЮxFxb.kbm_~X/]AEV\f4IU)Znh=ގ+W<{ٮh=ގ+W<{ٮh=ގ+W<{ٮh=ގ+W<{ٮh=ގ+W<{ٮh=ގ+W<{ٮh=ގ+W<{ٮh=ގ+W<{٫ф{5t'-tS[̒̒̒̒̒̒̒̒̒̒̒̒̒̒̒̒̒̒̒̒̒̒̒S &Hc l/ޏ^£8Tg Q*3Fp£8Tg Q*3Fp£8Tg Q*3Fp£8Tg Q*3Fp£8Tg Q*3Fp£8T(nGQ*3Fp£8Tg Q*3Fp£8Tg Q*3Fp£8Tg Q*3Fp£8Tg Q*3Fp£8Tg Q*3GWwe;,\fkz;,\fkz;,\fkz;,\fX /kT) ̰c8)Ũ% *; L))!¬qlSM+"(~9=-:X/UZ.WI ЮxG\фl?~eI\CB0N 8Ɖ,d_쵻x6Jzec|@l֫u\)MIDqE $!!:S-=oonPHEм 6MG1.IiUE jfqj ,rgY #BVTةS.)/}G Nw9k0/1 ֬^lq{e' 'y\IwXBG7N8\_?6~Mb^O,O52SaIHq$9|aSs-%(%+ -&R&^i.K50#7,[j㨉}%Hq( bIdN|Ihxs5!Jp:*8U,ʜGѰ@Nw9k0/wȗ²IRjIHqJzuCJ9Eo}[J~)?(:г\u+ZkZ!5(u 6Ec0aՂKdmu}ԉD$< 73>ʞ";܇z0tyVhRTji= h-uFގ+W<{ٮh7i+7߸et t{5G[et tnie^[+uFW 9Fe1ҫuߒ@c9xo7.y*V]-Up˽8J7TE7=5bwq9ٙXD&JA#~1L$2 fMeh17 m$6y7$^O;fZY; IMP] p U6xoGest+=ѹbbu_Gy5x.I>TRBlTɱ[oģS M\B[⃪mV/K_e%i]$0E @mJVѩS,:<ew-Єzٺ%T6MqKxG.U*߾-Ifm@MЙvd|D Ĥ!ߐ0^^ѱw ~oXQY# ̰M,Tl첺Nx~ƯRR2ɹܘI+]u>Z|Lay}-W| 0a>1&ZH=F ۂI"يj[%fKZiQC@X/?AQHU_qs blDqFUm+ILʹiJ]sجR^i9+|MhVjr/M(+z'B%Ru17DIhxJ,c(ݮ]|;.~-;hTʐ*M[ٛet~mȶ3*tnObfRI5^3,6kA]Oϼ &tM*emLjd^`fG]*>πM#ffrAX&ENB`J իc p;4յIUп&XVXuW޿})d@±*\S`\qd{YLZfW U >Sak+ROfoGes?YC YXnJLZ(BAC?y0SZ6l s,ldL;" -[/bKv, }AL"^rE!kEaXqxD2]_uM]:#4p낶l=9a23 )2S$uJkxOjmY4E6- =NɾxH[[Ȧ9B `"aMڱ4v+=Ѻ&u S/INc[őG4a.A߸%:i 41<ȕo~O=ގ+'CǼ\ '&YđeƏpeթ먱7IJ(s ɐĿ0*(XsFtpZ,Cpge&8KKBj a9wfnaa--j"n[ -l\7P]v %^NDI)gH֫) U5;T˻X+Hxm:"Jm]NX.$_ƅ~ 2HyJKTD6bNkkXmC\1jzqD_W<{frU)-RHbdrBet4DjES6 *N|* r>0ƒ+0M|UUxٜ.N"xba"ӂbc(Tk,`ÿ _;z;,Z_+H6yĽEvEx\=_W<{f~P*N%jDׂbѴvAfκª}tL0$*QtaIY˦kDԴ㎡f|<|0gߟR qkxo]0[VZS~DNE|2(a4|RwovQ,*@a0y[55zFJW/ίS"E_Klh6g LZ`T+ -([a**IW *7}DLDYp$ +m+$]5x"QMx{O*El(Ӌp79k0\&۸`Mi5~#HJ RM\x<%)Hu \-ġck 3 O K]UjBK/!J Ybg?1"ҿ߭pQ UhD fyrSmR&p Mގ+W<{ٮh7d?^qhHJ&Д!9@!JQntI̶mLW$, 4b'` :,I!F&|5:6[ڮѻݒ&eaTuCKtj9|e XJR%:\I }+'|a-2Zm9Aet t{5Fep(:!F-E }@BJR(2et t{5G[et t{5G[AB\ $\E+zFnQTfzFnQTfzFnQTfzFnQTfzFnQTfzFnQTY hV؛{&=bc&=bc&=bc&=bc&=bc&=bc&=bc&=bc&=bc&=bc&=bc&=bc&=bc&=bc&=bc&=bc&=bc&=bc&=bc&=bc&=bc&(\O1111111111111111111111 ZN!-!1AQaq0@P` ᐀?!K/b W~E`C*]Rp6g-0f A4>\W.@DIm\r!LcbuwѬU}jX] ~4w Y58FAgJJNT7#ҖO$ حRcmp}rCݥ/]ѦieX-0EH3$,Ss@X'cw5 ҖȆD-}{]UQcF8uvlТtóKbcҤ!,aFL@5n=h3Й~6bs|֞鉌L?d@J21a3+PS>aK`D̳4N o'}2g@lfiQb AE8\RMҗZ (bUX'6mt `E(p[SW. ࣾѽM{reP[6}M>+k 5I,AދHEHXAImhC7Y;3Cd&Ԙ=m-De&Ɨ2!eYRq+O\<ćPU[D5x_tUg- @MiTD%k2Hɚ7܀ WڎP8;Qpܶ٩x}_TǸO#jq0 sè)̖j۱-.NH7(n GW!OyO>ag-$f,4\~}n=bX{U7> nNũ V6sNADR#r`btR=(P^550Qz{;_ J2^lqH6 ǽlR0.#&Ҷ0z?N\췾, x_Fe}#ZlI!։ XHD=bN NKt)Ð&|}`fnjKP79>mpwmlpƭCC98ҷޕ_:[Ȩebw"<8d m*/6Ԇ vq4@vf߮ ;5[ :[46"klvr>tvA?t] Tk{)n5jt\%yE,^GQH\_f᰻Cڒ"A ekSXI6!Z$i>,4$6{+saj'kWdHdwG5Nw6X`l¨-S-z{ Fi "BJ$af99$M'[\ְ`pf 4(.[StΔ$/9!oP&UnүXp-r{&waV{-D"$PPD ZDYH@j[vh 6RRpl&ߔ$>U~JKLl1KX)`4+б)!bQkH]Ft5W@٥)5u ~4& X'Scɒ g LAkJS(VJn%D%)DDD mxjOC@>F1'_5KThzEIkѣHx/w"l eQt%A8J^Џ_O; IJ?DI{!FYc=]NgH8%.&fx Q#ZC ĎD0BG9a/HÁi}o{%Ōz;T#+Ӏ%0iiiiii@Hyb!5kM4M4M4M4M4M4M4M4M4M4M4Յ$[,͉Friiiiiiiiiii+@2m?=o x?Ov6bL,빌L't^ mc_SXs>=ۯw)w1D8v\O{*(. /PKr(T" ,b R]F5T"2B` U2b ҤJb$?>{ |Qs*qW 1&ʴyJD.GBX1W^q\ !1#n{]"y(ğFRK˺yD >MQЧI0B f km4IjRŶ&{jYQ%p_ (H"6ڻjA$ٟQīAeCJ! oz50 &N>Ơ=LV!ރ8{c6B{dԐ{%UcmGë<iE\P-`6P],Pt歭7a M~!$m G| HBdh /uF9Xf؉o*J^^#+!qqo1@hMc-$xN3fbI ԞX5bC޷{׼;Q^~Gm{~o1NI6b>r9OS)|>r9OS)|>r9OS)C9qN(((((((((((e.#l][l~((((((((((*TLJ$cMk\7k;x&ox'$vMs\OH湿\95s[ƹ?#rkrGo5o$1ɮk5Ic\7ktvLy a M4Ql6hh؀湿d,d B3*mS1OX`H]~mS,LDTR`ً/}SRjqm#pstczF6%_Z"E (or1 b R4[2FfR_LM9V9Dܛo):ol?95sX o O*NaMC EP|f8M!ZA-pa RHCGv*,cRPt&0M[SjkVlōиf]5QTәFBӡ8'0"eCS Z}Kr@Ϥp()=m&Aa~y JiǫJ%@-F o/X #FI)pBJZq%-;wC"5V NPM0(Vx`;DT"`-"(T$)0'Ғ !Sm L>*dɒoA6͍F/'J%QN 0c8'whYܥU;NkH["ec=,[6و-PI >f`l !1me%d%)Dk%'zk'gw*AADV&/IH+AlZN߀܁EY̬lL5! Eݱ[ -}nj6P 2 $HK,rXrTR~™AB`a FڍZitPTU.I\\hKA[bX#Es$ 3},sgoqO%A%7RF;ARm a(;$E#v$]oTpN\'k%flX1ӍaKV!CԳOtfb3iC+AP$kA$t@ >j^2bZo`^EDҿ0D 1ɮkO 6J% 2#'Q ʰʵҝ?N ڑ5-IԌw*BD@>6Df( Y> Tؔڸ 1ha$@lq}:m4'[h6b,(/rkr(r k,hDp}Rd&;M6s5csaY_lPev/C}4 XWc9|bM߼*$d&JmԤ4̄#0tv A۾ #MU2ulf䢰q$t{t{Nrؤ /Bli: Jt߀/5 !5i WKʑ(fAtFO ͙dɚI~5$#U33Z]&&3I2vvm8'"&@0$ A ? ?M9I$5J"Q@ - dQ) B軦;0^@Qc;7onZzқesp這gpuY]SJ biM3-5*M´]]\=Q,RN{oҶI(̓;)r/gI+esN'B2,6I&޻ZGK0SH&a9z;(ΔԬ%jq$eWIƗe-_&Y+P+Al܂olbdR Ru pmCMёRPfE) ]eVeGģ%ݴ^slaYIln05 ,[H5> ffKhZ 2D_,ib&ءeF,{m>e THZE_}_rZe gbImn>5l4K20b#+R'F`Ѹ 76"b7V/*h/0k;8vT!\h [B*TZNvH ͰO&B1Ją&\@.&gM4f,1;P*Kd("$(cv>cpV͒nȱV OJdDZ(@ٗT%#.P֍a Ѻ@`!:Ny[W(v \6#0M4kdѺ4^CytED@$Ms] 95s} \c:w$\$)s{Gn, v'#lPE@T?rXդkh*P38)HWLň# 7QKidXk= [!gZ0H0}dW0"-H.yQ,ܔ[ 8I%ک4|0u> @&=q821J0xvUτ(zRy&RL$$DKWᕈlc4XHDjaX} :Dcnj HS0IJ ere F8K; AоSMX#$Z]gՎQXZ DBZd湿\DCm|71,|ֻR D$5[&-9l҆:}0VB]="b.$MjS @W~ -1o~@6m$}Н[% 1ɮk5Ic\7k;x&ox'$vMs\OH湿\95s[ƹ?#rkrGo5ocMk\7k} rI)J|>R)OS)J|>R)OS)J|>R)O"fcڻw/Z^ܽkzr]ֻw/Z^ܽkzr]ֻw/Z^ܽkzr]ֻw/Z^ܽkzr]ֻw/Z^ܽkzr]ֻw/Z^ؽi$Q*mӾAw}v/Z^ܽkzr]ֻw/Z^ܽkzr]ֻw/Z^ܽkzr]ֻw/Z^ܽkzr]ֻw/Z^ܽkzr]ֻw/Z^ܽkhBͲ$1ɮk5Ic\7k;x&ox'$vMs\߻ǂ UMCDi=)Zoda4Y8fԜ5h$k;x&o0{fp)4-e.:EK2+\FPCڋ;fAE\f!fVY:EN` $"DR@HgyOunE 2,E' )YNLdz|F"IA 4Okp=jH̥3\s7#OH湿w*>#BYK.̃{+vT&O7{*3N7&*7ʍJ+JD*'P$2 ֔JJ``u/ N ѵ\+BoquiyD5W b`mac(/ iqks}5Ic\7ݵ~m゘ Gpi0 Q7 )ZQ|Ewݵ`:&} DkZ>/ r.GHoZa2bfQt8d@ *&b2PR=/\+x'$vMs\‚vqaI1)/(Cy4H1rL}5Ic\7kv:@1BPkVWHp4kB m%vc7~5 bzRԩ*Ɍ:G r Q3%d*0XjPqNH\"lh V]O\ܣ,tK@oSz,ԋ1I.[T̆BbBB=ΔM܋$P N[0~5,$]EiUH0+aƭ2\7f`>-Jݹz$0!dBd!+R4A =5l5 t؉=9 l铣J `Մ[5 \VMѕ\ںEËȝW"h\GH蘙ݏmnMR7AUPjÂoXs V8|c\7-I-g6#Wlc> P剣0 )+2$/cFiI4P l# }hA2ziyX7S4sW+};4(v#I2dv"ˆ'ѹ9cT5'l)C uox' r3 \,;H]0kAb ޠeM4b湿{`feĎ"8fs}-|]fɶrPArDn2w-?7PGX3h `V|'c~hasQ ,YY`ShD lo)( wV WG2#YveJaV҃MIl\FQdXZoJ}Qh"&Nq' cYg/Z6b2 Q0Al); H!.,Ƈ۬.06Mb DA^KmVOb `وjH4>Kiء+e IdMB:C А@m"i4P|F$M텆6V>beFZ6_ykm}1ɮk.hsjak.L#6n4 x {OڸRAH̻h3tD[|\G@oP0S, %&ڄ>3- 4&JvA?S)[|Ij@ C:4X\ҘjAnd bوS0!=Bi٨ eufB)DAcZRʗ.gX.It#8p$d3LP@K%f`3p12 D#lSM*3I$\c7ͨh-+gf1v 95s~osq3R=0`FX #&nzFVz=ݕ&v@;ZB,E15!?leeH.fa2/PBaTzk3i wB>7 >F",.Pƀ+S h(7w*0fܾ:6%D}$#+5??9X]lRB%EEL+ll a=# O"ڠ z K+ LкѪI>]j& p4hc\7vw0LjNR-=F XUKpF6%Y1ƷbvwFƫf0@ T\k4v06j N`A@0LJ]`" Hc{4>8LWC y*Io4*RW6+$6X~7Sx mi$H S jVP vP%wv7I - \UKRkMs\߽<76&$鼞O~-1+B9L-)hqDK4|"1T"HEQ}!M=!7@C(־7bXֻCR 4 f戈EG%Ʒ4ܷBcڥT*R85Ic\7paAPlL6P"i|k;x&oV o (3܀ ɟ\95s~QB,KaӅ[Z5,>W6)eK'xؽ; f` W80UtERGZ0>Qn?ƹ?#rkߥbsۻJuvO/[^4@A 9l{Du`%ֱaѐJh-wm L`($if"֣'8]@Kbfma`]c%gioE/7#}$1ɮkvʅR2A>qLʔmpРU`Ӷ@'Ij I'}MIL U0de&/">$/$A;eT8} fe+C;񾤞t#7ƹ?#rka$HJP3|!C l ø p1\prk,o772,D$HRe.P,e E35Jc :Ɣ_F"Ġ> =\95s i4Z_G} DvORcZ?@e0~$1ɮk5Ic\7kdn Ѱk_k_k_k_k_k_>e\ eKm_,/Oj Kmmm[&/I/KmmmaeJD!Kmmm2Kmmm5Kmmm~t7Kmmm}QKmmm^ɂYf}_='C(v=F*j ѿT:f%S@dH%2}\5,M5 !+MlHqGiBӃ q SDZӤОj!In)NӛOoSDI?>>A-~ZC=b˘JXy:P?趗V=ZhoA`r2Bk -| D|͌\'OL}Bs͒~O?XrJd7cԟb˘T-*J16?+aK&=>fj5}B^j&>8IQuX΄sOoH1 4cK?I-{ )jI>ز1)S0iRb7ӽDQN"4bDȜ݌\'OL}B 6'LL%nEh,`LF5ȣf+d\c7?,gYz Wv1sY'} qSR7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#r7#sr)%٨ԍ܍܍܍܍܍܍܍܍܍܍܍܍܍܍܍܍܍܍܍܍zZ͆:5;;;;;;;;;;;1)ǹgBL?ݝݝݝݝݝݝݝݝݝݝݝݝݝݝݝݝݝݝݝݝݝWEcA]]]]]]]]]]]9&N{q=Ǹ{q=Ǹ{q=Ǹ{q=Ǹ{q=Ǹk{q=Ǹ{q=Ǹ{q=Ǹ{q=Ǹ{q=Ǹ{ss VVVVVVVVVVVVVVVVVVVVWi_ծ~t Xc:zk_1s=@/NyZ |'OP

nVe7?>p *Lf>n}H@Fqv`'Mί=p/X CΦB &XjLV-ҵCwT'=zab!W̏r+r"t^-i5 d6D\2McV&h3h1GyHXzl0U c@s1k)RY tX̬W=p hF)Qh}tB{~ጧv5V}hyGo_ᗢ*V5DtB ?fZ&)֎!=E:4iT/q[1kdȆ:F"Gat3D92шԚ,ủk A7P%JhҚgkfSAhW$ۃ< Z0aU0T!'OFС1?pC>"у8'PDM= 7?o&Ħ1`oT0ˁi#.Q]ta?X>VEOTLr֍0X j{5XLJ~7K2>1yhnG B^"(tSزXC\д*,)4},DC飒/DzngԓO$ce4Nl|'Nrǟe!ܒ=O{Ů);tJ/!݈܄'CwPLbNd&!ܭ >] hzji2CR{,êEsᗢ.D-ɵ@ձj4Knz>n=* yt*Cc&+dYH= p Ab|cjOA) : !##Wh;v1Qp-Rkr#WQQV"лITTdoS?ᗢ7,!FQqi%TKXNyKLsN¬4\2a[/ A!Òe7??\2aծ~t Xc:zk_1s=@/GP

kӾA,Xbŋ,Xbŋ/'?]_cxG4xG4xG4xG4xG4xN``8R)JR)JR

nVe7??\2'X6iHANiծs [OPI$Fx5^BF1ծs ':nl,.$4_XFYlc[l1C*u{t 3{Ѫ-]֫Ą|ɏAU/GiEO%@Q(u{t p)]J[] TKMpzkGaB:ZoZ4 7z&5zrNyZ1cAƏBt,n "가73JpSe66'^aKtdLhJ5ufw#Tts8 .{7?>Ga ] %E/Be!7ÿ˒ &#=.{7?ӊ}hKH<;!UVDքu/Be?!KQ`bsAeVtV5 ntISj'P*E2gQ5`3 ɗyVjk 8Z\h=T5oDe:'CC5 -+Tay *ҒD%T꺔JfP)ک(sXN^؛`#٬nƆXN+kD:|##yhcBEurӠFs"sVsR! Y5w5Znuz#AɧNc) CɊH 3]?T]C 5CYjҰbKژ4jD+av8F(5lF.Z8JǼ36G6g".Y2ӚtN lLuiG}#K~1d󨦼U:Eˆa1Д&/]g) еtr ƕ$&I {? Ձ" M"-mI#(ΐ[v>nFLakLOW瘲E5Цtw 7?ЌOD:{kZ)$y`xh1oR`f8NZ4SAHi,5| $$SKzcR)Cwf-]1c:~uf2ȿТ694*+:H%u /Eؚ{5:._uYc-p˜r&ș4j)ap##ʦ= .r6fLdMH3Ot6QijJXcGk$BF% 9e.q5 DDl~4jFy$OGA""c:zk\DEzhZ+ Gбs=@.qPn %;A Gh{7??\2u+qcDMRRE(" (q4HX(.t ņa;-?S/ۆ TĀ.\kQº=ծsɴ- UL3z'b55&KkњnVe7KOO@!ox⇊(x⇊(x⇊(x⇊(x⇊(x]La!B!B!B!B!B!B!B!B!B!B!Bsk$nl&l&l&l&l&l&l&l&l&l&l;!B!B!B!B!B!B!B!B!B!B!B'*!1Q0@AaPq `р?F >a%1Hݝ# D))!{KKZr2cag:Ohױ[ %ؖ?},ЧDɚ6"J=>A6ZӫT%~[ {:_z4y@sˊg~djaXG11\>͂C<|pe0$+PEIH8K S20Z&0 vtI = L4b\gXT%&n.G/PQQFltVaCRu"Qz5?lɢJ-X}X " j?`(V0 .t:3HuΤ[rO=j#R#W*EA"6:_uLViJR3/$t$ XY hMvhgR-QY0bA(֦j(-rA[2PS^q`AmHĉ! ƢuYs"2! F( 2#5#G1?h)5GMFKtCJPZcӆ[<-4(z`a h!-D3" @@!;bQʪ.FUUUUUUUUUU&2VR(((((A1EQEQEQEQEQEQEQEQEQEQCzCaEQEQEQEQEQEQEQEQEQEQE 1٪=xD _zk?ŞEZc#޺UOk[4GoAk.:5Jn*T5$ srW^k[4GoAk!Ǜvp˖\a5*؆롯(bHCcҰc@0Z1ؘ _8Rk[4GoAkzRf/HJƘbiw޺Fx5ȍLrpa4 SkTw/}Dz;"4s7$.isA}ƌ- sB\aRɣr,[pHCo/}Dz5C޶4zՌQUF7롯.]aI#ccS=,$YX0׵{#׏( zk>7biLz*t0!{]٢=xz _zk?<{P>#>#>#>#>#>$#>#>#>#>#>#>#>#>#>#>Ќ+[iG|G|G|G|G|G|G|G|G|G|GӨ>>g3|ϙ>g3|ϙ>g1ZDDNNNNNNNNNNNNNNNNNNNNNOB$ .5AAAAAT IҔ)JR)JR)JR)JR)JRc)JR)JR)JR)JR)JR׏wKf=-9]٢=xOWth^>-#׏wKf=-9]٢=xOWth^>-#׏1OCQׂ A*HK ,!xlcL?M2!Ip5DzQXdSIXZL~ OQ8,|:s$gQPG]٢= )Og{Ul}h&D!!C#8HZ{ W#$@A҃DFdܧBqV]٢=M5 r] O oCA2O~n0JKprm .Mrb(}MtɁQlsmek(s]ѳ-B(!Zp'  CB/S\Wth3|Vĸ1c<!"c fEXPGO~,YהF'y+[4G4b0-oC76l1m(bV0$82E{8Xob?C ͍5rH64x#.A>Ĕn1zVKS{ 2rC-th(dވ;Mb!c6$W F?etd. 5^9'|O>'|O>'P%AAAAAAAAAA@AAAAAAAAAA$ }Tz!:>w{[rDzH[ytDzbD.n=Fl}žoN*Z) 8(AK!@$^ɏIti]٢=xO}ł!4aH"OljZPęDvša͑mwKf=-$9HcU YFL=!`HB$ςy>mB8]٢=xO}AC^ŰN`^L6! H-.l}=fY|'8!^t]٢=xO~+"/TAUb?ƅ| @k ;[4G:&eEbsŊ_'Ds}[)CCZ4mzf >IXSDz`kiz""F/g7 Ȅɑ-LNLb'%AkqA]٢=uHƏCе2H8(OхH] Ga߳,//?p i[(F (t.eCQ9qZ{{[4G0,H8"Q$# p<0"T$]WL=OZ`S.my ex" .l-zgkk'!H4Bp4Y ig$X9w^Ʌ2j]٢=t[d:v6.i9&!PFlclb-HƌJV[tŬu{=JVwBZܑhd`ȶYk `yF'uwKf_$P^Ͽ'Yz=)no$!}h +cqs/Eem J6E1;#ϸKkt|SxcYl#ЅXz$LЈA$~]lG!D%׶)@T䶇,_&H{,$"+P䔍 O}-#׏m^  z6$a#$QtPKy)~4馶IDn]D$*tUth^>v2K˥cRBT' "St-#׏;t{0ǐDzI*}*)WDzЃ(z$16^)0fl}ſ{4 ؍gM!3"KFϾ]٢=xO~ Q X%9 KvډN-#׏4 k2/\"Px%-#׏wKbԡP=|O>'|O>'|O>'Qah     R)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR.!1Qa@A 0P`qp᐀?¹e>p`,O"߳A$2C,q7qw-@Imr]P0WXP̒U`P (YD"iXlN&xF_@>V/dt%>$^{U@4@̀@i9xjyLYàXH?Ԫ-7uKX H" 0#@c" "AB`&l@`}p8@ tGNX c@CiɡS0@.\oY2I`}K?SS,c x_FN`31 ə`@DQ0̑ )hj%dv}ѐo7@AK rƭ<8lUS14pOzG .4Pe& ݇_@)gyJ3(@01&l)P3d B >v$CHS0q@&TPrJ6"* h@O8vm$ RT`@˙ pOqax0iX 2d:&@TUc{B 0aF2F ,b?Zg_`P_)8bz>Ӥڧ <"tz30R<LjjhTp(9 \π^` iiiiiiiiiiiiiiiii馚iiiiiiiiii{Bq0l0l0l0l0l @, 6`كf 6`كf 6`كf 6`كf 6`كf 6`كf 6`كf 6`كf 6`كf 6`كf 6`@@0l0l0l0l0l0l0l0l0l0l0l P 㣸P(J%DQ(J%DQ(J%UPJ%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J$ (J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(JtxBDž,ׁ}ۥĔr<)fᤚO/^$:1&dXZ"N~@ eD[C K28#d=_$FfWfQS 4}"%Z dLw+J9 -gՂm%K M :`jO`O4".Xr4` l9sE#uR[FM (^#L/$~n M >lp>-fjt)\b ޠ0N7*R MNv0rQ1x@+J9 Aq׃ @=P"X0X̳fL@2`K⥄ ;p K1 5G'{{8lG R {T @ƥ ] lnG a2X@+˙A/ȂP{ nJNh0ɯOnwٺ^IG!ch`.b"KRhlߕؓYYa=\PY9;%>&E !X{` R솚 X9 K 0%p%͟4 4xya08-? ?dK@_!" }K{"!Ro@x y]nQX%-`` @P/D0JB,rC+tK[1|Y9;4Vϐ@{vl, nBSW T1G0,Ѐ.cH]"n &.W}Ĕr8R 2Ÿ#fLCZ m ų޼7K׉(,xRxGu txBDž,׃nk}v"D$H"D$H"D$!E8 5}}}}}}}}}}LM5W!Q$I$I$I$I$I"Y? SIHmG<&$oKC7v'j8 Y @#w؉r!Ʉ/W04qzа98WFdžwv  XPG^EG H&@E \L1)ơu!HT *P@p@`>U0 D7K֌8@HaA9CD ޾}S!0\qL `!€ʭ@8ZVVj|dٗ@J"-:NDdQ0"h̙Pk@pL`ې{LtKօA`|{Ϫ9}m 54zh{ƈNLL↧k gVՇh2@&%ZXhڧ -F@H|gi"LQM 9|L QS:y4B>/5vɵ/ ,j(6cRU<EAV4e % @w]0p[}@YuPi5+-@&z^1`="M0D0J^$[ŒQ{Ip,6%Eerd#] S@@I9 ]d< X)/Cz> iL!kz]P!7'0ʗ0{b >@ * %Ǫ c @Z#Ak>@7L3+@Tm@ cA8&)ABƑ]Mx@HYbb]=/^@_cP>y~ A'mB $g|ᢄ@A0!ױFrB4$k H{LK9`&&E%T(&c 6p<_y"H}'@d_00ܳא(ݠFsIP@dYWJSBtdf"(7c6}z{.Sr@`"hq|j] xMA@@xGW*{HPH '8m_X*|z(>$H X 3@"*@߄`ɷ> p`.b - =GăxD(@V x0BRzp  |HU jt@ p" <` 8|k@B/wL(b4e*֨0Lb9-v ރ{n H rǃ@ `iN=/_*;djL"4Hky(E}`Ri҃ 850`iǥ'ldbq2V/ɶsJ @ tQD 0\n[!6T ;` [N 0 zȀ=/^d)2+Aӏ9rRΊ_MX*A  "<Y f:;a@$@ F:X@ >g,aJc6G"V1QH:P&?ds €ȇͿ7aGd#2a1zԥ'Q/A JFQ$  Jipq8kA *\8@]qzQ^B`lZ'P Jz(7 @{ &y*mL %66I+Gm20YTK#5EfX*MAw%0Xr4\ 6x44 Y& tD`C0\5zhVMK-A %z}#`gJscIt@b_F`*hOh@:lP@`&@4P_==/^v^kW V z&ϯC,3gPIb^tHoa Nݲ >vƙyl'(@Q.Z ^P=x@@\ ^Wg&vҐP+@.pp#شT &Z@1@7;` I- +F X(Ha|pbZp.%G;`x(@4m2(.ݑT^ a +2 j"/+ɲfKHPfg`ZDL) A~A/;8w;n peXȄ z:%C>@9 d 4 [d0>c?rz5@ "qd j&!c@ ۍ wl؂{1\xMРPA jP=/_6 Pӑo=/_+;dئj U,A /@> 4P@( e@HQ@MЮ;}9 PJaC  r^ $D}a#y xlD#@EN@A@a!wB@/Z6@=/_+;d<ʩX ?\ M .iÂ= ``e0z^Xvɲ"G``&i aDtTqz^mǥ6Ⱌ`߿~߿~߿PJ*TRJ*TRJ*TRJ*TRJ*TRJ3 *TRJ*TRJ*TRJ*TRJ*TRJ*TPH     #././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/essays/invocation.jpg0000664000175000017500000022753600000000000022766 0ustar00zuulzuul00000000000000JFIFHHExifMM*>F(iNHH02100100http://ns.adobe.com/xap/1.0/ 72 72 Inch Exif Version 2.1 FlashPix Version 1.0 Internal error (unknown value 65535) 1024 768 C     C    N$*2nWP3R?_ =F{/Yd1S`:7ٯ-]sz^ߞs;UJ/=-?DAg]rgBڽ;KmP y_i$=s :> ޺^ShϒKzO $Ag]rH@&t-.}@tџ%@Cf>y+dz'.0HG؈I Jcq.9B};g[nnf"$IơI1r0$egBڽmp]^ Iɖa1$2y ޺^ShϒKzO !۲>&eZqXwimkUhړ\>;}|dh;lKP:gMq ^V~NUUN ;vk.:k#"}ڍ\v;_vn;aUH΅ϵ{(Cҽ_#/KtwWw2OdTתزYΌ[cV/:1bk׸w3޿{"Hݔz<|eKy=س5gTalmٱcmGOVw8kk:}|yni_}ZSM.ε>}ըQ6== abFύ} kQߌrq3mqs^ We]gk-DjufҫaƽgZ; ]%}[z{c݌Ow3޿{"HݔCeuz{ ׽mscqO*z]ls|<Ag]r]6mCt|5;szW Y=5~pG2ߺ>cߥU]m<΅ϵ{('ҽ_!iwFųnLD֩݅[OMuzwshzsFW \'zyM>J/=-?D8Oj>kU{->g@]GqſbT,jv?@=s 1"),IF)"y΅ϵ{(%eQ0-c S$#$btџ%@q.9BpH&t-.}@tџ%@q.9B΅ϵ{(w3޿{"H46{(@&t-.}@tџ%@q.9Bq3mqs^p6(ȴ sv kjP]/)g@%~EoC kj@D]/)g@% qS7s)0u DٌH";XYc/z= },5妩xg>[4{4d'PH$H%Ja(J70#ǥҌ ӷl>vbiۼsjGbG>~'ڕ⳶J'q^&<{%z{X"@vĥrafgwj+,YM>51xjlN lpd'P@$H%Ja(J{ ΞWv'܈}%nN&vg3]=em~c8KN_ַ]g,XmR+ vĥr_ruw۟髵fvQi[v.<HuZ!vӱŮc}-!!&92峬QyĦJ.ȔP2&'$J DI!95[啠vĥrAeGSBA&xcOk/#3I׻˩?U0-D}䅕gN{;]I:Jf(S @%dJW(!b鬩]1 bRHmej0@2ŋ6vN'{|,S٪WcF[ru3~R+yI5]ϕ6y`J/8P E<{6ކ}2;|eujaYg̈.Y1g8tnӪL%])\u8#}6gw,;kl_kjy"J &z:- y õpvbR v1lճ}ϗosRDv~7$յw| ORsa$K| e`$$@$I(S @%dJW( (8}8N+Fau@.ؔBc煵N> ]Z;S9?:9%,͕YHuO]nMӑL%{wS/4څMMӛ,3"Vrù47m?|u/aC\nh۴N$]3=E猦J.ȔP$dH$E@LdaA{G& Bd DHuLuwXu_ƻ5yӳɆrSl©\k5u|e5{?4ۺY Uui۱[ 7o7pbL%])\%+$K2vSj܏[ɱY@#3I':~PWll;<\WqN\3E«nJKcBmgz}oHm=Sf۳ëٕ_Wo*;c Sה -N1yĦJ.ȔPE@4jw{kЛrB0N'Uc4O?v&|}D6i'WՋ'~c.enXf_po~F"/8P EbRNؘ F;X׫a $fi:IIB 5$ EJ("R@lJW!Qѥ6t=^sWKgώ@HuD^q)%+vĥr%ާ<2FfJ/8P EbR&@F$d'P^q)%+vĥr34@QyĦJ.ȔPE@Hu EJ("R@lJW!#3I%Ja(J])\d'P^q)%+vĥr34@QyĦJ.ȔPE@Hu EJ("R@lJW!#3I%Ja(J])\d'P^q)%+vĥr34@QyĦJ.ȔPE@Hu EJ("R@lJW!#3I%Ja(J"J'X"L%Nq/|ϠS @430P456 @!$17`#%2ʣo(T?\VK9]}~2;It˾9peUlzFLCGߦڤ_.eU[:Et&e/ee0Ȼ"?ma676t$4k&pRv"jZu}n2bw~ j[Ithe{MLR˲ "<"޵TQ,-5YU S'T"M7CS˝!$;h,!ez9ߟv U  Ἑf;$E.4${$@&!FGf?R&`)KAWZ~ɠdrh`~7WJtSIbee3 ͅBX\t$ľ˗*0ⱬbm)DV-|͋6t,zI?Kདྷfb: @ET[|t9S40BG G=&j#dJl+qai v][߆e/nZُ${U߂v:|da~?IAeɜj ;MM NG ~ɡ??)SU&,8 lsL%>( rdKrr!k-/{e,*x! 5nB˃Cdr4O$^ɘ x̭@85r :Yf Y64'U;'?X^LH$C zXxjDTh G=hr˲6\^R0np eN/lzɴ$ū˗W[/W~7o/ֳ/݌^5/~3zvalM{b.]pM7 )c RXk#L5µӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭd]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭt]:Nӭtlȫnu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[ntcQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DuNQ:DPinu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[nu'[BE`xXߵxi\}ju{c^r3 ƽMf/{WG._  7_ \5^o/}s0{Hق|!Z-Y'uw;Ff .[oh[eemãʳot77^bf/i{0ӧQY{$"h(#(, 30^\{UUZ8JeT6UB>"ɸnUQj=^kم>ʋK݀u!A@e]}BbEmfz; k.'XG'nEdAVqR"RT8*٪VePcXfq* 5Ye )ػrMtA?pbUk.7Z3q"tBM7:MظazIܲd!hr3 f4gf05pǧ" f#1'dj'cz [kDr/ v`>jᕏFy+ 8$ 9| &d6 F~mxbtkܡvaե0A9"2/.zxxbjˑ6$ [r(RlCvpٔa%TVu 0iܤB/J%Fd H,$T# &btkܡjaӅN -Pu,&-lcp41s=(Wg/}s0{M=Vi'rlfLbG.]f2277IDlBܱwj t yu?n5_$Q)ZӬÑQ -#Qϫ@9 3pM$d/!p)T+e#" )-4T˚ò+20Z~ac!_|h@R%@J®+H^/R\ sWfef/i54[V͵豫0ç ?R(|2@L^2"N{7Ga;qjڵmF'EY8\X3c?TŸrpOwٚ<]̛a%#fi&Zf#_"gct[t^6+"&=CnO~@vdc,K:Ư㡥qL1(js0EFM)Pk/}s0|,kڻcҾdfGf/{Wz0u{c^r3 ƽMf/{WG._  7_ \5^o/}rf)%:+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJAXmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[XmbV)[Xmbu( RJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kRJ+kNLq޶uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊t;mWE:NSE:NSE:NSE:NSE:NSE:NSE:NSE:NSE:NSE:NmhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uhZ)֊uh'Xۅ9+o Ç9+o Ç9+o Ç9+o Ç9+o Ç9+o Ç9+o Ç9+o Ç9+o Ç9+o Ç9+o Ç9+o Ç9+o Ç9+n̨YF6fcIvyJ,wuaoƜ7g2=N~H 20mDd1QDQlJbdQǑ&( 7{#I2DBwlۼ.TuO\$٩wYXp[q7w̏i'ѸUb1QİʼnhF_FsS$ FjQyqRf ZS?(P]\YޏesxW|ݙ5 _<\9DI6U)0O `d4*JfL\/RN8i=-2E@a%a5/x"HO8te/Ɯ7a$"s\ 1BfliOA(0dܥ(iWXGmݿs~0co Ç,4Nmh+6\ K[ hᭈ:x,:3|(v_if-_,Y I~[73 P1d0u1 zrp&=_v3nژI*i =t$x :cV=߲=(u$;,EI~LEsj\bɩfR;9l߇ ^DncynS>eľcK-ctbIvD1~Ƒ$4_I,r&لhb"x˅&Jͩ# +c߿i]vNjv CYE]i8ۗ#$M&J32I:=¤zL(Իp[q7$]3dLt ,^ĒZӕP"_10 }(ys)h8W/2 ès#f)tT4}Cb^׼}q='(ɥ~|ݵxӚep6d14J&a#ˏj|a$&Op2Vcn6lyȆk$T^eջ3J\=1_f/U!0}(2%#T@]}S="؏f<~|ݻ굴:e"V` 1='\ kdR:LYOH&I["I6SÇ6 Dw'/4:[X!鶢Z,wߗ nf<Y91􄎴H̷tAYecQ"y)ǞzhTes (XxQ2i?iH$(,LD]%PM,G ӛ&.eِ[_uwhmf[,q J2e{owj\Id>;?q z? Y]ڻ7NnH!kơXXjc}vazڠwwb1 G^5ھx4ZKN=;M-pa㕠qϳ; {Wmx!tsHxG e#_i*z e*)hQڐ}qZozq7vUIcxD%Bﮮw4:JMǯ|/3oڣ  q7ws!c'nT|Ff $M11%f8 Z!c-yb[:S уf1 :8inۂ7wJ'j &  Qm_J* Md]v#ZxjM(Ջv6V1ᘨD\$vg4bw 5dQl˦PK/Z;&j6wp)f\U`DsxW|K=M 9d(D(,}-p?HsxW|+pܾͨhaaoƜ7aoƜ7aoƜ7aoƜ7aoƜ7aoƜ7aoƜ7aoƜ7aoƜ7aoƜ7aoƜ7aoƜ7aoƜ7aot:UWCu]t:UWCu]t:UWCu]t:UWCu]t:UU_Cu]t:UWCu]t:UWCu]t:UWCu]t:UWCu]t:Tw aWCu]t:UWCu]t:UWCu]t:UWCu]t:UWCu]o4!01PR"23A #BQ4@a`$qD?޿ o^2FO [a-W5`Z+.Ws\AՁ7t[6++j#Vj ^tBgjiƌ.B∷B)rBkdg1dELSs\qs_,s6B9,J'0]N:םڧ0_Vjˆb{ͥ%Qge¹L"X~d-QfxCH;ҩbꢌL158avң=28bM@r'I 62*v˯u}?Ha%|*@˂^&qTbi.X*3Q4v')%3iGM3 #Vj‹Uj8mU[2l_l5cc[Nl#[5￸[Fs l9F$< g-ؿkg42,KhK-  d5 |8\kIzUEkE1([ )@)Q0GmF7YX(%|/Wtʈb7U ӵV N+AWzEv*;AYSɺxr{? U2o.[$ڭ> RTf+kTG; A+UPЩL)khMwzC5W\PjPx  `bUt*"ԱnT T} 'e=1(›G6Jj=>-uܪ &Q_AYX$<S\%eЪj,UT{*jSzmî'߹ahcNQ)]6ɯ-* X,Vh~o[uҳ,TD{ҷT7i,嘵UTu ~<)kN6.JIKΫTբ&YUI}ײ0;.Q AkdM CEVjP #(ꆿEZ+Xetu(kr{:t6u8Y}?jV_Oڲ~՗e/Y}?jV_Oڲ~՗e/Y}?jV_Oڲ~՗e/Y}?jV_Oڲ~՗e/Y}?jV_Oڲ~SKe`… 򬾟e/Y}?jV_Oڲ~՗e/Y}?jV_Oڲ~՗e/Y}?jV_Oڲ~՗e/Y}?jV_Oڲ~՗e/Y}?ju gP#5jV_Oڲ~՗e/Y}?jV_Oڲ~՗e/Y}?jV_Oڲ~՗e/Y}?jV_Oڲ~՗e/Y}?jV_Oڲ~՗8!/FjZVUjZVUjZVUjZVUjZU~ƯZVUjZVUjZVUjZVUjZVU!ųbjZVUjZVUjZVUjZVUjZZ]j^5=3Ѷ?FCۢVF^d}׍n)[3=iz]j^4=+lLmvOѫx=3Ѷ?FCۢVF^d|"8[t6 0P@MEڮRJ'QL&rGD5^//׍on(m9ufSeD uL h Eut,W|5 ʮJ:9+0+ff_Rgx>UQ^0lZurttB!\sYrWb~.s ٭knP51+-v/ Ql.SB ,ix[KχuWY~V\~( h{}7Z+\(9l\|9NFrVD+ sN[>yJٞW\.+{uЧrM:-/sW\[KϣWŲ+fzgm/_>_Ƈw鞍~.5Rgz6'h{tWyJٞKϣW]+fzgm/_>_ƇEw鞍~.Ϟ(9 >eAܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar U5PFHWY0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,>%CS Ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw,Aܳ;ar Y0fw! )px VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVGRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY[XGPaPPaPPaPPaPPaPPaP`~:G84⪩%1GGLi` Cz)CO5vUy 3m!iR4OrѼɀi%0KSCvcQS[u22)wFADF)襈o99PaPQsT:.t:*[| ǼA}`jsSd<]u$7o^nn6K$xowN[{9PaPм0MuP IR7S$5 b v꤂mn#``$$"(bp_P TrD}Bc.TOlnr6ׂP:K4qU [_5 UW˴FNF+KAnG]PXx%-SdtT!M ~E1mҢѴ _U 6%O l#QV#^/ukh ~6/GEZO.|rB ȅ)o@4IUඃl E4RG`FuTq:ܪ3CYCVbIW 1BS!t,_nXLrتBgӇ7Uީ,e;sS8qYKbS`M5N&8`wJ[0+©j9&eDMaekh2Jh2T[>=sx|'?M,:>jkw ($-rMZoQLn3eVwKJ;US7%KL/'5;062)}>rN4wUSON֗"ƖQ|GLL]ʬj<5-&;TBHZ)6vvTSh)"P҇ǽm54T%iE8g%߆PaQv(Uk+Ud?4+V.ܪw[-s쟴q(Vx+-~.^ U+̶",epŔťi. jƕHmv xf\rPƶn"v&YI YKBQ_ fhx&96T ɛ Eq۴@p V-Z+c?LJK)jIkΉsrmB;MFXS]Tj+d)e/ҦWYz SU%F _'Wu χUu?3QTZHՓN> NimB6 [7Js1reT I> TY.fbLR-Cҙ+QD*6CmU1R!~unPWy.^"_XWZ7UpuV~gZur+ed4\ ][ 5 U$ʑI Ps^j,6@^ZNvM}4'5bZbZφPSy( moDH4Wch{P)Q6 aGvBd6xPțuLpn7U jDL *wL-eG_#1/kr&[kx-ph7^j :FBnAQ7r| bRB@..U[pNgoJpBW}LJ?x/f肫ip mAmFˌPEU;6 QT!@Pjr+46񦉧R2cm ] ~SMv$yzxƱS־x۪X]aݨ0rCh[\ y\#ŧҘJ*m̶g%dmM <**f'4RTUPG|tl%6m&XJ(|ʲ(È#NNT .{(rT dc.մTf9S|Z&HvNQ72u6RTFK( (}!m6ۢxG8{wr-,X{()?e_&M=#5*LdSiPhASld5Ri2UP$.!9pK_덅¥az(GوmNkybW+  o JH,W>)Ce5K暨*a 9Lz$ʆs%|2˼NU<"1a|:XAnArLn4A McI kSFcqj{ \bkfG8hTQ몛9!I wT).\xJsLg >׷5HhnH1gm,خ=l)X]AJ$c1it)'sqaXMmP㚶#ŽWĂ$r4G\q ?\% ![_rEsCEW#P\ a}A~גb[>L1H<('4mIeP,䭜5{hLonhUE[!kUkojls &pw*1L{cmCƶ>jF:UOU$ A튩T}n j2Irϛ]R5[RD5z)C.v zo ~t& 96Y}-vZ(|5k`ĶxEJ$s>eHwNjz}ĪأUQ|l1~^*4SB$~ѤQUjFc5]0d~e6FEIT*ߢPaTy3_)+U0h^6Ҵ)[_&%UO+ێ?GD_ -̓?ΡW2g&Db-<ӱr'Ry=5:?C'j@#zt:;:wA'?T+}8n;sSB [Nm)c_ƂȅpHLߑQ 84ᜟ#MjD"4wBFƃBZqO?Ģt8u˨Je(KlQ":e FX%DM uQ"(]GCoX'^_J J/,,,,,,,,,,,,,,,,,,,,,,,,,,,(((((((((((((((((((((((((((( ?zgzgzgzgzgzgzgzgzgփ[3S=L3S=L3S=L3S=L3S=L3S=L3S=L3S=L3S=LuYzgzgzgzgzgzgzgzgzgTݝtЊ444444444444444444444444444444444444 D"|4=[ ? ވO<4=7x iVB~xh{O·O M+C~xhzn^SCwA: 2Z/ L!70zeY"i[+>$jyberZQ)!V`&.wʌ^B~m,G tX"J#PӖ.TRPⶐNHcR)(*j{UH#e~ Qmm~q*LNB9vVWBjJdTNG"\?QXn&J"b2W,+]=-SeH{F&%+(lj e:#Tj$*SKɵM+iFu' }, aBi[.339 ]n;y&~â5IsL1lKLB8}u-)$5~mN!h8{Dт9oވO6"ZuɁ*VNL*gr10 öOJ5*0LlITQiB:K%L&~'^B~sRPե2|dس7Qz J[t$jˈMzn[W:tA5A5AJ݇ZW*לJt(tQYCwCCu~=mSg\(7TY\DE :mCwoD'W+z!?T4=[ ? ވO<4=7x iVB~h{O·O MYHȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐȐdjejdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdHdH2*Rh 7 oYn-Ÿ[qn-Ÿ[qn-Ÿ[qn-Ÿ[qn-Ÿ R-Ÿ[qn-Ÿ[qn-Ÿ[qn-Ÿ[qn-Ÿ)n-Ÿ[qn-Ÿ[qn-Ÿ[qn-Ÿ[qn-Ÿ7ûɯowMɺ7W7û&fwxd_  u|3|;2nowMɺ7W7kE &fL _dܾr; ᛵ>~?꺐-u-{zY E,j݄kC_:O} v'Q?sGwm;&fq״cp{U ~nRm >?lGL:SONɺRwiȿ7CV "1MTQRlJWF!:3n"vT>6$&Dnns,4:t?#Muv}:6l֣^9$-&A)9b- (&k듗w FدâXv!%"&UA.rԆJ`گ9NDAGyTn*\H1r']IcĂ'SA.%*)N̴wu}R~&Ֆ)HKSw%Z#D]Hi8 uB62Hq) Nj5*ΏQ{7rN - W4HĂ9[zf%rhFZSH}nź U$j* D/¼k0{]gQ>5fLEXypI/J)0 e"?Q5Ī9#gOSw$R.TZ'ZT$z#웰> \XʘŪ;q7W"GcTEQL!'%fLeB% fFfDhPˏp&%qccT2kp꤬Um Jm:Ƭ$Q uOzǩ|K*M}2}]^WڋQ|=r1^ħ.jmjQSy?#~z:اs\"FW:ыdn1ZA\],bnBTv/|b/iE-Jvڊ~۫q?&*$ Ja}K܄)8waUg$Z5ouq6!-]/l],z}r Qȱtq5\dcE1cQQm)p"f^.ЉH#pĖ,vm&37[AcaZ"f1},DI/۩ݹ:r;'wتH;+сheA>u0lKv>uwXBnJOTZ?[Aw['B$ӔĘH3U'](&JK8vhOG]]%mbs Jn"W)Tҹ+lB%LBp9hU\L _LX j* zSz ȍɀNbNm:^1/G=D_hPClu䛫+_B]6zwN,L숙j GEdKr)Y"jN:FMoQOz|XBj9q?;R6b3jFPI`6bu|3eYW;SkBJTAujîTR5t$J#Б.Oa )Hl\'&b$u {t"f:;mAE'Ղt曫;bC5=jQslTL?&bSL45(:ڈBI&pb7c1`DpЅ,F M 5(KI #jALD8t(?ߗ\D_ Neԕti}ƴVI>?7W7$KT$xd_ ģ;&fwxd_  u|3|;2nowMɺ7W7û&fwxd_  u|3|;߇VS !124r"03APQaqs#@BR b$CS`5c%?TiJب a)qa$fYiÉ X=9?kMz}3a M~'"MR!X``ćAiZpcJewBθgS^䨍tr!v%5(J:֣@ e*XEPx z,=6j*XXju8+y jS![ʈ5VAz{R`*xQ!W{121X+< _m8pkS`_P%Xdyͻ{fL3щ#3. p* <[qAIfBV{Gr})HeEG#5dEbN#  V+8|!;F/ ҇4/7.P:# MzP`ޗMbJ8Qh',׈x!WAi%('Ф-!h8 T* =.RPH%tOX0O6챴i&>??)$<|VI'̾-Z= ЩyU'R{D-yңq/1"7(rVTT{M=V@T_V$h?YHyM"Sc{E?8a:R9ۊ 8Б GW1 qAXjڂT<0ɱʊ(W@BDL ' jRN}%J6R0z M5[!Iu~Lq|L5Rj$<"1%~SHyb|(Pߔ}"KSuaMϔD|~)1*hbCOo>QC)D|&=\ܡBZk/ѯ qo>ҨBDL S" Js(i0/Jq 3Mg`IlXr]T|aym|`>Y?h1/Klfyʜe*`4J0hVz0Rq+lR&'.[N>㍡(@5$D*ʰD՛Aa0S6Da%l^dO$<|.Ik]A0ZZKҊ5ғ" *B0V "%"wD|%?{>SOVbU@U%v\J_]a-k JRZbI92ˌ% pC2)*qF,$C _Go h:\>gT~# OA i=eu2VWIϧS]'G̮W~Q9kUu;^H9Y]'>Mvʮk2^qG++өדUy#WS+?(etrmR]y>FitN aK+pAnZ]Y!R(Î߱ݯ'Aĥ>uj@E rU8,MK3mzpr_]R0Y˳5䏙\AǝCN,9Y]'>c>xFL6ΩE!fjwC7M..zmJ%%Vi۔C]e4bÀBmNV0 Цf[-:1›eO-"'BuIO|[L{ͩ*hP9+*[O)N4^OW1>1sjFL6ΩE!f;ӺLtv&ͷM`t%J8[ Ɩ۵Efedb`7"|bJe±q@[qd^ <\>[N&ˈ%*@q'0Q5M-\{辦E!ĖIB %S+P",B}} \*Q$]^X]$|?KK"ۊwa&2о8:WS_)[u8`9-&8 [VRd.MUehʎ*>ȹcb2ʙsE[Iw Hef&=ދlȼRҾ2Ì($[@ viV]F2-1rJ9Y]'>c?M_L]h{z~>hf5m#)=%&*TkdXVLyL*Fd)?lMghF^+ vbZjYXTVbYR:\"'ҬC(W9+l)I>0ɱ\ @5Ny?_ƘW.yޟ]]7?fJ$6O wHVy$#H%!7vs,-q)PUdT@\ZZ-7^+!bRyoSBˆnx(LQlMʾ0ݚ$4ɺ9zM0)j?YDJ)QU.=ܴ*C\"AD!X|4]VٲtILQnIWʪnL A)ENX8CS2)&xH6xSs3-ߐM7}0"͛=Um(y#W%9_J3`50CN10NfR7BWXylZ> AU[4PraRŪsWD\?,K-(7w_@(,qR֯jIB.}Ȕmv6质yXl]+ޕ&E;}"zMVBҕ Ju6VKk.z邾17"ĺSŹ[JxAmWE tK.]KWz r y#W%9_\=?rEK(C&Y(APp|㨑s D$Pwbܬ+R $EE>%}]-wB.}Ȕmv6质yXl]4:oEAIf@$W)VU'BTeqoe'Tw`Fm6HZ#W~Q9кV0\p?դ˜hc1&%D (w4LT>'CWM+PF?l*p$ {!$ hxDO*{@r5{$-҇pcnܤ[jUlLʉ>Q6iy[U~J ? 0Z9s c#0D̈ʍJTS#ˡ KPb.-& W&jhd!)H( j;LHU+[WJbpI%: hw!P`$r~\!WQ?fm&Onj_4kvQ"%YJnGN۵X%'/6ZӸvB-G^[ =- {P̥om83r8Hk[= y#W$7[}*;) ZR: %-3'T6BBP*hI{pjzLNY'R/rR(x[(p/x-j^UlZOl50ɲJA,?2n*G8'˜ bB]BU+ <niZN yIZ}W~Q9kUr͓Zs,6o.S'>ג>eu2VWIϧS]'>ג>eu2VWIϧS]'G̮W~Q9kUu;^H9Y]'>Mvʮk2^qG++өדUy#WS+?(etu5*$|ey<. V3mwmNͶ;6'|fDhm3mwmNͶ;6'|fDhm3mwmNͶ;6'|fDhm3mwmNͶ;6'|fDhm3mwmNͶ;66VP-SEohm3mwmNͶ;6'|fDhm3mwmNͶ;6'|fDhm3mwmNͶ;6'|fDhm3mwmNͶ;6'|fDhm3mwmNͶ;%ھ 4[@ahm3mwmNͶ;6'|fDhm3mwmNͶ;6'|fDhm3mwmNͶ;6'|fDhm3mwmNͶ;6'|fDhm3mwmNͶ^]*AAʿTqc!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:$XNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN5H8zc!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:!:0tr[_KwS.oG[u3z<ƖKf44:]Lޏ+1u9fyY-M/ΗS7ioi}-NtVcKSKns[_KwS.oG[u3z<ƖKf44:]Lޏ+1u9fyY-M/i[CNX!~-P"al|Gt)k!(HQ7((]V "-µײ{G$tVcKSKn䥼biRVí'%uJKuOg)P$+ Br :*s7B/H>ZY 3QQN*Բ/5(ETC͡aRx!ǚmM.9M-N=J,R,˭eJ2Iua틘_ ~ڟ~)SJuY55)!#:]Lޏ+1rRw1( ir,.Od1⏖% p)M&Xk%pRzOAe$*Ȩ<_7d)Sh@tC,6m׭ PHeP(R iih)aLA31in(eT1 cŹ@@ȹ \@jc1)!#:]Lޏ+1rReIQ{"I IJI e,XgspY 7%Kʾ<'W8QNNAmZh`mp7.k @81$.6xG98ҍEh{Ssn"I&m5L\Ųî 0~,82@ p5αUOah$*p`*n_[Me;:\9&L4)m(c &&4!t+z<ƖKvUCzTU&GgР)B")~`AaS6qa-T uTo6~qG jO&V-pBvm`[gr[_ӌKns_Ae+ n~&.U-P8| ]%#)'|S6 H/M(+t.MŔ d!T5~Oă-ʌIJeϼ^c+"fjda䚥qָ7ioduXuض1t0Za'\(_VA"ElliNvC:x+H'.*$zΟ{zŁKJ>[՟Q 56zn$ӏ`+LZoT&) 46Bga~!#0]Zc~dZZE8k12EkS7q\yN8i(9jЮ1%gRziLt S눤Pj}dޔ' Ba8_Gd~CD5%&pW;0tmʹ̹s$85~%&qU#Ȣp{MLY<T{S[Z_yv- Vo}OVMdV=Uw@[kK8Pav XcM@?b'#&UL:?!Sn) 50_i6)L:M]KEiSaZPeJk5G1rR^bOR){$S,8Ґmi\f.~*t<"bY܇R|1a31X KBGKn(%l%8K˃[қE{h"BeۣhOIU?M=y) U,W ߊgI݆/j8z~%jER5.*x֞W >BlRE1D=>Tu3z<Ɩ i6M1cVo/R˃%e+R=0tYyn _햫JMC}ZKiS-M/% ^P;[N HX)P?,'ښM{%/5RʤkbTۓtM>3tM}]Rŕۭ]0lצenVJO_9%ݱ[Xk֬_PQjaW+f{ט(y}-ܡok&Xůb}|}Phċ r[BN*ӧ\p)a)P[T (mH- 6Ii=f^sMП 䥘KhE{*UW?P0f+JgSOdMMLc}wNf4u~UU]p(>ԼCv9mDW%QҽJmqzo|22[HH~!hpkC\uqaJӁIhok[6iǒoG\|?HI$aZScw N u4=(K,QрI1s]-YV3F#2PͲx?t!yY_(WVpzY0EK@=r] vVr[7 Lp>nͮ"g1CI2?y%!=8LHNJ8Mv*z]t\h:L_}J@ܜ6-' I&iWŭE-d'Z 1tɲ,5Kn-/iJrf:|! =8϶M \gR?19/8RP׷ʊ)4'WG;:4I1KK0Rr 9C[k/^U&ہt!QfC+S a'ï!U ulOIQ Jy@Q1=vï!\ˠ>P\RCi' Kn1t?szWa1-"*b\Ep0>1#> ̿8rGdSTJ~bs_0ƃ_Hh6-),w W ^mNpB )9C,<&vM1&Y [8f4M͹av F (ED89Bb4^OEq(b/|,4ڭhĮKը5$KnԃBuwVA^ui4yV߉fpFTiA 5,QCb*ETI.ajp |0R&$oo客ܫEJmYÄI[1gfaN%)UV@> qN@"d5.JH@/.K2@vaKoZ>)Vq@uJL:nJ\O_':?yS^HI8s-%֕5fӈo3z;'"Yo/%p.<lcRYᢽU>VE:EkUղO~Z+CgjRi"G!N4]lS &t.`:Á%&ӓ!i4RI q wR+KI5p=SaH˺kENcX䫡I5ňW-;E뢟!.]mX,51xi\gX+^撷:AM|+輮q6 )()* A_^j=U*Cz<ƖKsWZ"8pR(cF}:Vx/߈k];1bm t8=!b/]>&g.H ĒYdpM-(!e-U(tDӿ{$t0_[L#l!g26P~,S9yY-M/%8 YNL0[$1=6Z6pJK)JT>Ҕg8 \ZTij)JN(iևXj)Kҩ100oB}.өNHZ2HlVS,Ұ^nU:~PiK(H^01,8ۂYتGwd%0ڞNK {`@)'i`+@_i97OR(PBGBh!S(\#ЫijҭȥOlpol)!%+T* m- bJAK+zrڱ{l\TP[Y>0&ECEјaUb'26N; }̃^e H#T!!HJEioi}-`Uq߄32izeԅB 'Ԅ%dc:Rz yPYJJJ0{inmҤEGh˴F # BP/[qha"ܫw("8}z<ƖEZPp'w{Ӳ8qmc=@*k1uZFN~HOt]iĿ''Kf44(IWi}2lܫFkJYhpˍ)JA[_KwS.oG[u3z<ƖKf44:]Lޏ+1u9fyY-M/ΗS7ioi}-NtVcKSKns[_KwS.oG[u3z<ƖKf44:]Lޏ+1u9fyU-"юq1&98cLsq1&98cLsq1&98cLsq1&98cLsq1&98 %i4R98cLsq1&98cLsq1&98cLsq1&98cLsq1&98cLs%iq1&98cLsq1&98cLsq1&98cLsq1&98cLsq1&98 ZNC-!1AQaq0P @`p?!s8v6\ (`f=_VRz#*B3DGmj 7p$tFM1,*H!!QR Af08b1$tJ36#o왣WBqiC@Ĭ#JD~`[a@РDĢ{zˀH3_ V[)Wi~+ITF z,D4y접IK)٦&ذanI"@b tYTa}CLCDmOa@N+, `N)h۩JI).<-22HNk&}"H׸ w 0 tC DSJT\6[YytȢ}&_tTǸO#T` sØtyCZf &[f#&:$F3'V0nB.(a >jvVĻD L7ֿ_E ؙ$=@*89 =h.dzQd,0ɱ qVҾlb\ }bK\È$ùmj{?BzQ5fzS@J̑n= tzX CXW,a.VX|q^Q0Y^@4I!Ή X$ D:łLpOF $t7a%bP(+s]jv~KbqzTT X \RPuWl:P0z_Y`'|4p;yAIV.'%{.@]l#Vg/%9@tmOm{LJRQ2 OswZIANТϵ64!s8wUՆ]O D*v(JKCه ^* U(! 5)uNQ#:)di # X G 'nv^oƿSm{Ƕ|{wZ\]'fE6ʒA*ÒNm=iʭnүXp*uǢLwZNM%芏Fa]' ϞaX"z KFNvZ7.3V3yڛP *|&Am':@I%m0{U)`o  pIV!Z ֿ_E#CLV]O(3l8%L8R}&,EA0ōFt ?^U@Jd6DOH3ίuW   Za\$(8:#zHsmi=Wې A͋Ũccq h]rl^ȏu?aD"]@t=Okތ lRIM$Vb:҇$ѐ/J@QSS =JojB C*ݝg`MWJ O1IȨ [J! BȎ%%t;l (kJU3-lL1Yp!P ̵fB*$a%pz\=pz\=pz\=pz\=pz/\=pz\=pz\=pz\=pz\=pz\=pz\=pz\=pz\=pz\=pz@i|^Ҙc4M4M4M4M4M4M4M4M4Mj.e`ptiiiiiiiiids!p&iiiiiiiiijYD|g{%9߼ڏd?Q~j=mGSͨJsyTB&+CwЊ1[fbȤLf)ဪlr1%9SXB>U zD{ll\92Ja)3$m1eM[ˢ8_ykEQ=BaBZfcwg ;B qttQ얆3 %%0p4:BGBvk2K;<EAʴ!IpK%d㢏d^|>Nz(%/ ^2fcw]3.m;Cp)L1hMvFB}rjwD?DcMKIIV^7P-(KʵD*sbPo-ҥa຺BHꠒ&X&b#qJ en6Oe$0١ S:,o|?<~Viͩy@&lEZA;%c:CՋGp}*g%Rl f˭I" 1$ܫXH'|n&lYtLgx@q{gigZ>{RnaW3Gܝ%JM,׃b-#Keb;䭛t Y6x>42Y*Q! lP,%3¯wKn0@5 +H b\6 yfD`gaH*>V4R Y6&h`'>j '\+:C 0f:NMcGn31N$yC`Dƴg[v)T Ch aY:s2Da ^&PXPP d\6HY9:LqŶ)Z-;YBlQf)7`V\j9aM)bgR>D#Ze":v_bH6 z*D1e_) B{yc/8N?0y`إjĜBNģAD3X~:xIJh@@,0T}UbacSD@&_q$vpX# ՜@2CWZW2(2*J-]ԃROS!mi4SY^xߘ% ufQkL=Q@e+ؽ/R%C &ME.+6mX}Ft-j-jh 36 1eu?yBşxRemxpHIqpdvfq+7=PR3UeD Mi4QY^xߘ%Oh/7"#:Z% fJ%& ٫6ga7z"M]Q0VִR_֒ 얫F ۤJTO1 !cBDD(~Lm9RҤ8IF!Ґ@d% ` $lkr&>k'd?B$a>gdF@NtC8DTzI:݊/`z? 'jS@C 4Sb%e4gAM8Ȣ3$xʋ#UU@w$iX-z\ZMAbqf[E (ERDM M.M}jɂF?K^dDnTg0WOB z[xy}:ނӞ֛8I٩%p0(!GJ| tzUiKE7 BL&fgAM8Ȣ3$xʯB{N> 0`A7ֵ#A]b 3v A .2sbՆ 2xƺaMcS EXJ#F#{%9%F^mGSͨJsyN6){%9̼iCUUUUUUUUUUUUUUUUUUUUUUUUUUUi&e$P1~`pO&j4]L|]!./\^qz/\^qz/\^qz/\^qz/\^qz+Y/\^qz/\^qz/\^qz/\^qz/\^qzW/\^qz/\^qz/\^qz/\^qz/\^pz$r01Z:@ e(cx`b LC{`&Mu,7wzՅ7bs7nGvedVQ:勫]QC/ɀ:^/j!w-e JqŴuvp12͡ %ȶ56jw({ӶE0H7:HC(1>& X$b ̣w҄ !xEs c(rߥK2ZJ[CIx/jR3* K "VҀA%SDHeI"&~ؗRAț/>'z<+.(,@M\atzGZB[(\G:2!VWA#Դu>޾o.[4?` DK $Tx@*%X7d)n/d,@Aq0".&,mbDʨU޾ @ rqSzj*m*)1yhqejLo!vՅe" S-%$zZCJ&Ò;c@] gZB$6!٩R*zIXmHhDadVbKĔ[#o8t#RȦb16-wz|_ɿ ¤$/\qVd!1@_ɿC$U` F}E "VӅNx]@ZtB& fʄ LHX^x+2l&IVnݾ ڐ(^ tZԤ`+S ûJYE H|;Me$ mGT rE>TVX & c҆J'֍ DI vc\#^hDdOogFN$ɢ 2FPԲ0=|+!n3gQ&][A9;o_-S0ʯ}:rj }WDD}SxWge$$H"ΰWSzIY"ǽI16 RGYhd"X+{Ղ"ZP!:4٪HqG|F~.D90ھWiwʒpkej&3;pMa-8p\q#ڠeIvisK7"{R_"="zl;T. cYoѦEfˎ c2XԴƅ&#B3@vRH&6޻UӀVm{M𱩦1M58cDLIC3-da:ĮStXTYf)YHC]!)$e.OZK@$HID$q'ibFgSUJ 9xn Y=pXsF Y,P 1,dR ]4ƓPbB'btU 5cee6RKAT9YE@*<$~M7mh_G!ޠ>##`X*vlrBDCrm5?s$QtZI DID3_ʐ: 6| AȭKޙ.as?_7DB *HD+7BEBN {GԨ`LKlHIΣܺmGfR0lFDEt<54} =CZC%4sItN*t&Bq$M3 ʩ h00Ҭ.E(.-쵨ڼa/%GQ]FW+(>+ X\; -azm H1bh2$ɱ0ħ_ BPᎺb}j8ơR*H{Qr`С@@_ZTY7C5x/C8jkfu)Z"F{!?hP16{"$1;,O/Ke6j #1&31[z#.D` )&U gCҡc7iĿBKUGv$LJНă5`Gv&~Mb<\ q@ ޾?(z&"jy3 g}^yKAFL|VS{Π_R=ыe,Y6V  q 05 $6(XpNXF՟$B Ц8D%] Mf0:=;HKauu]P[DV!0 pliِ AXT=rTKO2.mbfGt3[ؑC&( z`_J`L$՜n=pA`1r3b"-!psA`\.+.Sdp,[F&w3o!@iQpm` 7 =fJ c8 PSIZ 1X nt,m؍HL@}XؑS|7_]Ten̊Y VV` Ej" /(g`ȀL)0؇JX Z,z JPC4G^2Dd޹=GjoM,7c:qMM.&3wEZL%؏i>+VH:ҷ@Sn%m &uP"Q#`6Rw ̡g\naصʄk"Db@2C%yzGd3ol :mdLriaAhx=,- 6P @[B`Pv3KlDKEIcبP ݭ%@ ,/L2jiNJI\Y /ߗV.:bHa aBL $և߀xICLPDq( )tq1! DlpEP8B/$'4Tb^ŗu"1A5/9e4*(f0aΠ\{qdcQ l4DDWFdW Oz DSj>lJTe8TdjP |>/ɟ jT=QH[ $Jd|!էA`X GTZ)0F$GK46G^``C|ki <&$HoWʓNG޾oɿKxt2AD8;PfZ [PU2 oG=n&~Mm$ \` HyG|M޾oɿ&L;|M޾oɿ&L;|M޾oɿ&L;|M޾oɿ&L;|M޾oɿ&L;|M޾oɿ&L;|M޾oɿcFqc->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>NV,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*7}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}W}Ujv5 ? oi¿X9.?eRv;YɄF9%kIa!M/ѿk |#lp k7_wgXHByl!kJphdk DvILХ(b 7@@0 mIN@nD?mmmmmmmmmmmmmm'Q$I$I$I$I$$I$I$I$I'I$I$I$I$IRfmmmmmmmmm=mmmmlCmmmmmmmmmnRmmmmKmmmmmmmmmnRmmmmKmmmmmmmmmnRmmmmKmmmmmmmmmnRmmmmKmmmmmmmmmnRmmmmKmmmmmmemJMnRmmmmKmۡ-Umm![{nRmFij}mKmm'ۭmmYk6|a`nRmɁi-Kmgt/mdh~nRmSe a$ Km3U mdvOomO)}nRmWmKmͶmnE2nRm#E;_mKmj٭mmmo.)VIǞfnRmVYumKmmmmmmommnRmmmmKmmmmmmmmmnRmmmmKmmmmmmmmmnRmmmmKmmmmmmmmmnRmmmmKmmmmmmmmmnRmmmmK$I$I$I$I$$I$I$I$I.RI$I$I$I$IIi$I$I$I$I6I$I$I$I$LI$I$I$I$,mmmmmmmm+mmmmm-/-/-/-/-/-/-/-/-/-/-/- G/-&0/-VWd /-ؙ̅r/- n{ƨ/ -,P#/K-ɠGL?/hM-#[Gگ/0)--'{&50!4 /-;`u7Ŀˈ/s-Yn CUn ![s,/C$_-"% 3&/&fܶ4-f!M?P/^,o\-.B;\jӿ/4-[#/)H>/K- |7=ԟ/7-Sq$g$'~/`v_m-Թ8- @0+GQ㈺-k/|@u/mx-}/Ђh|-yo/{{-?/-6o/-Bo/-/-/-/-/-/-/-/-/-/-/-/-mmmmmmmm+mmmmm^mmmmimmmm}mmmm,1!Q0APa @`q?SIMV*c|u*CS>I`NRLDɡ 2%Bҕjk& :Kr>F))cXBF4!%1EIƛL0gaV`У@ ˙$'A1IֿE-1l&5(i w/#[S,EfCjT}TjJ5=4W{Zx#Wၝ1;1fǃ4`[,21oy?kARר6d *:jV5S*ՕG۲suj zQ.ΟZRAXV 1EC~j^e+~^OaB72=jƯ_ E-FoEԯo(NH5O;*5I}?QKb 20J~?p5/'O?o*[ ,/f"Cu sEc"OD>Q]@A)#Qމ)?cGzd ?sؔDb-QEXjCX G ]̠FLMB2 vڰ50.ص~ɚZE-nlLt!ܵGү(uA+MՏ 6,`4~ j%0K ,v;CA 5-2IU[Ҕ)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR\R)JR)JR)JR)JR)JR)JR)JR)JR)EX)JR)JR)JR)JR)J_ u[$mgggggggggggggggggggggggggggggggggggbf? llllllllllllllllllllllllllllllllllld_qggggggggggggggggggggggggggggggggggggctkT+a&n&n&n&n&n&n&n&n&n&n&n&n&n&n&n&n&n&nw-C&n&n&n&n&n&n&n&n&n&n&n&n&n&n&n&n&n4w{}{&n&n&n&n&n&n&n&n&n&n&n&n&n&n&n&n&n&CAJvEE%{+bd%{..O0W=bd%{..O0W=b& xB|p~w =J>bʛ] ).4dM|`Pa}%L>h,PZlՑC})Ʋ &'v43Kخ [+e]b{ i$D&`fhP`@x]C..ۢcϰ"[t;x(6)jJV@|lRdMu,aSa*MQ\hycqMx "H?@VlBBz1T]1vW.A5hZIFb{hbK] *Q5aE}T)f)3*ж 㡱v=b@UcQ࡫n?( SrŮ=&T^DY?d{؍fcW}Dv|qZ]Gqeia}4{,#!ԉc48voE m~̇}8#Yg?7ٞ= h5*V0ڤ1$bQֆj6} 4lbOlNjAP:tĨ noQ3Q1R)<>U"& V 3-b"U̎m+>UOo:؄p=6k>Ԥ߱jwVQ$ЦGfkc^b>dvV'j}8#sg;Ac1D^ U m} BŨ{dOlb[o.I!I1L5׺WEho$1lA"K~ɇ©Lt1R'9 .="M #:AOaDGFkH%`#1hYil{xRQf^DQl:CiQCWaѡwln'w=8YTBFH.vNF0RX&ZBmE,ahTXOADd.{Rm9q]J!^DXE b6 -B7j~<Z# OIНLITS& 5[datv1usNH~ɇXJKvEL<{..O0W=bd%{..O0W=bd%{..?999999999999999999999999999999999998S,}g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:g:cc}lŶWΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙΙƙ vY$I$I$I$I$I$I$I$I$HI$I$I$I$I$I$I$I$I$ERqI$I$I$I$I$I$I$I$I$GcX?41豏?E~h1,cAc ~cX?41Ǣ)Pg^{W`v=!C<ςwjs cAG!<\xaK4L葑w BkP(v N*H dh-=l1KA*%;X-UC߃Ŭw]l0+y= cAASsXFl˅Fhf]rGOR%Ŏ#ɇCU{yfT^F:jκބRC u4Іul~h1"cM 1#FiJ5w_4,cbBcl9 KPm92&F!XL%F\ zׄ0M|V`w+co)<EʤYhf%HL,Ě`븕CGă'*Zrg[/IHlZD6N|H`#|lzsT_~g0)z15 N˄7ZuLd Do|YX=P".Z\DIҴőթHH4Z/Ps@BJ!;(բl$zn*c#eZX4_ qO}>5 w܁.]CCq|VG`7{>TNP&Z Z U5{0GaI:.:z *KqD:lf~|G(lt gA* =):z|HDqn -Ecrw_'B]gC}Hc2-EDzM"jf.Hʦ. <Ք$ۉ M A!]E`ZqrN臹elhՒ1 PFZʙhM)Oҡ}zhbLzQQh|Q w!3pz,6j(rOMGd\Do!ZC6Bu).ǣ4+F*$_]±(Cg؝%5=X퍄@b@KcYуn/2j<vbe?KNGq舕0[>NmG6v:_BDg.Agw7%ب|MUz *B:nPh*m '(PRczԓJxj> :z%76AE2$_lTZGjNDhO4H`ɢF{gAYGR%Cte)Y֨NB.FW&GZ $ O% (t :FDOy͐j/BH@dQL"mc4;!"G' "5mo -+V?M魮' NV_x~ǯfMD^i OEq%i#DCOQ(f@D5Q,i HsZ z64<j6P rP2//X$O14ДMK8 ϵ=Cա-4Fq z\Bϸ$߁(k%suy4&9&v$?AAiGq05[W~=쨁4gQq# mMM=FژcA]?| BƱqW#Mz+ӏj3|3|XcNd[-tigc-Hc׳Ve%z8:kŠT[汏?&O[!Z9 ~cX?41豏?E~h1,cAc ~cX>b}XB!B!B!B!B!B!B!B!B!B!B!B!B!B!BB!B!B!B!B!B!B!B!B!B!B!B!B!B!B)!10AP Q@aq`?'C~t}Q/+RC#!2~ǫ1uFTir#F/bWMr< vfFֳ{.̇xZk RuFTir?zc%yb68eDǚWjT̅Xև"ՎdГm1(&cKhOT%F!SS?F=3'B uHctBX.ŭc}Iٚ&XCt $fP`hπ?Bh&?i6*x[ǧ@g]2cb<*7RM,hš45S (Cg%BV!x}?mت1h,&0dQʑcCSG“Z*BKl([(fv1mtBƒCPa 2# FHD-7lC^jT\Aȥ腅 "[”l|00),'$, RQi  bQUUUUUUUUNkbQj+1jPVR(((((((((نEQEQEQEQEQEQEQEQEPQEQEQEQEQEQEQEQEQBnAlzGy=z{ׅ#Ho;zGO{#Ho;zGO{#Ho;zGO{#Ho;zGO{#[z77㨫^/kƶhQ2JݓȢ1`{F98&\>'y= ]ъ с6Mяj] fo{TQ~$(-ֆщ9/|kf뉨zZv- AWs77R&- KRU"o az'AI#M hJ #71&n4 A,hCCZ$Qe8( =qяMWAXt#xda!`z*oA PI!hAZ{^5Du|ښ^f" ^i1)%u)"o;|uxt3dXQ+JCΣPEL.DIX &+V2-M-;^' f1!АH "m p!&D\p5^ׅlq5%9cR2mnhh2F.f\OFP-)RHdАp]Qv}AaWr8 HPbӥ;^&1FUDfn߅.v0AKcO{^5DuѦ~Dn { ,,ڢl$HSCyoFƚ>uS` = (T,$HNf_DGж#2+`)K[ԿCb :,%*bRAx^ׅlqDc: KC^F7^GyPh)Дy(ail%fVlc#:Pw4 PFFZ2̡ĸOkƶh#Ѽ=kƶh#Ѽ=kƶh#Ѽ=kƶh#Ѽ=kƶh#Ѽ=kƶj#7#קx_*]zUUUUUUUUUVzUUUUUUUUUZ169=1(-1ץiPw{4^SK٧\^=*WiW:.~OJu;zUίKߥҮuz]N/fsw{4^SK٧\^=*W.&BҮuz]N^حY|mZ$^=*W٦;ERlUP ddJ4 ۰l%%Bb&#'OJu;oDT]C4"&LFh.$4fߠQ9L=zUίK 憨c 5b:c#ƢtV`to9[a* 2BRNrW,xK !/e5`#t \=r !iFTP J_L좣@pmyFZQ:6M?NWxdd!!CH=KW*WIieC 8&e!zfs'gS7jC~/fC1hOi?UZ!]\@-Mpf17|%2(lPMhR#Ta%" D̄!,UW+~:m* }!  ͆s[CcHҮu|RI.&9i3)*obt2AnPD`OY#3gF/*iֈ_NpFRӡ_CY ,S)*5 PNN>8u|Vr"D dɸvJ'E2B)12MYjw1bb4 p֗RdSӅo#`=ܡh[ڷ¹Tih2%/b8oŅRZMڝYAg%FǼ!Cx4[oD!Dc ƚcXK` c;݇`k\JcфIIxHCoTL)ԅ- H1- K&&S$WM"٧g//ѩ 6J;iJ@MBD.v.hDTbZ} RF4.uz]N S%cAEb."^~V @4N!F@M*<HF@yP*l7B?.T H@"Xp"CNU0P:Q t@ dDrS $HHD녒ګ@E%*l1_Uxt px?Ţr6'(4B_TNo9y^%<C Otr@ a@ 4AL.Q ;S408El0xȀN^!@I|D( @9 X=\d5d 'p o`S@ d ÛPɻiP֩Z0 F[LCK#⡸T RԀn\ XI|$__$o>OQ&l@& H!%t a@!BQ@(0 `6H5 P.XT"JJMBl@e[[B) #, U$'!Aw/E'XT"T |$2+@@q@`$dZ00=qDx>)HJ%fX ansfƤ.^( RêĀEx=f1Yrc1>TY1ujja ;֯θ;iU#NeHߗLML8Zt02`RC 1`zH~DF]@Wy`Dvx},aCVG(t= _ ͰE:r 9.ǔgk' $&c5(%$. ByM%W@BLZ2hZі'`~@G"\ }0S:54@ #vi0d9fb l~<c0X?1<_͕o4N.ٹ0'jL 坌/&" ay $b'Cga&1h STH~lQ4kH C5 Yxl5BɅÚ$ Xi9GcMf$ar $;Ȁ0Ljy X$.JKhꓤK)3_A :W^SAW@;T UdV)bhm4/ǥ[ ` 5>kKtDV/M`.f!A"HgTNG &p(? 5^LOe l!p2JĊ<܆aa,X҉MrGL`=ZHbfx^1ah$齡`t@Lx"Cyٻ__0؅l죑j 0 Dc!|6e#<aYAmv>!<(U۠R~72@3DTk|x^#v%6X"5aXLP82od߁6?y`i)I z Z&q!D]:R$@ \%lp?[ *PǦ6O @Wwf6{:/,u! F; sx<3C#/`(&H1T ɷ@o8*LJm |elp?D Hԁ s`_ B w4QM&/!yٻ__(L m!$L\$x[ /a, X#^ #^x@nȮE@y070ؐ/a/(cD #./E݇495{LfM 0[9; M`#=/gmMT!YI!%/ȠJHDpAYb^DD`*Xv~0a=`e'&.IP5,(} Ҳ`EZc_ B+Rkf h蒀Y*i򪘤72i5e d~PunҜچZ 0J m&y/+=ő )DH#x^._"H ֊F?|ʭY\b$rc$F^|Oǔ$G$"L YE.1'֑ԋy^vnO18< yٻ__E

P!캪 nAUUUUUUUUUUUUUUUUUUUUUUUUUT x8 x8 x8 ݾ8@x 7р/ Z@D̂KA p0 0N`D.qK@ M #HP^XD=' EWdP5@#hV- `A^xz8rrCva`3R;g+%[!@  3i04 2&H&8>r<lOHb. ^d h@ @Ϥ7X!E aabnKpOHOͯXx 0 *V,`(P@|.34AP` ll hN4&A$ H~e#%8*>Bp/ iɀ @2(@;T3iSCxRi.B xoo @> < ƘH`HD [D=@4STX$ )40`G+2XWiZ)R NǓH1qP4FWÀ d!3؞/n*чyU0PeY`uml pQ^UOp;LM"?#! BJǷ c`2F@8!ǐ{2\?Px]%ޘ@ ylt @^ 'h4Ӂ@, @vsP(Q >b= `- -> l#!~@x\6ޠ%d1@Q $W  Xq>Dp$6 &r<91B@r@y9h2`tuI @dMxSFR GP֕0fwa3@ f 82?ZAED 0'g3 |fP=1|@C(-X )=U$d阠 ðX sF  Fc_@ 8WB p4zA@ OB5+0p0(7 @BR h RY$ @"6DW N@5FP_i@68p!2"(ј OP/u A#JDFiDdh/VD@ Pp\u#,8t'4 081 daȯ*"`è 0+Ћ԰]@ 8Ǫq rd @= \A" &i^:NXBRoJ1^vj -@uqg>_Ii ]P֜>G@p I4# j!L @ %}Mà>VR0P2п^@<,..B® }`GH? р@` 1~/YbTU94i  p]C5=~u @POCA c?IXh$ s D# :0@\N^̶ , : 0Qw` >,lk7Q@5_ 7i8"`а(Ojh 8"z _ i @˝&@}2\_@0":!@-NU#!'F0@Y>DJ' {DJvh73  >=}Ki0H@G U+T{j@'r_H GPaeW&%䁀&mɴ" \e &z_k$ 4y(Yu0%*@A!tI8 |bBф929K~6U؈O6zD$gci !  8z^<0@ h,@ņ@X VJPpp(4$x MBA$a,~24@)ſD@0hIteL,UH~qJZi+ʈ:0I k (Vw,1~& H4c@@Z ?x8 x8 x8 x8URJ*TRJ*TRJ*TRJ*TRJ!s )RJ*TRJ*TRJ*TRJ*TRJ;P*TRJ*TRJ*TRJ*TRJ*TS@././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/essays/pycon2013.rst0000664000175000017500000004545000000000000022274 0ustar00zuulzuul00000000000000================================================================= Dynamic Code Patterns: Extending Your Applications with Plugins ================================================================= This essay is based on my PyCon 2013 presentation of the same title. The presentation was recorded and the video is `available online `__, as are `the slides `__. Over the past few years I have been doing a lot of work on applications that make heavy use of Python’s ability to load code dynamically at runtime. This essay includes the results of some focused research that I did into patterns for using dynamic code, and the impact that research had on the design of stevedore and ceilometer, an application that uses it For my analysis, I counted any application or framework that loads code dynamically at runtime to be using plugins. I did not consider delayed execution of hard-coded import statements as plugins, but restricted the research to true dynamic loading. In most cases, the name or location of the code is given through some external mechanism like a configuration file. Why Use Plugins? ================ Before examining patterns for using plugins, we should talk about why to use plugins in an application at all. One important benefit is improved design. Keeping a separation between core and extension code encourages you to think more about abstractions in your design. Building an extensible system can take more work than hardwiring everything, but the results tend to be more flexible and maintainable over the long term. Plugins are a good way to implement device drivers and other versions of the `Strategy pattern`_. The application can maintain generic core logic, and the plugin can handle the details for interfacing with an outside system or device. .. _Strategy pattern: http://en.wikipedia.org/wiki/Strategy_pattern Packaging extensions separately reduces dependency bloat and makes deployment easier to manage and install. Users who do not need some drivers or features can avoid deploying dependencies that are only used by those plugins. Plugins also provide a convenient way to extend the feature set of an application by hooking new code into well-defined extension points. And having such an extensible system makes it easier for other developers to contribute to your project indirectly by providing add-on packages that are released separately. Requirements for Ceilometer =========================== I have spent a fair bit of time studying plugin-based architectures over the last year while helping to create ceilometer_, the new metering component in OpenStack_. Ceilometer measures the resources being used in a cloud deployment so we can bill the tenants for those resources. We collect data like the lifetimes of servers, along with bandwidth and storage consumed. .. _OpenStack: http://openstack.org .. _ceilometer: https://launchpad.net/ceilometer However, the type and number of things a given cloud deployer will want to charge for will vary, so we wanted a flexible system for taking those measurements. We need to allow deployers to write their own plugins to measure things we haven’t thought of, or that may need to be measured in a way that is private to their configuration (a case we have at DreamHost). We are expecting a lot of developers who don’t interact with us directly to be trying to write extensions to ceilometer for use in private cloud deployments, so it is also important to clearly document how to create new plugins. With these things in mind, we designed ceilometer to be flexible in several different areas. .. image:: ceilometer-design.jpg :scale: 50 :align: center OpenStack is a collection of components that cooperate to provide `Infrastructure as a Service`_ features. Each component manages a different aspect of the cloud and uses a message bus to communicate with the other components. All of the components generate notification messages when events happen (like instances being created or destroyed). Capturing those messages was the first source of data for ceilometer. The notifications contain different metadata depending on the resource that triggered the event, so we needed plugins to translate the notification messages into a standard format for metering. .. _Infrastructure as a Service: http://en.wikipedia.org/wiki/Cloud_computing There aren’t events for all of the things we want to measure for billing, so we also had to create some agents to poll for data. For example, we want to check periodically to see how much CPU capacity each instance has consumed. Some pollsters run on the hypervisor server, and others run on a management server where they can communicate with the other OpenStack components via their APIs. All of the ceilometer services use another message bus to deliver data to a collector process which uses a storage driver to write data to a database. We support relational and non-relational databases, depending on the choice of the deployer. This architecture resulted in five sets of plugins for ceilometer. OpenStack includes a message bus abstraction layer and a set of drivers for using RabbitMQ, Qpid, and ZMQ. Since that was already implemented for us, we didn’t have to touch it. The other 4 sets we created from scratch: * The plugins for processing notification messages * The pollsters for the compute nodes * The central pollsters * And the storage driver The resulting designs use patterns found in other applications and frameworks that use plugins. Other Plugin-based Applications =============================== During my research, I looked at a few projects that I was already familiar with, either as a user or a developer, and some I had not used before. There are plenty of other examples, but this list was long enough to identify some common patterns and help us with our design. Blogofile_ and Sphinx_ are two apps for working with different forms of text for publishing. They use extensions to add new content processing features. .. _Blogofile: http://blogofile.com/ .. _Sphinx: http://sphinx-doc.org/ Mercurial_ is a command line app that can be extended with new subcommands. Cliff_ is a library I created for building apps like Mercurial. .. _Mercurial: http://mercurial.selenic.com/ .. _Cliff: http://cliff.readthedocs.org Virtualenvwrapper_ is a command line tool that uses hooks in a different way, to extend existing commands but not necessarily add new ones. .. _Virtualenvwrapper: http://virtualenvwrapper.readthedocs.org Nose_ and Trac_ are common developer tools. You’re more likely to have used them than written extensions for them, but they do both use plugins. .. _Nose: https://nose.readthedocs.org/ .. _Trac: http://trac.edgewall.org/ Django_, Pyramid_, and SQLAlchemy_ are developer libraries that use plugins. .. _Django: https://www.djangoproject.com .. _Pyramid: http://docs.pylonsproject.org/projects/pyramid/en/latest/ .. _SQLAlchemy: http://www.sqlalchemy.org Diamond_ is a monitoring app with an extensive plugin set, similar to the system we were planning to build for OpenStack. .. _Diamond: https://github.com/BrightcoveOS/Diamond Nova_ is the primary component of the OpenStack cloud system. It relies on a large number of drivers for managing different aspects of the computing environment. .. _Nova: https://launchpad.net/nova I looked at all of this code in an effort to derive ideas about the "right way" to handle plugins for ceilometer. While some of what I will say today may sound critical of the choices made by the developers of the other code, I do have the benefit of hindsight and a different perspective based on looking at the examples all together, as well as different requirements for our project. Discovery ========= The first thing an application has to do with a plugin is find it. The tools I looked at are split between some form of explicit definition of plugins and a scanner that looked for the plugins. .. image:: discovery.jpg :scale: 50 :align: center Each of those sets is then further divided between what was being listed or scanned -- files on the filesystem, or python import references (either a module, or something inside of a module). The "Explicit import reference" category means there is a configuration file somewhere and a user lists an importable object in that file. The "Scan import reference" category means a registry of import strings is being scanned. All of these examples use setuptools and pkg_resources to manage entry points. Enabling ======== After the app finds a plugin, the next step is to decide whether to load it and use it. Most applications require an explicit step to configure extensions. There are times when this makes sense. Developer tools like Django are right to ask the developer to list the desired extensions explicitly, since you’re really bringing that code in statically. The extensions to SQLAlchemy are all enabled, but only one is really used at a time and that is chosen by the database connection string. .. image:: enabling.jpg :scale: 50 :align: center However, some of the user applications like Blogofile, Mercurial, and Trac ask the user to explicitly enable extensions through a configuration step that seems like it could be skipped. When I created virtualenvwrapper and cliff, I decided to use installation as a trigger for activation because I wanted to avoid an extra opportunity for misconfiguration. In both of those cases, installing an extension makes it available, so the user can start taking advantage of it immediately. That’s also true for Nose extensions, although whether or not they are used for a given test suite or test run depends on the options you give nose. Importing ========= After the app decides whether to load a plugin, the next step is to actually get the code. All of the examples I looked at used two techniques, either calling import explicitly (by using the builtin function, the imp module, or some other variation), or using pkg_resources. .. image:: importing.jpg :scale: 50 :align: center Nose, SQLAlchemy, and Blogofile all use both techniques. Nose falls back to a custom importer if pkg_resources is not installed. SQLAlchemy uses a custom importer for "extensions" distributed with the core but pkg_resources to find separate packages. Blogofile uses pkg_resources to find plugins, coupled with manual scanning and importing of the directories containing those plugins to load their parts. If I discount the packages I created myself, shown here in italics, there seems to be a clear bias towards creating custom wrappers around import. That route seems easy at first, but all of the implementations I found exhibited some problems with tricky corner cases. Application/Plugin Integration ============================== After the code for the extension is imported, the next step is to integrate it with the rest of the app. That is, to configure any hooks that need to call into the plugin, pass the plugin any state it needs, etc. I looked at this step along two axes. .. image:: integration.jpg :scale: 50 :align: center First, I considered the granularity of the plugin interface. For "fine" grained plugins, the extension is treated as a standalone object to be called on as needed. In these cases, the code object being loaded is usually a function or a class. For more "coarse" grained cases, a single plugin will include hooks that are referenced from multiple places in the application. There may be several classes inside the plugin, for example, or templates that are accessed directly by the application, not through a plugin API. The other axis related to integration looks at how the code provided by the plugin is brought into the application. I found two techniques for doing that. First, the application can instruct the plugin to integrate itself. That prompting usually takes the form of a setup() or initialization function implemented by the plugin author that calls back to an application context object, registering parts of the plugin explicitly. That registration could also be handled implicitly using an interface library such as the way Trac uses zope.interface. Second, the application itself can interrogate or inspect the plugin, and make decisions based on the result. This usually means that part of the plugin API is responsible for providing metadata about the plugin itself, not just taking action. API Enforcement =============== One common issue with dynamically loaded code is enforcing the plugin API at runtime. This is always a potential issue in dynamic languages, but it comes up frequently with plugins because the code is often written by someone other than the core developer for the application. I saw two basic techniques to help developers get their plugins right: convention and interfaces. .. image:: api-enforcement.jpg :scale: 50 :align: center Many of the applications that used convention also had coarse-grained plugin APIs, and so while they may use classes to provide their features, the plugin relies on convention for discovering its configuration. On the right are applications for which the plugin uses a class hierarchy. In the case of Nose, using the base class is optional, so that’s a quasi-interface. Trac, on the other hand, uses formal interfaces through `zope.interface`_. .. _zope.interface: http://docs.zope.org/zope.interface Diamond enforces a strict subclassing of its Collector base class. For cliff I chose to use the abc_ module to define an abstract base class, but stick with `"duck typing"`_ in the actual application. The developer doesn’t have to inherit from the base class, but doing so helps ensure that the implementation is complete. .. _abc: http://docs.python.org/2/library/abc.html .. _"duck typing": http://en.wikipedia.org/wiki/Duck_typing Invocation ========== And the final dimension I looked at was how the plugin code was used at runtime. There were three primary patterns here. .. image:: invocation.jpg :scale: 50 :align: center 1. "Drivers" are loaded one at a time, and used directly. 2. The apps using the "Dispatcher" pattern load all of the extensions, and then make calls to the appropriate one based on name or some other selection criteria when an event happens. 3. The apps that use the "Iterator" pattern call each extension in turn, so that all of the plugins have a chance to participate in the processing. Ceilometer Design ================= This analysis had a direct influence on the choices we made while implementing ceilometer. Discovery and Import -------------------- For finding and loading, we chose to use entry points because they were the simplest solution. All of the apps that work on files instead of import references had issues, ranging from poorly implemented import path munging to packaging and distribution challenges. Even some of the code for working with import references directly was a little hairy. Leaving that to a library that handles the different cases transparently made our life a lot easier. They are easier for users to install and configure because they don’t have to understand how your code is laid out. That also makes them more resilient in the face of code changes. Entry points also support different package formats (egg, sdist, operating system packages), so it doesn’t matter how extensions are distributed. They also make it easier for code to be packaged by the Linux distributions, since the packages don’t have to share overlapping installation directories. There are alternate implementations of entry-point like systems, but none are so widely used or tested as pkg_resources. And to further simplify, we always use entry points, even for the plugins we distribute with our core. That eliminates any special cases. Enabling -------- We came up with a somewhat novel solution to manage which plugins are enabled. For Ceilometer we wanted to default to collecting data, but allow deployers to disable certain meters to save storage space if they knew they did not need the data. The solution was to use explicit configuration, but invert it from the normal implementation. We assume that all of the extensions found should be loaded and used, unless they are explicitly *disabled* in the configuration file. We did that in the first version to simplify the configuration process, because we assumed most users would want most of the plugins to be used. Defaulting to enabled means users only have to provide a short list of the meters to turn off. Ceilometer plugins also have a chance, when they are being loaded, to disable themselves automatically. This is especially useful in the polling plugins, which can tell the app to ignore them if the resource they use for collecting measurements is not present (like they work with a different hypervisor, or external service that is not configured). Letting the plugin disable itself avoids repeated warning messages in the log file as a plugin is asked to poll for data that it cannot retrieve. Integration ----------- For our integration pattern we went with a fine-grained API using inspection. There is a separate namespace for each type of plugin, and each plugin instance refers to a single class. The application loads and instantiates that class, then calls methods on it it to determine what it provides and wants (which notifications to subscribe to and which meters are produced). This design lets us avoid having repetitious setup or configuration code in each plugin, since they provide data to the application on demand and the application configures itself. The instances don’t know about the application, or each other. They only run when the application calls them, never independently. API Enforcement --------------- To define the API for each set of plugins we created a separate abstract base class using the abc module. This gives us a way to document each plugin API and Developers who use the base class get some help for free. Since we don’t enforce the class hierarchy we also watch for unexpected errors from the plugins any time we call into them. Invocation ---------- We used all three invocation patterns, in different places. 1. We only use one storage system at a time, so we treat the storage plugin like a driver. 2. We load all of the notification plugins, and then dispatch incoming messages to them based on the message content. 3. We load all of the polling plugins and iterate through them on a regular schedule. Conclusions =========== After we had all of this working in ceilometer, I extracted some of the code into stevedore. It wraps pkg_resources with a series of manager classes that implement the loading, enabling, and invocation patterns. .. seealso:: * PyCon 2013 Video: http://pyvideo.org/video/1789/dynamic-code-patterns-extending-your-application * Slides: http://www.slideshare.net/doughellmann/dynamic-codepatterns * :doc:`/user/patterns_loading` * :doc:`/user/patterns_enabling` ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/history.rst0000664000175000017500000000010400000000000021013 0ustar00zuulzuul00000000000000=========== ChangeLog =========== .. include:: ../../../ChangeLog ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/index.rst0000664000175000017500000000031400000000000020424 0ustar00zuulzuul00000000000000====================== stevedore User Guide ====================== .. toctree:: :glob: :maxdepth: 2 patterns_loading patterns_enabling tutorial/index sphinxext essays/* history ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/patterns_enabling.rst0000664000175000017500000000437500000000000023027 0ustar00zuulzuul00000000000000======================= Patterns for Enabling ======================= The entry point registry maintained by setuptools lists the available plugins, but does not provide a way for the end-user to control which are used or enabled. The common patterns for managing the set of extensions to be used are described below. Enabled Through Installation ============================ For many applications, simply installing an extension is enough of an indication that the extension should be used. No explicit configuration is required on the part of the user to either discover or enable the extension, since its entry point can be discovered when all of the plugins are loaded at runtime. Examples of enabling through installation include: * `python-openstackclient`_ * virtualenvwrapper_ .. _python-openstackclient: https://github.com/openstack/python-openstackclient .. _virtualenvwrapper: http://pypi.python.org/pypi/virtualenvwrapper Enabled Explicitly ================== In other cases, the extensions may be installed system-wide but should not all be enabled for a given application or instance of an application. In these situations, the person deploying or using the application will want to select the extensions to be used through an explicit configuration step. Examples of explicitly enabled extensions include: * `Django apps`_ * `Sphinx extensions`_ * `Trac Plugins`_ .. _Trac Plugins: http://trac.edgewall.org/wiki/TracPlugins .. _Sphinx extensions: http://sphinx.pocoo.org/extensions.html .. _Django apps: https://docs.djangoproject.com/en/dev/intro/tutorial01/ .. seealso:: :class:`stevedore.named.NamedExtensionManager` Self-Enabled ============ Finally, some applications ask their extensions whether they should be enabled. The extension may look at other libraries installed on the system, check an external configuration setting, or examine a resource to see if it can be managed by the plugin. These checks are usually at runtime, either when the extension is loaded or when the user tries to access a specific resource. Examples of self-enabled extensions include: * anydbm_ * PIL_ .. _anydbm: http://docs.python.org/library/anydbm.html .. _PIL: http://www.pythonware.com/products/pil/ .. seealso:: :class:`stevedore.enabled.EnabledExtensionManager` ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/patterns_loading.rst0000664000175000017500000001004300000000000022652 0ustar00zuulzuul00000000000000====================== Patterns for Loading ====================== Setuptools entry points are registered as within a namespace that defines the API expected by the plugin code. Each entry point has a name, which does not have to be unique within a given namespace. The flexibility of this name management system makes it possible to use plugins in a variety of ways. The manager classes in stevedore wrap :mod:`importlib.metadata` to apply different rules matching the patterns described here. Drivers -- Single Name, Single Entry Point ========================================== Specifying a *driver* for communicating with an external resource (database, device, or remote application) is perhaps the most common use of dynamically loaded libraries. Drivers support the abstracted view of the resource so an application can work with different types of resources. For example, drivers may connect to database engines, load different file formats, or communicate with similar web services from different providers. Many drivers may be available for a given application, but it is implied in the interface between the application and the driver that only one driver will be used to manage a given resource. .. graphviz:: digraph drivers { app [label="namespace",shape="record"]; d1 [style=filled,color=".7 .3 1.0",label="driver 1"]; d2 [style=dotted,label="driver 2"]; d3 [style=dotted,label="driver 3"]; app -> d1; app -> d2 [style=dotted]; app -> d3 [style=dotted]; } Examples of the *drivers* pattern include: * database client libraries used by SQLAlchemy_ * cloud vendor API clients used by libcloud_ .. _SQLAlchemy: http://sqlalchemy.org/ .. _libcloud: http://libcloud.apache.org/ .. seealso:: :class:`stevedore.driver.DriverManager` Hooks -- Single Name, Many Entry Points ======================================= *Hooks*, *signals*, or *callbacks* are invoked based on an event occurring within an application. All of the hooks for an application may share a single namespace (e.g., ``my.application.hooks``) and use a different name for the triggered event (e.g., ``startup`` and ``precommit``). Multiple entry points can share the same name within the namespace, so that multiple hooks can be invoked when an event occurs. .. graphviz:: digraph drivers { app [label="namespace::event_name",shape="record"]; l1 [style=filled,color=".7 .3 1.0",label="event_name (lib1)"]; l2 [style=filled,color=".7 .3 1.0",label="event_name (lib2)"]; l3 [style=filled,color=".7 .3 1.0",label="event_name (lib3)"]; app -> l1; app -> l2; app -> l3; } Examples of the *hooks* pattern include: * Emacs `mode hook functions`_ * `Django signals`_ .. _Django signals: https://docs.djangoproject.com/en/dev/topics/signals/ .. _mode hook functions: http://www.gnu.org/software/emacs/manual/html_node/emacs/Hooks.html .. seealso:: :class:`stevedore.hook.HookManager` Extensions -- Many Names, Many Entry Points =========================================== The more general form of extending an application is to load additional functionality by discovering add-on modules that use a minimal API to inject themselves at runtime. Extensions typically want to be notified that they have been loaded and are being used so they can perform initialization or setup steps. An extension may replace core functionality or add to it. .. graphviz:: digraph drivers { app [label="application",shape="record"]; e1 [style=filled,color=".7 .3 1.0",label="extension 1"]; e2 [style=filled,color=".7 .3 1.0",label="extension 2"]; e3 [style=filled,color=".7 .3 1.0",label="extension 3"]; app -> e1; app -> e2; app -> e3; } Examples of the *extensions* pattern include: * `Django apps`_ * `Sphinx extensions`_ * `Trac Plugins`_ .. _Trac Plugins: http://trac.edgewall.org/wiki/TracPlugins .. _Sphinx extensions: http://sphinx.pocoo.org/extensions.html .. _Django apps: https://docs.djangoproject.com/en/dev/intro/tutorial01/ .. seealso:: :class:`stevedore.extension.ExtensionManager` ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/sphinxext.rst0000664000175000017500000000327600000000000021361 0ustar00zuulzuul00000000000000==================== Sphinx Integration ==================== Stevedore includes an extension for integrating with Sphinx to automatically produce documentation about the supported plugins. To activate the plugin add ``stevedore.sphinxext`` to the list of extensions in your ``conf.py``. .. rst:directive:: .. list-plugins:: namespace List the plugins in a namespace. Options: ``detailed`` Flag to switch between simple and detailed output (see below). ``overline-style`` Character to use to draw line above header, defaults to none. ``underline-style`` Character to use to draw line below header, defaults to ``=``. Simple List =========== By default, the ``list-plugins`` directive produces a simple list of plugins in a given namespace including the name and the first line of the docstring. For example: :: .. list-plugins:: stevedore.example.formatter produces ------ .. list-plugins:: stevedore.example.formatter ------ Detailed Lists ============== Adding the ``detailed`` flag to the directive causes the output to include a separate subsection for each plugin, with the full docstring rendered. The section heading level can be controlled using the ``underline-style`` and ``overline-style`` options to fit the results into the structure of your existing document. :: .. list-plugins:: stevedore.example.formatter :detailed: produces ------ .. list-plugins:: stevedore.example.formatter :detailed: :underline-style: - ------ .. note:: Depending on how Sphinx is configured, bad reStructuredText syntax in the docstrings of the plugins may cause the documentation build to fail completely when detailed mode is enabled. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8607552 stevedore-3.5.0/doc/source/user/tutorial/0000775000175000017500000000000000000000000020430 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/tutorial/creating_plugins.rst0000664000175000017500000001412300000000000024520 0ustar00zuulzuul00000000000000================== Creating Plugins ================== After a lot of trial and error, the easiest way I have found to define an API is to follow these steps: #. Use the `abc module`_ to create a base abstract class to define the behaviors required of plugins of the API. Developers don't have to subclass from the base class, but it provides a convenient way to document the API, and using an abstract base class keeps you honest. #. Create plugins by subclassing the base class and implementing the required methods. #. Define a unique namespace for each API by combining the name of the application (or library) and a name of the API. Keep it shallow. For example, "cliff.formatters" or "ceilometer.pollsters.compute". Example Plugin Set ================== The example program in this tutorial will create a plugin set with several data formatters, like what might be used by a command line program to prepare data to be printed to the console. Each formatter will take as input a dictionary with string keys and built-in data types as values. It will return as output an iterator that produces the string with the data structure formatted based on the rules of the specific formatter being used. The formatter's constructor lets the caller specify the maximum width the output should have. A Plugin Base Class =================== Step 1 above is to define an abstract base class for the API that needs to be implemented by each plugin. .. literalinclude:: ../../../../stevedore/example/base.py :language: python :prepend: # stevedore/example/base.py The constructor is a concrete method because subclasses do not need to override it, but the :func:`format` method does not do anything useful because there is no "default" implementation available. Concrete Plugins ================ The next step is to create a couple of plugin classes with concrete implementations of :func:`format`. A simple example formatter produces output with each variable name and value on a single line. .. literalinclude:: ../../../../stevedore/example/simple.py :language: python :prepend: # stevedore/example/simple.py There are plenty of other formatting options, but this example will give us enough to work with to demonstrate registering and using plugins. Registering the Plugins ======================= To use setuptools entry points, you must package your application or library using setuptools. The build and packaging process generates metadata which is available after installation to find the plugins provided by each python distribution. The entry points must be declared as belonging to a specific namespace, so we need to pick one before going any further. These plugins are formatters from the stevedore examples, so I will use the namespace "stevedore.example.formatter". Now it is possible to provide all of the necessary information in the packaging instructions: .. literalinclude:: ../../../../stevedore/example/setup.py :language: python :prepend: # stevedore/example/setup.py The important lines are near the bottom where the ``entry_points`` argument to :func:`setup` is set. The value is a dictionary mapping the namespace for the plugins to a list of their definitions. Each item in the list should be a string with ``name = module:importable`` where *name* is the user-visible name for the plugin, *module* is the Python import reference for the module, and *importable* is the name of something that can be imported from inside the module. .. literalinclude:: ../../../../stevedore/example/setup.py :language: python :lines: 37-43 In this case, there are two plugins registered. The "simple" plugin defined above, and a "plain" plugin, which is just an alias for the simple plugin. setuptools Metadata =================== During the build, setuptools copies entry point definitions to a file in the ".egg-info" directory for the package. For example, the file for stevedore is located in ``stevedore.egg-info/entry_points.txt``: :: [stevedore.example.formatter] simple = stevedore.example.simple:Simple plain = stevedore.example.simple:Simple [stevedore.test.extension] t2 = stevedore.tests.test_extension:FauxExtension t1 = stevedore.tests.test_extension:FauxExtension :mod:`importlib.metadata` uses the ``entry_points.txt`` file from all of the installed packages on the import path to find plugins. You should not modify these files, except by changing the list of entry points in ``setup.py``. .. _abc module: http://docs.python.org/2/library/abc.html .. _field list: http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#field-lists Adding Plugins in Other Packages ================================ Part of the appeal of using entry points for plugins is that they can be distributed independently of an application. The namespace setuptools uses to find the plugins is different from the Python source code namespace. It is common to use a plugin namespace prefixed with the name of the application or library that loads the plugins, to ensure it is unique, but that name has no bearing on what Python package the code for the plugin should live in. For example, we can add an alternate implementation of a formatter plugin that produces a reStructuredText `field list`_. .. literalinclude:: ../../../../stevedore/example2/fields.py :language: python :prepend: # stevedore/example2/fields.py The new plugin can then be packaged using a ``setup.py`` containing .. literalinclude:: ../../../../stevedore/example2/setup.py :language: python :prepend: # stevedore/example2/setup.py The new plugin is in a separate ``stevedore-examples2`` package. .. literalinclude:: ../../../../stevedore/example2/setup.py :language: python :lines: 3-4 However, the plugin is registered as part of the ``stevedore.example.formatter`` namespace. .. literalinclude:: ../../../../stevedore/example2/setup.py :language: python :lines: 36-40 When the plugin namespace is scanned, all packages on the current ``PYTHONPATH`` are examined and the entry point from the second package is found and can be loaded without the application having to know where the plugin is actually installed. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/tutorial/driver_output.txt0000664000175000017500000000276100000000000024112 0ustar00zuulzuul00000000000000$ python -m stevedore.example.load_as_driver a = A b = B long = word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word $ python -m stevedore.example.load_as_driver field : a : A : b : B : long : word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word $ python -m stevedore.example.load_as_driver field --width 30 : a : A : b : B : long : word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/tutorial/extension_output.txt0000664000175000017500000000264000000000000024627 0ustar00zuulzuul00000000000000$ python -m stevedore.example.load_as_extension --width 30 Formatter: simple a = A b = B long = word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word Formatter: field : a : A : b : B : long : word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word Formatter: plain a = A b = B long = word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/tutorial/index.rst0000664000175000017500000000205000000000000022266 0ustar00zuulzuul00000000000000===================================== Using Stevedore in Your Application ===================================== This tutorial is a step-by-step walk-through demonstrating how to define plugins and then use stevedore to load and use them in your application. .. toctree:: :maxdepth: 2 naming creating_plugins loading testing .. seealso:: * :doc:`../essays/pycon2013` * `Using setuptools entry points`_ * `Package Discovery and Resource Access using pkg_resources`_ * `Using Entry Points to Write Plugins | Pylons`_ * `importlib.metadata`_ .. _Using setuptools entry points: http://reinout.vanrees.org/weblog/2010/01/06/zest-releaser-entry-points.html .. _Package Discovery and Resource Access using pkg_resources: http://pythonhosted.org/distribute/pkg_resources.html .. _Using Entry Points to Write Plugins | Pylons: http://docs.pylonsproject.org/projects/pylons-webframework/en/latest/advanced_pylons/entry_points_and_plugins.html .. _importlib.metadata: https://docs.python.org/3/library/importlib.metadata.html#entry-points ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/tutorial/loading.rst0000664000175000017500000001167700000000000022613 0ustar00zuulzuul00000000000000===================== Loading the Plugins ===================== There are several different enabling and invocation patterns for consumers of plugins, depending on your needs. Loading Drivers =============== The most common way plugins are used is as individual drivers. In this case, there may be many plugin options to choose from, but only one needs to be loaded and called. The :class:`~stevedore.driver.DriverManager` class supports this pattern. This example program uses a :class:`DriverManager` to load a formatter defined in the examples for stevedore. It then uses the formatter to convert a data structure to a text format, which it can print. .. literalinclude:: ../../../../stevedore/example/load_as_driver.py :language: python :prepend: # stevedore/example/load_as_driver.py The manager takes the plugin namespace and name as arguments, and uses them to find the plugin. Then, because ``invoke_on_load`` is true, it calls the object loaded. In this case that object is the plugin class registered as a formatter. The ``invoke_args`` are positional arguments passed to the class constructor, and are used to set the maximum width parameter. .. literalinclude:: ../../../../stevedore/example/load_as_driver.py :language: python :lines: 30-35 After the manager is created, it holds a reference to a single object returned by calling the code registered for the plugin. That object is the actual driver, in this case an instance of the formatter class from the plugin. The single driver can be accessed via the :attr:`driver` property of the manager, and then its methods can be called directly. .. literalinclude:: ../../../../stevedore/example/load_as_driver.py :language: python :lines: 34-35 Running the example program produces this output: .. literalinclude:: driver_output.txt Loading Extensions ================== Another common use case is to load several extensions at one time, and do something with all of them. Several of the other manager classes support this invocation pattern, including :class:`~stevedore.extension.ExtensionManager`, :class:`~stevedore.named.NamedExtensionManager`, and :class:`~stevedore.enabled.EnabledExtensionManager`. .. literalinclude:: ../../../../stevedore/example/load_as_extension.py :language: python :prepend: # stevedore/example/load_as_extension.py The :class:`ExtensionManager` is created slightly differently from the :class:`DriverManager` because it does not need to know in advance which plugin to load. It loads all of the plugins it finds. .. literalinclude:: ../../../../stevedore/example/load_as_extension.py :language: python :lines: 24-28 To call the plugins, use the :meth:`map` method, passing a callable to be invoked for each extension. The :func:`format_data` function used with :meth:`map` in this example takes two arguments, the :class:`~stevedore.extension.Extension` and the data argument given to :meth:`map`. .. literalinclude:: ../../../../stevedore/example/load_as_extension.py :language: python :lines: 30-33 The :class:`Extension` passed :func:`format_data` is a class defined by stevedore that wraps the plugin. It includes the name of the plugin, the :class:`EntryPoint` returned by :mod:`importlib.metadata`, and the plugin itself (the named object referenced by the plugin definition). When ``invoke_on_load`` is true, the :class:`Extension` will also have an :attr:`obj` attribute containing the value returned when the plugin was invoked. :meth:`map` returns a sequence of the values returned by the callback function. In this case, :func:`format_data` returns a tuple containing the extension name and the iterable that produces the text to print. As the results are processed, the name of each plugin is printed and then the formatted data. .. literalinclude:: ../../../../stevedore/example/load_as_extension.py :language: python :lines: 33-37 The order the plugins are loaded is undefined, and depends on the order packages are found on the import path as well as the way the metadata files are read. If the order extensions are used matters, try the :class:`~stevedore.named.NamedExtensionManager`. .. literalinclude:: extension_output.txt Why Not Call Plugins Directly? ============================== Using a separate callable argument to :meth:`map`, rather than just invoking the plugin directly introduces a separation between your application code and the plugins. The benefits of this separation manifest in the application code design and in the plugin API design. If :meth:`map` called the plugin directly, each plugin would have to be a callable. That would mean a separate namespace for what is really just a method of the plugin. By using a separate callable argument, the plugin API does not need to match exactly any particular use case in the application. This frees you to create a finer-grained API, with more individual methods that can be called in different ways to achieve different goals. .. seealso:: * :doc:`../patterns_loading` * :doc:`../patterns_enabling` ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/tutorial/naming.rst0000664000175000017500000000357100000000000022441 0ustar00zuulzuul00000000000000=============================== Guidelines for Naming Plugins =============================== Stevedore uses setuptools entry points to define and load plugins. An entry point is standard way to refer to a named object defined inside a Python module or package. The name can be a reference to any class, function, or instance, as long as it is created when the containing module is imported (i.e., it needs to be a module-level global). Names and Namespaces ==================== Entry points are registered using a *name* in a *namespace*. Entry point names are usually considered user-visible. For example, they frequently appear in configuration files where a driver is being enabled. Because they are public, names are typically as short as possible while remaining descriptive. For example, database driver plugin names might be "mysql", "postgresql", "sqlite", etc. Namespaces, on the other hand, are an implementation detail, and while they are known to developers they are not usually exposed to users. The namespace naming syntax looks a lot like Python's package syntax (``a.b.c``) but *namespaces do not correspond to Python packages*. Using a Python package name for an entry point namespace is an easy way to ensure a unique name, but it's not required at all. The main feature of entry points is that they can be discovered *across* packages. That means that a plugin can be developed and installed completely separately from the application that uses it, as long as they agree on the namespace and API. Each namespace is owned by the code that consumes the plugins and is used to search for entry points. The entry point names are typically owned by the plugin, but they can also be defined by the consuming code for named hooks (see :class:`~stevedore.hook.HookManager`). The names of entry points must be unique within a given distribution, but are not necessarily unique in a namespace. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/doc/source/user/tutorial/testing.rst0000664000175000017500000000025400000000000022640 0ustar00zuulzuul00000000000000========= Testing ========= .. describe using the TestManager for setting up application tests .. seealso:: * :class:`~stevedore.tests.manager.TestExtensionManager` ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8527553 stevedore-3.5.0/releasenotes/0000775000175000017500000000000000000000000016233 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8607552 stevedore-3.5.0/releasenotes/notes/0000775000175000017500000000000000000000000017363 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/notes/add-reno-996dd44974d53238.yaml0000664000175000017500000000007200000000000023761 0ustar00zuulzuul00000000000000--- other: - Introduce reno for deployer release notes. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/notes/add-skip-caching-aa13be0299cc8b8c.yaml0000664000175000017500000000050000000000000025701 0ustar00zuulzuul00000000000000--- features: - | Add possibility to skip caching endpoints to the filesystem when '.disable' file is present in the cache directory. fixes: - | When python interpreter invokimg the module is located under /tmp (the case when i.e. Ansible module uses stevedore) do not try to write cache to the file system. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/notes/drop-python2-support-3f0f717570cad8cb.yaml0000664000175000017500000000014100000000000026616 0ustar00zuulzuul00000000000000--- upgrade: - | Support for Python 2.7 is removed. Python 3.6 or greater is now required. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/notes/entry-point-type-change-06ca3b301ba7aad1.yaml0000664000175000017500000000115300000000000027262 0ustar00zuulzuul00000000000000--- features: - | Adds a caching layer. The cache is a single JSON file created automatically in the user's home directory. It stores the parsed text data from all of the metadata input files in a file with a name based on the hash of the contents and `sys.path`, ensuring uniqueness for applications installed into different virtual environments. upgrade: - | The type of the entry point objects returned has changed from `pkg_resources.EntryPoint` to `importlib.metadata.EntryPoint`. The new objects still have a `load()` method, but some of the other APIs are different. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/notes/expose-entry-point-properties-6f2d868d4342fc0d.yaml0000664000175000017500000000033700000000000030460 0ustar00zuulzuul00000000000000--- features: - | Add `extras` and `attr` properties to the `Extension` class to make it easier for consumers to access the underlying properties, regardless of the version of `importlib.metadata` being used. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/notes/module-name-property-d3b2d092259dadec.yaml0000664000175000017500000000024600000000000026706 0ustar00zuulzuul00000000000000--- features: - | Add a `module_name` property to the `Extension` class to make it easier for consumers to determine where the plugin is being loaded from. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8647554 stevedore-3.5.0/releasenotes/source/0000775000175000017500000000000000000000000017533 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8647554 stevedore-3.5.0/releasenotes/source/_static/0000775000175000017500000000000000000000000021161 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/source/_static/.placeholder0000664000175000017500000000000000000000000023432 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8647554 stevedore-3.5.0/releasenotes/source/_templates/0000775000175000017500000000000000000000000021670 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/source/_templates/.placeholder0000664000175000017500000000000000000000000024141 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/source/conf.py0000664000175000017500000002135000000000000021033 0ustar00zuulzuul00000000000000# -*- coding: utf-8 -*- # Copyright (C) 2020 Red Hat, Inc. # # 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. # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # sys.path.insert(0, os.path.abspath('.')) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'openstackdocstheme', 'reno.sphinxext', ] # openstackdocstheme options openstackdocs_repo_name = 'openstack/stevedore' openstackdocs_auto_name = False openstackdocs_bug_project = 'python-stevedore' openstackdocs_bug_tag = '' # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. # source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'stevedore Release Notes' copyright = u'2016, stevedore Developers' # Release do not need a version number in the title, they # cover multiple versions. # The full version, including alpha/beta/rc tags. release = '' # The short X.Y version. version = '' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: # today = '' # Else, today_fmt is used as the format for a strftime call. # today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [] # The reST default role (used for this markup: `text`) to use for all # documents. # default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. # add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). # add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. # show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'native' # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. # keep_warnings = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'openstackdocs' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. # html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". # html_title = None # A shorter title for the navigation bar. Default is the same as html_title. # html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. # html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. # html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. # html_extra_path = [] # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. # html_use_smartypants = True # Custom sidebar templates, maps document names to template names. # html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. # html_additional_pages = {} # If false, no module index is generated. # html_domain_indices = True # If false, no index is generated. # html_use_index = True # If true, the index is split into individual pages for each letter. # html_split_index = False # If true, links to the reST sources are added to the pages. # html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. # html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. # html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. # html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). # html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'stevedoreReleaseNotesDoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # 'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', 'stevedoreReleaseNotes.tex', u'stevedore Release Notes Documentation', u'stevedore Developers', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. # latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. # latex_use_parts = False # If true, show page references after internal links. # latex_show_pagerefs = False # If true, show URL addresses after external links. # latex_show_urls = False # Documents to append as an appendix to all manuals. # latex_appendices = [] # If false, no module index is generated. # latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'stevedoreReleaseNotes', u'stevedore Release Notes Documentation', [u'stevedore Developers'], 1) ] # If true, show URL addresses after external links. # man_show_urls = False # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'stevedoreReleaseNotes', u'stevedore Release Notes Documentation', u'stevedore Developers', 'stevedoreReleaseNotes', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. # texinfo_appendices = [] # If false, no module index is generated. # texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. # texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. # texinfo_no_detailmenu = False # -- Options for Internationalization output ------------------------------ locale_dirs = ['locale/'] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/source/index.rst0000664000175000017500000000033100000000000021371 0ustar00zuulzuul00000000000000========================= stevedore Release Notes ========================= .. toctree:: :maxdepth: 1 unreleased xena wallaby victoria ussuri train stein rocky queens pike ocata ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/source/ocata.rst0000664000175000017500000000023000000000000021347 0ustar00zuulzuul00000000000000=================================== Ocata Series Release Notes =================================== .. release-notes:: :branch: origin/stable/ocata ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/source/pike.rst0000664000175000017500000000021700000000000021215 0ustar00zuulzuul00000000000000=================================== Pike Series Release Notes =================================== .. release-notes:: :branch: stable/pike ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/source/queens.rst0000664000175000017500000000022300000000000021562 0ustar00zuulzuul00000000000000=================================== Queens Series Release Notes =================================== .. release-notes:: :branch: stable/queens ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/source/rocky.rst0000664000175000017500000000022100000000000021407 0ustar00zuulzuul00000000000000=================================== Rocky Series Release Notes =================================== .. release-notes:: :branch: stable/rocky ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/source/stein.rst0000664000175000017500000000022100000000000021402 0ustar00zuulzuul00000000000000=================================== Stein Series Release Notes =================================== .. release-notes:: :branch: stable/stein ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/source/train.rst0000664000175000017500000000017600000000000021406 0ustar00zuulzuul00000000000000========================== Train Series Release Notes ========================== .. release-notes:: :branch: stable/train ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/source/unreleased.rst0000664000175000017500000000016000000000000022411 0ustar00zuulzuul00000000000000============================== Current Series Release Notes ============================== .. release-notes:: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/source/ussuri.rst0000664000175000017500000000020200000000000021611 0ustar00zuulzuul00000000000000=========================== Ussuri Series Release Notes =========================== .. release-notes:: :branch: stable/ussuri ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/source/victoria.rst0000664000175000017500000000021200000000000022100 0ustar00zuulzuul00000000000000============================= Victoria Series Release Notes ============================= .. release-notes:: :branch: stable/victoria ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/source/wallaby.rst0000664000175000017500000000020600000000000021716 0ustar00zuulzuul00000000000000============================ Wallaby Series Release Notes ============================ .. release-notes:: :branch: stable/wallaby ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/releasenotes/source/xena.rst0000664000175000017500000000017200000000000021220 0ustar00zuulzuul00000000000000========================= Xena Series Release Notes ========================= .. release-notes:: :branch: stable/xena ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/requirements.txt0000664000175000017500000000045700000000000017034 0ustar00zuulzuul00000000000000# The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. pbr!=2.1.0,>=2.0.0 # Apache-2.0 importlib_metadata>=1.7.0;python_version<'3.8' # Apache-2.0 ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8767555 stevedore-3.5.0/setup.cfg0000664000175000017500000000222300000000000015362 0ustar00zuulzuul00000000000000[metadata] name = stevedore description_file = README.rst author = OpenStack author_email = openstack-discuss@lists.openstack.org summary = Manage dynamic plugins for Python applications home_page = https://docs.openstack.org/stevedore/latest/ python_requires = >=3.6 classifier = Development Status :: 5 - Production/Stable License :: OSI Approved :: Apache Software License Programming Language :: Python Programming Language :: Python :: 3 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3 :: Only Programming Language :: Python :: Implementation :: CPython Intended Audience :: Developers Environment :: Console [files] packages = stevedore [entry_points] stevedore.example.formatter = simple = stevedore.example.simple:Simple field = stevedore.example2.fields:FieldList plain = stevedore.example.simple:Simple stevedore.test.extension = t1 = stevedore.tests.test_extension:FauxExtension t2 = stevedore.tests.test_extension:FauxExtension e1 = stevedore.tests.test_extension:BrokenExtension e2 = stevedore.tests.notfound:UnimportableExtension [egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/setup.py0000664000175000017500000000137600000000000015263 0ustar00zuulzuul00000000000000# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # # 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. # THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT import setuptools setuptools.setup( setup_requires=['pbr>=2.0.0'], pbr=True) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8647554 stevedore-3.5.0/stevedore/0000775000175000017500000000000000000000000015542 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/__init__.py0000664000175000017500000000104000000000000017646 0ustar00zuulzuul00000000000000# flake8: noqa __all__ = [ 'ExtensionManager', 'EnabledExtensionManager', 'NamedExtensionManager', 'HookManager', 'DriverManager', ] from .extension import ExtensionManager from .enabled import EnabledExtensionManager from .named import NamedExtensionManager from .hook import HookManager from .driver import DriverManager import logging # Configure a NullHandler for our log messages in case # the app we're used from does not set up logging. LOG = logging.getLogger('stevedore') LOG.addHandler(logging.NullHandler()) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/_cache.py0000664000175000017500000001452100000000000017321 0ustar00zuulzuul00000000000000# 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. """Use a cache layer in front of entry point scanning.""" import errno import glob import hashlib import itertools import json import logging import os import os.path import struct import sys try: # For python 3.8 and later import importlib.metadata as importlib_metadata except ImportError: # For everyone else import importlib_metadata log = logging.getLogger('stevedore._cache') def _get_cache_dir(): """Locate a platform-appropriate cache directory to use. Does not ensure that the cache directory exists. """ # Linux, Unix, AIX, etc. if os.name == 'posix' and sys.platform != 'darwin': # use ~/.cache if empty OR not set base_path = os.environ.get("XDG_CACHE_HOME", None) \ or os.path.expanduser('~/.cache') return os.path.join(base_path, 'python-entrypoints') # Mac OS elif sys.platform == 'darwin': return os.path.expanduser('~/Library/Caches/Python Entry Points') # Windows (hopefully) else: base_path = os.environ.get('LOCALAPPDATA', None) \ or os.path.expanduser('~\\AppData\\Local') return os.path.join(base_path, 'Python Entry Points') def _get_mtime(name): try: s = os.stat(name) return s.st_mtime except OSError as err: if err.errno != errno.ENOENT: raise return -1.0 def _ftobytes(f): return struct.Struct('f').pack(f) def _hash_settings_for_path(path): """Return a hash and the path settings that created it.""" paths = [] h = hashlib.sha256() # Tie the cache to the python interpreter, in case it is part of a # virtualenv. h.update(sys.executable.encode('utf-8')) h.update(sys.prefix.encode('utf-8')) for entry in path: mtime = _get_mtime(entry) h.update(entry.encode('utf-8')) h.update(_ftobytes(mtime)) paths.append((entry, mtime)) for ep_file in itertools.chain( glob.iglob(os.path.join(entry, '*.dist-info', 'entry_points.txt')), glob.iglob(os.path.join(entry, '*.egg-info', 'entry_points.txt')) ): mtime = _get_mtime(ep_file) h.update(ep_file.encode('utf-8')) h.update(_ftobytes(mtime)) paths.append((ep_file, mtime)) return (h.hexdigest(), paths) def _build_cacheable_data(path): real_groups = importlib_metadata.entry_points() # Convert the namedtuple values to regular tuples groups = {} for name, group_data in real_groups.items(): existing = set() members = [] groups[name] = members for ep in group_data: # Filter out duplicates that can occur when testing a # package that provides entry points using tox, where the # package is installed in the virtualenv that tox builds # and is present in the path as '.'. item = ep.name, ep.value, ep.group # convert to tuple if item in existing: continue existing.add(item) members.append(item) return { 'groups': groups, 'sys.executable': sys.executable, 'sys.prefix': sys.prefix, } class Cache: def __init__(self, cache_dir=None): if cache_dir is None: cache_dir = _get_cache_dir() self._dir = cache_dir self._internal = {} self._disable_caching = False # Caching can be disabled by either placing .disable file into the # target directory or when python executable is under /tmp (this is the # case when executed from ansible) if any([os.path.isfile(os.path.join(self._dir, '.disable')), sys.executable[0:4] == '/tmp']): self._disable_caching = True def _get_data_for_path(self, path): if path is None: path = sys.path internal_key = tuple(path) if internal_key in self._internal: return self._internal[internal_key] digest, path_values = _hash_settings_for_path(path) filename = os.path.join(self._dir, digest) try: log.debug('reading %s', filename) with open(filename, 'r') as f: data = json.load(f) except (IOError, json.JSONDecodeError): data = _build_cacheable_data(path) data['path_values'] = path_values if not self._disable_caching: try: log.debug('writing to %s', filename) os.makedirs(self._dir, exist_ok=True) with open(filename, 'w') as f: json.dump(data, f) except (IOError, OSError): # Could not create cache dir or write file. pass self._internal[internal_key] = data return data def get_group_all(self, group, path=None): result = [] data = self._get_data_for_path(path) group_data = data.get('groups', {}).get(group, []) for vals in group_data: result.append(importlib_metadata.EntryPoint(*vals)) return result def get_group_named(self, group, path=None): result = {} for ep in self.get_group_all(group, path=path): if ep.name not in result: result[ep.name] = ep return result def get_single(self, group, name, path=None): for name, ep in self.get_group_named(group, path=path).items(): if name == name: return ep raise ValueError('No entrypoint {!r} in group {!r}'.format( group, name)) _c = Cache() get_group_all = _c.get_group_all get_group_named = _c.get_group_named get_single = _c.get_single ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/dispatch.py0000664000175000017500000002253100000000000017716 0ustar00zuulzuul00000000000000# 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. import logging from .enabled import EnabledExtensionManager from .exception import NoMatches LOG = logging.getLogger(__name__) class DispatchExtensionManager(EnabledExtensionManager): """Loads all plugins and filters on execution. This is useful for long-running processes that need to pass different inputs to different extensions. :param namespace: The namespace for the entry points. :type namespace: str :param check_func: Function to determine which extensions to load. :type check_func: callable :param invoke_on_load: Boolean controlling whether to invoke the object returned by the entry point after the driver is loaded. :type invoke_on_load: bool :param invoke_args: Positional arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_args: tuple :param invoke_kwds: Named arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_kwds: dict :param propagate_map_exceptions: Boolean controlling whether exceptions are propagated up through the map call or whether they are logged and then ignored :type invoke_on_load: bool """ def map(self, filter_func, func, *args, **kwds): """Iterate over the extensions invoking func() for any where filter_func() returns True. The signature of filter_func() should be:: def filter_func(ext, *args, **kwds): pass The first argument to filter_func(), 'ext', is the :class:`~stevedore.extension.Extension` instance. filter_func() should return True if the extension should be invoked for the input arguments. The signature for func() should be:: def func(ext, *args, **kwds): pass The first argument to func(), 'ext', is the :class:`~stevedore.extension.Extension` instance. Exceptions raised from within func() are propagated up and processing stopped if self.propagate_map_exceptions is True, otherwise they are logged and ignored. :param filter_func: Callable to test each extension. :param func: Callable to invoke for each extension. :param args: Variable arguments to pass to func() :param kwds: Keyword arguments to pass to func() :returns: List of values returned from func() """ if not self.extensions: # FIXME: Use a more specific exception class here. raise NoMatches('No %s extensions found' % self.namespace) response = [] for e in self.extensions: if filter_func(e, *args, **kwds): self._invoke_one_plugin(response.append, func, e, args, kwds) return response def map_method(self, filter_func, method_name, *args, **kwds): """Iterate over the extensions invoking each one's object method called `method_name` for any where filter_func() returns True. This is equivalent of using :meth:`map` with func set to `lambda x: x.obj.method_name()` while being more convenient. Exceptions raised from within the called method are propagated up and processing stopped if self.propagate_map_exceptions is True, otherwise they are logged and ignored. .. versionadded:: 0.12 :param filter_func: Callable to test each extension. :param method_name: The extension method name to call for each extension. :param args: Variable arguments to pass to method :param kwds: Keyword arguments to pass to method :returns: List of values returned from methods """ return self.map(filter_func, self._call_extension_method, method_name, *args, **kwds) class NameDispatchExtensionManager(DispatchExtensionManager): """Loads all plugins and filters on execution. This is useful for long-running processes that need to pass different inputs to different extensions and can predict the name of the extensions before calling them. The check_func argument should return a boolean, with ``True`` indicating that the extension should be loaded and made available and ``False`` indicating that the extension should be ignored. :param namespace: The namespace for the entry points. :type namespace: str :param check_func: Function to determine which extensions to load. :type check_func: callable :param invoke_on_load: Boolean controlling whether to invoke the object returned by the entry point after the driver is loaded. :type invoke_on_load: bool :param invoke_args: Positional arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_args: tuple :param invoke_kwds: Named arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_kwds: dict :param propagate_map_exceptions: Boolean controlling whether exceptions are propagated up through the map call or whether they are logged and then ignored :type invoke_on_load: bool :param on_load_failure_callback: Callback function that will be called when an entrypoint can not be loaded. The arguments that will be provided when this is called (when an entrypoint fails to load) are (manager, entrypoint, exception) :type on_load_failure_callback: function :param verify_requirements: Use setuptools to enforce the dependencies of the plugin(s) being loaded. Defaults to False. :type verify_requirements: bool """ def __init__(self, namespace, check_func, invoke_on_load=False, invoke_args=(), invoke_kwds={}, propagate_map_exceptions=False, on_load_failure_callback=None, verify_requirements=False): super(NameDispatchExtensionManager, self).__init__( namespace=namespace, check_func=check_func, invoke_on_load=invoke_on_load, invoke_args=invoke_args, invoke_kwds=invoke_kwds, propagate_map_exceptions=propagate_map_exceptions, on_load_failure_callback=on_load_failure_callback, verify_requirements=verify_requirements, ) def _init_plugins(self, extensions): super(NameDispatchExtensionManager, self)._init_plugins(extensions) self.by_name = dict((e.name, e) for e in self.extensions) def map(self, names, func, *args, **kwds): """Iterate over the extensions invoking func() for any where the name is in the given list of names. The signature for func() should be:: def func(ext, *args, **kwds): pass The first argument to func(), 'ext', is the :class:`~stevedore.extension.Extension` instance. Exceptions raised from within func() are propagated up and processing stopped if self.propagate_map_exceptions is True, otherwise they are logged and ignored. :param names: List or set of name(s) of extension(s) to invoke. :param func: Callable to invoke for each extension. :param args: Variable arguments to pass to func() :param kwds: Keyword arguments to pass to func() :returns: List of values returned from func() """ response = [] for name in names: try: e = self.by_name[name] except KeyError: LOG.debug('Missing extension %r being ignored', name) else: self._invoke_one_plugin(response.append, func, e, args, kwds) return response def map_method(self, names, method_name, *args, **kwds): """Iterate over the extensions invoking each one's object method called `method_name` for any where the name is in the given list of names. This is equivalent of using :meth:`map` with func set to `lambda x: x.obj.method_name()` while being more convenient. Exceptions raised from within the called method are propagated up and processing stopped if self.propagate_map_exceptions is True, otherwise they are logged and ignored. .. versionadded:: 0.12 :param names: List or set of name(s) of extension(s) to invoke. :param method_name: The extension method name to call for each extension. :param args: Variable arguments to pass to method :param kwds: Keyword arguments to pass to method :returns: List of values returned from methods """ return self.map(names, self._call_extension_method, method_name, *args, **kwds) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/driver.py0000664000175000017500000001412100000000000017406 0ustar00zuulzuul00000000000000# 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. from .exception import MultipleMatches from .exception import NoMatches from .named import NamedExtensionManager class DriverManager(NamedExtensionManager): """Load a single plugin with a given name from the namespace. :param namespace: The namespace for the entry points. :type namespace: str :param name: The name of the driver to load. :type name: str :param invoke_on_load: Boolean controlling whether to invoke the object returned by the entry point after the driver is loaded. :type invoke_on_load: bool :param invoke_args: Positional arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_args: tuple :param invoke_kwds: Named arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_kwds: dict :param on_load_failure_callback: Callback function that will be called when an entrypoint can not be loaded. The arguments that will be provided when this is called (when an entrypoint fails to load) are (manager, entrypoint, exception) :type on_load_failure_callback: function :param verify_requirements: Use setuptools to enforce the dependencies of the plugin(s) being loaded. Defaults to False. :type verify_requirements: bool :type warn_on_missing_entrypoint: bool """ def __init__(self, namespace, name, invoke_on_load=False, invoke_args=(), invoke_kwds={}, on_load_failure_callback=None, verify_requirements=False, warn_on_missing_entrypoint=True): on_load_failure_callback = on_load_failure_callback \ or self._default_on_load_failure super(DriverManager, self).__init__( namespace=namespace, names=[name], invoke_on_load=invoke_on_load, invoke_args=invoke_args, invoke_kwds=invoke_kwds, on_load_failure_callback=on_load_failure_callback, verify_requirements=verify_requirements, warn_on_missing_entrypoint=warn_on_missing_entrypoint ) @staticmethod def _default_on_load_failure(drivermanager, ep, err): raise @classmethod def make_test_instance(cls, extension, namespace='TESTING', propagate_map_exceptions=False, on_load_failure_callback=None, verify_requirements=False): """Construct a test DriverManager Test instances are passed a list of extensions to work from rather than loading them from entry points. :param extension: Pre-configured Extension instance :type extension: :class:`~stevedore.extension.Extension` :param namespace: The namespace for the manager; used only for identification since the extensions are passed in. :type namespace: str :param propagate_map_exceptions: Boolean controlling whether exceptions are propagated up through the map call or whether they are logged and then ignored :type propagate_map_exceptions: bool :param on_load_failure_callback: Callback function that will be called when an entrypoint can not be loaded. The arguments that will be provided when this is called (when an entrypoint fails to load) are (manager, entrypoint, exception) :type on_load_failure_callback: function :param verify_requirements: Use setuptools to enforce the dependencies of the plugin(s) being loaded. Defaults to False. :type verify_requirements: bool :return: The manager instance, initialized for testing """ o = super(DriverManager, cls).make_test_instance( [extension], namespace=namespace, propagate_map_exceptions=propagate_map_exceptions, on_load_failure_callback=on_load_failure_callback, verify_requirements=verify_requirements) return o def _init_plugins(self, extensions): super(DriverManager, self)._init_plugins(extensions) if not self.extensions: name = self._names[0] raise NoMatches('No %r driver found, looking for %r' % (self.namespace, name)) if len(self.extensions) > 1: discovered_drivers = ','.join(e.entry_point_target for e in self.extensions) raise MultipleMatches('Multiple %r drivers found: %s' % (self.namespace, discovered_drivers)) def __call__(self, func, *args, **kwds): """Invokes func() for the single loaded extension. The signature for func() should be:: def func(ext, *args, **kwds): pass The first argument to func(), 'ext', is the :class:`~stevedore.extension.Extension` instance. Exceptions raised from within func() are logged and ignored. :param func: Callable to invoke for each extension. :param args: Variable arguments to pass to func() :param kwds: Keyword arguments to pass to func() :returns: List of values returned from func() """ results = self.map(func, *args, **kwds) if results: return results[0] @property def driver(self): """Returns the driver being used by this manager.""" ext = self.extensions[0] return ext.obj if ext.obj else ext.plugin ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/enabled.py0000664000175000017500000000676200000000000017521 0ustar00zuulzuul00000000000000# 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. import logging from .extension import ExtensionManager LOG = logging.getLogger(__name__) class EnabledExtensionManager(ExtensionManager): """Loads only plugins that pass a check function. The check_func argument should return a boolean, with ``True`` indicating that the extension should be loaded and made available and ``False`` indicating that the extension should be ignored. :param namespace: The namespace for the entry points. :type namespace: str :param check_func: Function to determine which extensions to load. :type check_func: callable, taking an :class:`Extension` instance as argument :param invoke_on_load: Boolean controlling whether to invoke the object returned by the entry point after the driver is loaded. :type invoke_on_load: bool :param invoke_args: Positional arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_args: tuple :param invoke_kwds: Named arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_kwds: dict :param propagate_map_exceptions: Boolean controlling whether exceptions are propagated up through the map call or whether they are logged and then ignored :type propagate_map_exceptions: bool :param on_load_failure_callback: Callback function that will be called when an entrypoint can not be loaded. The arguments that will be provided when this is called (when an entrypoint fails to load) are (manager, entrypoint, exception) :type on_load_failure_callback: function :param verify_requirements: Use setuptools to enforce the dependencies of the plugin(s) being loaded. Defaults to False. :type verify_requirements: bool """ def __init__(self, namespace, check_func, invoke_on_load=False, invoke_args=(), invoke_kwds={}, propagate_map_exceptions=False, on_load_failure_callback=None, verify_requirements=False,): self.check_func = check_func super(EnabledExtensionManager, self).__init__( namespace, invoke_on_load=invoke_on_load, invoke_args=invoke_args, invoke_kwds=invoke_kwds, propagate_map_exceptions=propagate_map_exceptions, on_load_failure_callback=on_load_failure_callback, verify_requirements=verify_requirements, ) def _load_one_plugin(self, ep, invoke_on_load, invoke_args, invoke_kwds, verify_requirements): ext = super(EnabledExtensionManager, self)._load_one_plugin( ep, invoke_on_load, invoke_args, invoke_kwds, verify_requirements, ) if ext and not self.check_func(ext): LOG.debug('ignoring extension %r', ep.name) return None return ext ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8687553 stevedore-3.5.0/stevedore/example/0000775000175000017500000000000000000000000017175 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/example/__init__.py0000664000175000017500000000000000000000000021274 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/example/base.py0000664000175000017500000000212700000000000020463 0ustar00zuulzuul00000000000000# -*- coding: utf-8 -*- # Copyright (C) 2020 Red Hat, Inc. # # 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. import abc class FormatterBase(metaclass=abc.ABCMeta): """Base class for example plugin used in the tutorial. """ def __init__(self, max_width=60): self.max_width = max_width @abc.abstractmethod def format(self, data): """Format the data and return unicode text. :param data: A dictionary with string keys and simple types as values. :type data: dict(str:?) :returns: Iterable producing the formatted text. """ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/example/load_as_driver.py0000664000175000017500000000250100000000000022522 0ustar00zuulzuul00000000000000# Copyright (C) 2020 Red Hat, Inc. # # 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. import argparse from stevedore import driver if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument( 'format', nargs='?', default='simple', help='the output format', ) parser.add_argument( '--width', default=60, type=int, help='maximum output width for text', ) parsed_args = parser.parse_args() data = { 'a': 'A', 'b': 'B', 'long': 'word ' * 80, } mgr = driver.DriverManager( namespace='stevedore.example.formatter', name=parsed_args.format, invoke_on_load=True, invoke_args=(parsed_args.width,), ) for chunk in mgr.driver.format(data): print(chunk, end='') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/example/load_as_extension.py0000664000175000017500000000257400000000000023255 0ustar00zuulzuul00000000000000# Copyright (C) 2020 Red Hat, Inc. # # 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. import argparse from stevedore import extension if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument( '--width', default=60, type=int, help='maximum output width for text', ) parsed_args = parser.parse_args() data = { 'a': 'A', 'b': 'B', 'long': 'word ' * 80, } mgr = extension.ExtensionManager( namespace='stevedore.example.formatter', invoke_on_load=True, invoke_args=(parsed_args.width,), ) def format_data(ext, data): return (ext.name, ext.obj.format(data)) results = mgr.map(format_data, data) for name, result in results: print('Formatter: {0}'.format(name)) for chunk in result: print(chunk, end='') print('') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/example/setup.py0000664000175000017500000000335400000000000020714 0ustar00zuulzuul00000000000000# Copyright (C) 2020 Red Hat, Inc. # # 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. from setuptools import find_packages from setuptools import setup setup( name='stevedore-examples', version='1.0', description='Demonstration package for stevedore', author='Doug Hellmann', author_email='doug@doughellmann.com', url='http://opendev.org/openstack/stevedore', classifiers=['Development Status :: 3 - Alpha', 'License :: OSI Approved :: Apache Software License', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.5', 'Intended Audience :: Developers', 'Environment :: Console', ], platforms=['Any'], scripts=[], provides=['stevedore.examples', ], packages=find_packages(), include_package_data=True, entry_points={ 'stevedore.example.formatter': [ 'simple = stevedore.example.simple:Simple', 'plain = stevedore.example.simple:Simple', ], }, zip_safe=False, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/example/simple.py0000664000175000017500000000213000000000000021034 0ustar00zuulzuul00000000000000# Copyright (C) 2020 Red Hat, Inc. # # 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. from stevedore.example import base class Simple(base.FormatterBase): """A very basic formatter.""" def format(self, data): """Format the data and return unicode text. :param data: A dictionary with string keys and simple types as values. :type data: dict(str:?) """ for name, value in sorted(data.items()): line = '{name} = {value}\n'.format( name=name, value=value, ) yield line ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8687553 stevedore-3.5.0/stevedore/example2/0000775000175000017500000000000000000000000017257 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/example2/__init__.py0000664000175000017500000000000000000000000021356 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/example2/fields.py0000664000175000017500000000301100000000000021072 0ustar00zuulzuul00000000000000# -*- coding: utf-8 -*- # Copyright (C) 2020 Red Hat, Inc. # # 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. import textwrap from stevedore.example import base class FieldList(base.FormatterBase): """Format values as a reStructuredText field list. For example:: : name1 : value : name2 : value : name3 : a long value will be wrapped with a hanging indent """ def format(self, data): """Format the data and return unicode text. :param data: A dictionary with string keys and simple types as values. :type data: dict(str:?) """ for name, value in sorted(data.items()): full_text = ': {name} : {value}'.format( name=name, value=value, ) wrapped_text = textwrap.fill( full_text, initial_indent='', subsequent_indent=' ', width=self.max_width, ) yield wrapped_text + '\n' ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/example2/setup.py0000664000175000017500000000327200000000000020775 0ustar00zuulzuul00000000000000# Copyright (C) 2020 Red Hat, Inc. # # 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. from setuptools import find_packages from setuptools import setup setup( name='stevedore-examples2', version='1.0', description='Demonstration package for stevedore', author='Doug Hellmann', author_email='doug@doughellmann.com', url='http://opendev.org/openstack/stevedore', classifiers=['Development Status :: 3 - Alpha', 'License :: OSI Approved :: Apache Software License', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.5', 'Intended Audience :: Developers', 'Environment :: Console', ], platforms=['Any'], scripts=[], provides=['stevedore.examples2', ], packages=find_packages(), include_package_data=True, entry_points={ 'stevedore.example.formatter': [ 'field = stevedore.example2.fields:FieldList', ], }, zip_safe=False, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/exception.py0000664000175000017500000000154000000000000020112 0ustar00zuulzuul00000000000000# 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. class NoUniqueMatch(RuntimeError): """There was more than one extension, or none, that matched the query.""" class NoMatches(NoUniqueMatch): """There were no extensions with the driver name found.""" class MultipleMatches(NoUniqueMatch): """There were multiple matches for the given name.""" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/extension.py0000664000175000017500000003355200000000000020140 0ustar00zuulzuul00000000000000# 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. """ExtensionManager """ import logging import operator from . import _cache from .exception import NoMatches LOG = logging.getLogger(__name__) class Extension(object): """Book-keeping object for tracking extensions. The arguments passed to the constructor are saved as attributes of the instance using the same names, and can be accessed by the callables passed to :meth:`map` or when iterating over an :class:`ExtensionManager` directly. :param name: The entry point name. :type name: str :param entry_point: The EntryPoint instance returned by :mod:`entrypoints`. :type entry_point: EntryPoint :param plugin: The value returned by entry_point.load() :param obj: The object returned by ``plugin(*args, **kwds)`` if the manager invoked the extension on load. """ def __init__(self, name, entry_point, plugin, obj): self.name = name self.entry_point = entry_point self.plugin = plugin self.obj = obj @property def module_name(self): """The name of the module from which the entry point is loaded. :return: A string in 'dotted.module' format. """ # NOTE: importlib_metadata from PyPI includes this but the # Python 3.8 standard library does not. match = self.entry_point.pattern.match(self.entry_point.value) return match.group('module') @property def extras(self): """The 'extras' settings for the plugin.""" # NOTE: The underlying package returns re.Match objects for # some reason. Translate those to the matched strings, which # seem more useful. return [ # Python 3.6 returns _sre.SRE_Match objects. Later # versions of python return re.Match objects. Both types # have a 'string' attribute containing the text that # matched the pattern. getattr(e, 'string', e) for e in self.entry_point.extras ] @property def attr(self): """The attribute of the module to be loaded.""" match = self.entry_point.pattern.match(self.entry_point.value) return match.group('attr') @property def entry_point_target(self): """The module and attribute referenced by this extension's entry_point. :return: A string representation of the target of the entry point in 'dotted.module:object' format. """ return self.entry_point.value class ExtensionManager(object): """Base class for all of the other managers. :param namespace: The namespace for the entry points. :type namespace: str :param invoke_on_load: Boolean controlling whether to invoke the object returned by the entry point after the driver is loaded. :type invoke_on_load: bool :param invoke_args: Positional arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_args: tuple :param invoke_kwds: Named arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_kwds: dict :param propagate_map_exceptions: Boolean controlling whether exceptions are propagated up through the map call or whether they are logged and then ignored :type propagate_map_exceptions: bool :param on_load_failure_callback: Callback function that will be called when an entrypoint can not be loaded. The arguments that will be provided when this is called (when an entrypoint fails to load) are (manager, entrypoint, exception) :type on_load_failure_callback: function :param verify_requirements: Use setuptools to enforce the dependencies of the plugin(s) being loaded. Defaults to False. :type verify_requirements: bool """ def __init__(self, namespace, invoke_on_load=False, invoke_args=(), invoke_kwds={}, propagate_map_exceptions=False, on_load_failure_callback=None, verify_requirements=False): self._init_attributes( namespace, propagate_map_exceptions=propagate_map_exceptions, on_load_failure_callback=on_load_failure_callback) extensions = self._load_plugins(invoke_on_load, invoke_args, invoke_kwds, verify_requirements) self._init_plugins(extensions) @classmethod def make_test_instance(cls, extensions, namespace='TESTING', propagate_map_exceptions=False, on_load_failure_callback=None, verify_requirements=False): """Construct a test ExtensionManager Test instances are passed a list of extensions to work from rather than loading them from entry points. :param extensions: Pre-configured Extension instances to use :type extensions: list of :class:`~stevedore.extension.Extension` :param namespace: The namespace for the manager; used only for identification since the extensions are passed in. :type namespace: str :param propagate_map_exceptions: When calling map, controls whether exceptions are propagated up through the map call or whether they are logged and then ignored :type propagate_map_exceptions: bool :param on_load_failure_callback: Callback function that will be called when an entrypoint can not be loaded. The arguments that will be provided when this is called (when an entrypoint fails to load) are (manager, entrypoint, exception) :type on_load_failure_callback: function :param verify_requirements: Use setuptools to enforce the dependencies of the plugin(s) being loaded. Defaults to False. :type verify_requirements: bool :return: The manager instance, initialized for testing """ o = cls.__new__(cls) o._init_attributes(namespace, propagate_map_exceptions=propagate_map_exceptions, on_load_failure_callback=on_load_failure_callback) o._init_plugins(extensions) return o def _init_attributes(self, namespace, propagate_map_exceptions=False, on_load_failure_callback=None): self.namespace = namespace self.propagate_map_exceptions = propagate_map_exceptions self._on_load_failure_callback = on_load_failure_callback def _init_plugins(self, extensions): self.extensions = extensions self._extensions_by_name_cache = None @property def _extensions_by_name(self): if self._extensions_by_name_cache is None: d = {} for e in self.extensions: d[e.name] = e self._extensions_by_name_cache = d return self._extensions_by_name_cache ENTRY_POINT_CACHE = {} def list_entry_points(self): """Return the list of entry points for this namespace. The entry points are not actually loaded, their list is just read and returned. """ if self.namespace not in self.ENTRY_POINT_CACHE: eps = list(_cache.get_group_all(self.namespace)) self.ENTRY_POINT_CACHE[self.namespace] = eps return self.ENTRY_POINT_CACHE[self.namespace] def entry_points_names(self): """Return the list of entry points names for this namespace.""" return list(map(operator.attrgetter("name"), self.list_entry_points())) def _load_plugins(self, invoke_on_load, invoke_args, invoke_kwds, verify_requirements): extensions = [] for ep in self.list_entry_points(): LOG.debug('found extension %r', ep) try: ext = self._load_one_plugin(ep, invoke_on_load, invoke_args, invoke_kwds, verify_requirements, ) if ext: extensions.append(ext) except (KeyboardInterrupt, AssertionError): raise except Exception as err: if self._on_load_failure_callback is not None: self._on_load_failure_callback(self, ep, err) else: # Log the reason we couldn't import the module, # usually without a traceback. The most common # reason is an ImportError due to a missing # dependency, and the error message should be # enough to debug that. If debug logging is # enabled for our logger, provide the full # traceback. LOG.error('Could not load %r: %s', ep.name, err, exc_info=LOG.isEnabledFor(logging.DEBUG)) return extensions def _load_one_plugin(self, ep, invoke_on_load, invoke_args, invoke_kwds, verify_requirements): # NOTE(dhellmann): Using require=False is deprecated in # setuptools 11.3. if hasattr(ep, 'resolve') and hasattr(ep, 'require'): if verify_requirements: ep.require() plugin = ep.resolve() else: plugin = ep.load() if invoke_on_load: obj = plugin(*invoke_args, **invoke_kwds) else: obj = None return Extension(ep.name, ep, plugin, obj) def names(self): "Returns the names of the discovered extensions" # We want to return the names of the extensions in the order # they would be used by map(), since some subclasses change # that order. return [e.name for e in self.extensions] def map(self, func, *args, **kwds): """Iterate over the extensions invoking func() for each. The signature for func() should be:: def func(ext, *args, **kwds): pass The first argument to func(), 'ext', is the :class:`~stevedore.extension.Extension` instance. Exceptions raised from within func() are propagated up and processing stopped if self.propagate_map_exceptions is True, otherwise they are logged and ignored. :param func: Callable to invoke for each extension. :param args: Variable arguments to pass to func() :param kwds: Keyword arguments to pass to func() :returns: List of values returned from func() """ if not self.extensions: # FIXME: Use a more specific exception class here. raise NoMatches('No %s extensions found' % self.namespace) response = [] for e in self.extensions: self._invoke_one_plugin(response.append, func, e, args, kwds) return response @staticmethod def _call_extension_method(extension, method_name, *args, **kwds): return getattr(extension.obj, method_name)(*args, **kwds) def map_method(self, method_name, *args, **kwds): """Iterate over the extensions invoking a method by name. This is equivalent of using :meth:`map` with func set to `lambda x: x.obj.method_name()` while being more convenient. Exceptions raised from within the called method are propagated up and processing stopped if self.propagate_map_exceptions is True, otherwise they are logged and ignored. .. versionadded:: 0.12 :param method_name: The extension method name to call for each extension. :param args: Variable arguments to pass to method :param kwds: Keyword arguments to pass to method :returns: List of values returned from methods """ return self.map(self._call_extension_method, method_name, *args, **kwds) def _invoke_one_plugin(self, response_callback, func, e, args, kwds): try: response_callback(func(e, *args, **kwds)) except Exception as err: if self.propagate_map_exceptions: raise else: LOG.error('error calling %r: %s', e.name, err) LOG.exception(err) def items(self): """Return an iterator of tuples of the form (name, extension). This is analogous to the Mapping.items() method. """ return self._extensions_by_name.items() def __iter__(self): """Produce iterator for the manager. Iterating over an ExtensionManager produces the :class:`Extension` instances in the order they would be invoked. """ return iter(self.extensions) def __getitem__(self, name): """Return the named extension. Accessing an ExtensionManager as a dictionary (``em['name']``) produces the :class:`Extension` instance with the specified name. """ return self._extensions_by_name[name] def __contains__(self, name): """Return true if name is in list of enabled extensions.""" return any(extension.name == name for extension in self.extensions) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/hook.py0000664000175000017500000000760500000000000017064 0ustar00zuulzuul00000000000000# 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. from .named import NamedExtensionManager class HookManager(NamedExtensionManager): """Coordinate execution of multiple extensions using a common name. :param namespace: The namespace for the entry points. :type namespace: str :param name: The name of the hooks to load. :type name: str :param invoke_on_load: Boolean controlling whether to invoke the object returned by the entry point after the driver is loaded. :type invoke_on_load: bool :param invoke_args: Positional arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_args: tuple :param invoke_kwds: Named arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_kwds: dict :param on_load_failure_callback: Callback function that will be called when an entrypoint can not be loaded. The arguments that will be provided when this is called (when an entrypoint fails to load) are (manager, entrypoint, exception) :type on_load_failure_callback: function :param verify_requirements: Use setuptools to enforce the dependencies of the plugin(s) being loaded. Defaults to False. :type verify_requirements: bool :type on_missing_entrypoints_callback: function :param warn_on_missing_entrypoint: Flag to control whether failing to load a plugin is reported via a log mess. Only applies if on_missing_entrypoints_callback is None. :type warn_on_missing_entrypoint: bool """ def __init__(self, namespace, name, invoke_on_load=False, invoke_args=(), invoke_kwds={}, on_load_failure_callback=None, verify_requirements=False, on_missing_entrypoints_callback=None, # NOTE(dhellmann): This default is different from the # base class because for hooks it is less likely to # be an error to have no entry points present. warn_on_missing_entrypoint=False): super(HookManager, self).__init__( namespace, [name], invoke_on_load=invoke_on_load, invoke_args=invoke_args, invoke_kwds=invoke_kwds, on_load_failure_callback=on_load_failure_callback, on_missing_entrypoints_callback=on_missing_entrypoints_callback, verify_requirements=verify_requirements, warn_on_missing_entrypoint=warn_on_missing_entrypoint, ) def _init_attributes(self, namespace, names, name_order=False, propagate_map_exceptions=False, on_load_failure_callback=None): super(HookManager, self)._init_attributes( namespace, names, propagate_map_exceptions=propagate_map_exceptions, on_load_failure_callback=on_load_failure_callback) self._name = names[0] def __getitem__(self, name): """Return the named extensions. Accessing a HookManager as a dictionary (``em['name']``) produces a list of the :class:`Extension` instance(s) with the specified name, in the order they would be invoked by map(). """ if name != self._name: raise KeyError(name) return self.extensions ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/named.py0000664000175000017500000001610200000000000017200 0ustar00zuulzuul00000000000000# 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. import logging from .extension import ExtensionManager LOG = logging.getLogger(__name__) class NamedExtensionManager(ExtensionManager): """Loads only the named extensions. This is useful for explicitly enabling extensions in a configuration file, for example. :param namespace: The namespace for the entry points. :type namespace: str :param names: The names of the extensions to load. :type names: list(str) :param invoke_on_load: Boolean controlling whether to invoke the object returned by the entry point after the driver is loaded. :type invoke_on_load: bool :param invoke_args: Positional arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_args: tuple :param invoke_kwds: Named arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_kwds: dict :param name_order: If true, sort the loaded extensions to match the order used in ``names``. :type name_order: bool :param propagate_map_exceptions: Boolean controlling whether exceptions are propagated up through the map call or whether they are logged and then ignored :type propagate_map_exceptions: bool :param on_load_failure_callback: Callback function that will be called when an entrypoint can not be loaded. The arguments that will be provided when this is called (when an entrypoint fails to load) are (manager, entrypoint, exception) :type on_load_failure_callback: function :param on_missing_entrypoints_callback: Callback function that will be called when one or more names cannot be found. The provided argument will be a subset of the 'names' parameter. :type on_missing_entrypoints_callback: function :param verify_requirements: Use setuptools to enforce the dependencies of the plugin(s) being loaded. Defaults to False. :type verify_requirements: bool :param warn_on_missing_entrypoint: Flag to control whether failing to load a plugin is reported via a log mess. Only applies if on_missing_entrypoints_callback is None. :type warn_on_missing_entrypoint: bool """ def __init__(self, namespace, names, invoke_on_load=False, invoke_args=(), invoke_kwds={}, name_order=False, propagate_map_exceptions=False, on_load_failure_callback=None, on_missing_entrypoints_callback=None, verify_requirements=False, warn_on_missing_entrypoint=True): self._init_attributes( namespace, names, name_order=name_order, propagate_map_exceptions=propagate_map_exceptions, on_load_failure_callback=on_load_failure_callback) extensions = self._load_plugins(invoke_on_load, invoke_args, invoke_kwds, verify_requirements) self._missing_names = set(names) - set([e.name for e in extensions]) if self._missing_names: if on_missing_entrypoints_callback: on_missing_entrypoints_callback(self._missing_names) elif warn_on_missing_entrypoint: LOG.warning('Could not load %s' % ', '.join(self._missing_names)) self._init_plugins(extensions) @classmethod def make_test_instance(cls, extensions, namespace='TESTING', propagate_map_exceptions=False, on_load_failure_callback=None, verify_requirements=False): """Construct a test NamedExtensionManager Test instances are passed a list of extensions to use rather than loading them from entry points. :param extensions: Pre-configured Extension instances :type extensions: list of :class:`~stevedore.extension.Extension` :param namespace: The namespace for the manager; used only for identification since the extensions are passed in. :type namespace: str :param propagate_map_exceptions: Boolean controlling whether exceptions are propagated up through the map call or whether they are logged and then ignored :type propagate_map_exceptions: bool :param on_load_failure_callback: Callback function that will be called when an entrypoint can not be loaded. The arguments that will be provided when this is called (when an entrypoint fails to load) are (manager, entrypoint, exception) :type on_load_failure_callback: function :param verify_requirements: Use setuptools to enforce the dependencies of the plugin(s) being loaded. Defaults to False. :type verify_requirements: bool :return: The manager instance, initialized for testing """ o = cls.__new__(cls) names = [e.name for e in extensions] o._init_attributes(namespace, names, propagate_map_exceptions=propagate_map_exceptions, on_load_failure_callback=on_load_failure_callback) o._init_plugins(extensions) return o def _init_attributes(self, namespace, names, name_order=False, propagate_map_exceptions=False, on_load_failure_callback=None): super(NamedExtensionManager, self)._init_attributes( namespace, propagate_map_exceptions=propagate_map_exceptions, on_load_failure_callback=on_load_failure_callback) self._names = names self._missing_names = set() self._name_order = name_order def _init_plugins(self, extensions): super(NamedExtensionManager, self)._init_plugins(extensions) if self._name_order: self.extensions = [self[n] for n in self._names if n not in self._missing_names] def _load_one_plugin(self, ep, invoke_on_load, invoke_args, invoke_kwds, verify_requirements): # Check the name before going any further to prevent # undesirable code from being loaded at all if we are not # going to use it. if ep.name not in self._names: return None return super(NamedExtensionManager, self)._load_one_plugin( ep, invoke_on_load, invoke_args, invoke_kwds, verify_requirements, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/sphinxext.py0000664000175000017500000000733600000000000020157 0ustar00zuulzuul00000000000000# 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. import inspect from docutils import nodes from docutils.parsers import rst from docutils.parsers.rst import directives from docutils.statemachine import ViewList from sphinx.util import logging from sphinx.util.nodes import nested_parse_with_titles from stevedore import extension LOG = logging.getLogger(__name__) def _get_docstring(plugin): return inspect.getdoc(plugin) or '' def _simple_list(mgr): for name in sorted(mgr.names()): ext = mgr[name] doc = _get_docstring(ext.plugin) or '\n' summary = doc.splitlines()[0].strip() yield('* %s -- %s' % (ext.name, summary), ext.module_name) def _detailed_list(mgr, over='', under='-', titlecase=False): for name in sorted(mgr.names()): ext = mgr[name] if over: yield (over * len(ext.name), ext.module_name) if titlecase: yield (ext.name.title(), ext.module_name) else: yield (ext.name, ext.module_name) if under: yield (under * len(ext.name), ext.module_name) yield ('\n', ext.module_name) doc = _get_docstring(ext.plugin) if doc: yield (doc, ext.module_name) else: yield ( '.. warning:: No documentation found for {} in {}'.format( ext.name, ext.entry_point_target, ), ext.module_name, ) yield ('\n', ext.module_name) class ListPluginsDirective(rst.Directive): """Present a simple list of the plugins in a namespace.""" option_spec = { 'class': directives.class_option, 'detailed': directives.flag, 'titlecase': directives.flag, 'overline-style': directives.single_char_or_unicode, 'underline-style': directives.single_char_or_unicode, } has_content = True def run(self): namespace = ' '.join(self.content).strip() LOG.info('documenting plugins from %r' % namespace) overline_style = self.options.get('overline-style', '') underline_style = self.options.get('underline-style', '=') def report_load_failure(mgr, ep, err): LOG.warning(u'Failed to load %s: %s' % (ep.module, err)) mgr = extension.ExtensionManager( namespace, on_load_failure_callback=report_load_failure, ) result = ViewList() titlecase = 'titlecase' in self.options if 'detailed' in self.options: data = _detailed_list( mgr, over=overline_style, under=underline_style, titlecase=titlecase) else: data = _simple_list(mgr) for text, source in data: for line in text.splitlines(): result.append(line, source) # Parse what we have into a new section. node = nodes.section() node.document = self.state.document nested_parse_with_titles(self.state, result, node) return node.children def setup(app): LOG.info('loading stevedore.sphinxext') app.add_directive('list-plugins', ListPluginsDirective) return { 'parallel_read_safe': True, 'parallel_write_safe': True, } ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8727553 stevedore-3.5.0/stevedore/tests/0000775000175000017500000000000000000000000016704 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/__init__.py0000664000175000017500000000000000000000000021003 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/extension_unimportable.py0000664000175000017500000000000000000000000024041 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/manager.py0000664000175000017500000000475200000000000020700 0ustar00zuulzuul00000000000000# 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. """TestExtensionManager Extension manager used only for testing. """ import warnings from stevedore import extension class TestExtensionManager(extension.ExtensionManager): """ExtensionManager that is explicitly initialized for tests. .. deprecated:: 0.13 Use the :func:`make_test_instance` class method of the class being replaced by the test instance instead of using this class directly. :param extensions: Pre-configured Extension instances to use instead of loading them from entry points. :type extensions: list of :class:`~stevedore.extension.Extension` :param namespace: The namespace for the entry points. :type namespace: str :param invoke_on_load: Boolean controlling whether to invoke the object returned by the entry point after the driver is loaded. :type invoke_on_load: bool :param invoke_args: Positional arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_args: tuple :param invoke_kwds: Named arguments to pass when invoking the object returned by the entry point. Only used if invoke_on_load is True. :type invoke_kwds: dict """ def __init__(self, extensions, namespace='test', invoke_on_load=False, invoke_args=(), invoke_kwds={}): super(TestExtensionManager, self).__init__(namespace, invoke_on_load, invoke_args, invoke_kwds, ) self.extensions = extensions warnings.warn( 'TestExtesionManager has been replaced by make_test_instance()', DeprecationWarning) def _load_plugins(self, *args, **kwds): return [] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/test_cache.py0000664000175000017500000000360200000000000021361 0ustar00zuulzuul00000000000000# 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. """Tests for stevedore._cache """ import sys from unittest import mock from stevedore import _cache from stevedore.tests import utils class TestCache(utils.TestCase): def test_disable_caching_executable(self): """Test caching is disabled if python interpreter is located under /tmp directory (Ansible) """ with mock.patch.object(sys, 'executable', '/tmp/fake'): sot = _cache.Cache() self.assertTrue(sot._disable_caching) def test_disable_caching_file(self): """Test caching is disabled if .disable file is present in target dir """ cache_dir = _cache._get_cache_dir() with mock.patch('os.path.isfile') as mock_path: mock_path.return_value = True sot = _cache.Cache() mock_path.assert_called_with('%s/.disable' % cache_dir) self.assertTrue(sot._disable_caching) mock_path.return_value = False sot = _cache.Cache() self.assertFalse(sot._disable_caching) @mock.patch('os.makedirs') @mock.patch('builtins.open') def test__get_data_for_path_no_write(self, mock_open, mock_mkdir): sot = _cache.Cache() sot._disable_caching = True mock_open.side_effect = IOError sot._get_data_for_path('fake') mock_mkdir.assert_not_called() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/test_callback.py0000664000175000017500000000415000000000000022051 0ustar00zuulzuul00000000000000# 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. """Tests for failure loading callback """ from unittest import mock from testtools.matchers import GreaterThan from stevedore import extension from stevedore import named from stevedore.tests import utils class TestCallback(utils.TestCase): def test_extension_failure_custom_callback(self): errors = [] def failure_callback(manager, entrypoint, error): errors.append((manager, entrypoint, error)) em = extension.ExtensionManager('stevedore.test.extension', invoke_on_load=True, on_load_failure_callback= failure_callback) extensions = list(em.extensions) self.assertTrue(len(extensions), GreaterThan(0)) self.assertEqual(len(errors), 2) for manager, entrypoint, error in errors: self.assertIs(manager, em) self.assertIsInstance(error, (IOError, ImportError)) @mock.patch('stevedore.named.NamedExtensionManager._load_plugins') def test_missing_entrypoints_callback(self, load_fn): errors = set() def callback(names): errors.update(names) load_fn.return_value = [ extension.Extension('foo', None, None, None) ] named.NamedExtensionManager('stevedore.test.extension', names=['foo', 'bar'], invoke_on_load=True, on_missing_entrypoints_callback=callback) self.assertEqual(errors, {'bar'}) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/test_dispatch.py0000664000175000017500000001006100000000000022112 0ustar00zuulzuul00000000000000# 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. from stevedore import dispatch from stevedore.tests import utils def check_dispatch(ep, *args, **kwds): return ep.name == 't2' class TestDispatch(utils.TestCase): def check_dispatch(ep, *args, **kwds): return ep.name == 't2' def test_dispatch(self): def invoke(ep, *args, **kwds): return (ep.name, args, kwds) em = dispatch.DispatchExtensionManager('stevedore.test.extension', lambda *args, **kwds: True, invoke_on_load=True, invoke_args=('a',), invoke_kwds={'b': 'B'}, ) self.assertEqual(len(em.extensions), 2) self.assertEqual(set(em.names()), set(['t1', 't2'])) results = em.map(check_dispatch, invoke, 'first', named='named value', ) expected = [('t2', ('first',), {'named': 'named value'})] self.assertEqual(results, expected) def test_dispatch_map_method(self): em = dispatch.DispatchExtensionManager('stevedore.test.extension', lambda *args, **kwds: True, invoke_on_load=True, invoke_args=('a',), invoke_kwds={'b': 'B'}, ) results = em.map_method(check_dispatch, 'get_args_and_data', 'first') self.assertEqual(results, [(('a',), {'b': 'B'}, 'first')]) def test_name_dispatch(self): def invoke(ep, *args, **kwds): return (ep.name, args, kwds) em = dispatch.NameDispatchExtensionManager('stevedore.test.extension', lambda *args, **kwds: True, invoke_on_load=True, invoke_args=('a',), invoke_kwds={'b': 'B'}, ) self.assertEqual(len(em.extensions), 2) self.assertEqual(set(em.names()), set(['t1', 't2'])) results = em.map(['t2'], invoke, 'first', named='named value',) expected = [('t2', ('first',), {'named': 'named value'})] self.assertEqual(results, expected) def test_name_dispatch_ignore_missing(self): def invoke(ep, *args, **kwds): return (ep.name, args, kwds) em = dispatch.NameDispatchExtensionManager( 'stevedore.test.extension', lambda *args, **kwds: True, invoke_on_load=True, invoke_args=('a',), invoke_kwds={'b': 'B'}, ) results = em.map(['t3', 't1'], invoke, 'first', named='named value',) expected = [('t1', ('first',), {'named': 'named value'})] self.assertEqual(results, expected) def test_name_dispatch_map_method(self): em = dispatch.NameDispatchExtensionManager( 'stevedore.test.extension', lambda *args, **kwds: True, invoke_on_load=True, invoke_args=('a',), invoke_kwds={'b': 'B'}, ) results = em.map_method(['t3', 't1'], 'get_args_and_data', 'first') self.assertEqual(results, [(('a',), {'b': 'B'}, 'first')]) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/test_driver.py0000664000175000017500000000655700000000000021625 0ustar00zuulzuul00000000000000# 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. """Tests for stevedore.extension """ try: # For python 3.8 and later import importlib.metadata as importlib_metadata except ImportError: # For everyone else import importlib_metadata from stevedore import driver from stevedore import exception from stevedore import extension from stevedore.tests import test_extension from stevedore.tests import utils class TestCallback(utils.TestCase): def test_detect_plugins(self): em = driver.DriverManager('stevedore.test.extension', 't1') names = sorted(em.names()) self.assertEqual(names, ['t1']) def test_call(self): def invoke(ext, *args, **kwds): return (ext.name, args, kwds) em = driver.DriverManager('stevedore.test.extension', 't1') result = em(invoke, 'a', b='C') self.assertEqual(result, ('t1', ('a',), {'b': 'C'})) def test_driver_property_not_invoked_on_load(self): em = driver.DriverManager('stevedore.test.extension', 't1', invoke_on_load=False) d = em.driver self.assertIs(d, test_extension.FauxExtension) def test_driver_property_invoked_on_load(self): em = driver.DriverManager('stevedore.test.extension', 't1', invoke_on_load=True) d = em.driver self.assertIsInstance(d, test_extension.FauxExtension) def test_no_drivers(self): try: driver.DriverManager('stevedore.test.extension.none', 't1') except exception.NoMatches as err: self.assertIn("No 'stevedore.test.extension.none' driver found", str(err)) def test_bad_driver(self): try: driver.DriverManager('stevedore.test.extension', 'e2') except ImportError: pass else: self.assertEqual(False, "No error raised") def test_multiple_drivers(self): # The idea for this test was contributed by clayg: # https://gist.github.com/clayg/6311348 extensions = [ extension.Extension( 'backend', importlib_metadata.EntryPoint( 'backend', 'pkg1:driver', 'backend'), 'pkg backend', None, ), extension.Extension( 'backend', importlib_metadata.EntryPoint( 'backend', 'pkg2:driver', 'backend'), 'pkg backend', None, ), ] try: dm = driver.DriverManager.make_test_instance(extensions[0]) # Call the initialization code that verifies the extension dm._init_plugins(extensions) except exception.MultipleMatches as err: self.assertIn("Multiple", str(err)) else: self.fail('Should have had an error') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/test_enabled.py0000664000175000017500000000274000000000000021712 0ustar00zuulzuul00000000000000# 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. from stevedore import enabled from stevedore.tests import utils class TestEnabled(utils.TestCase): def test_enabled(self): def check_enabled(ep): return ep.name == 't2' em = enabled.EnabledExtensionManager( 'stevedore.test.extension', check_enabled, invoke_on_load=True, invoke_args=('a',), invoke_kwds={'b': 'B'}, ) self.assertEqual(len(em.extensions), 1) self.assertEqual(em.names(), ['t2']) def test_enabled_after_load(self): def check_enabled(ext): return ext.obj and ext.name == 't2' em = enabled.EnabledExtensionManager( 'stevedore.test.extension', check_enabled, invoke_on_load=True, invoke_args=('a',), invoke_kwds={'b': 'B'}, ) self.assertEqual(len(em.extensions), 1) self.assertEqual(em.names(), ['t2']) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/test_example_fields.py0000664000175000017500000000250700000000000023302 0ustar00zuulzuul00000000000000# 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. """Tests for stevedore.example2.fields """ from stevedore.example2 import fields from stevedore.tests import utils class TestExampleFields(utils.TestCase): def test_simple_items(self): f = fields.FieldList(100) text = ''.join(f.format({'a': 'A', 'b': 'B'})) expected = '\n'.join([ ': a : A', ': b : B', '', ]) self.assertEqual(text, expected) def test_long_item(self): f = fields.FieldList(25) text = ''.join(f.format({'name': 'a value longer than the allowed width'})) expected = '\n'.join([ ': name : a value longer', ' than the allowed', ' width', '', ]) self.assertEqual(text, expected) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/test_example_simple.py0000664000175000017500000000171400000000000023324 0ustar00zuulzuul00000000000000# 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. """Tests for stevedore.example.simple """ from stevedore.example import simple from stevedore.tests import utils class TestExampleSimple(utils.TestCase): def test_simple_items(self): f = simple.Simple(100) text = ''.join(f.format({'a': 'A', 'b': 'B'})) expected = '\n'.join([ 'a = A', 'b = B', '', ]) self.assertEqual(text, expected) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/test_extension.py0000664000175000017500000002452200000000000022336 0ustar00zuulzuul00000000000000# 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. """Tests for stevedore.extension """ import operator from unittest import mock try: # For python 3.8 and later import importlib.metadata as importlib_metadata except ImportError: # For everyone else import importlib_metadata from stevedore import exception from stevedore import extension from stevedore.tests import utils ALL_NAMES = ['e1', 't1', 't2'] WORKING_NAMES = ['t1', 't2'] class FauxExtension(object): def __init__(self, *args, **kwds): self.args = args self.kwds = kwds def get_args_and_data(self, data): return self.args, self.kwds, data class BrokenExtension(object): def __init__(self, *args, **kwds): raise IOError("Did not create") class TestCallback(utils.TestCase): def test_detect_plugins(self): em = extension.ExtensionManager('stevedore.test.extension') names = sorted(em.names()) self.assertEqual(names, ALL_NAMES) def test_get_by_name(self): em = extension.ExtensionManager('stevedore.test.extension') e = em['t1'] self.assertEqual(e.name, 't1') def test_list_entry_points(self): em = extension.ExtensionManager('stevedore.test.extension') n = em.list_entry_points() self.assertEqual(set(['e1', 'e2', 't1', 't2']), set(map(operator.attrgetter("name"), n))) self.assertEqual(4, len(n)) def test_list_entry_points_names(self): em = extension.ExtensionManager('stevedore.test.extension') names = em.entry_points_names() self.assertEqual(set(['e1', 'e2', 't1', 't2']), set(names)) self.assertEqual(4, len(names)) def test_contains_by_name(self): em = extension.ExtensionManager('stevedore.test.extension') self.assertEqual('t1' in em, True) def test_get_by_name_missing(self): em = extension.ExtensionManager('stevedore.test.extension') try: em['t3'] except KeyError: pass else: assert False, 'Failed to raise KeyError' def test_load_multiple_times_entry_points(self): # We expect to get the same EntryPoint object because we save them # in the cache. em1 = extension.ExtensionManager('stevedore.test.extension') eps1 = [ext.entry_point for ext in em1] em2 = extension.ExtensionManager('stevedore.test.extension') eps2 = [ext.entry_point for ext in em2] self.assertIs(eps1[0], eps2[0]) def test_load_multiple_times_plugins(self): # We expect to get the same plugin object (module or class) # because the underlying import machinery will cache the values. em1 = extension.ExtensionManager('stevedore.test.extension') plugins1 = [ext.plugin for ext in em1] em2 = extension.ExtensionManager('stevedore.test.extension') plugins2 = [ext.plugin for ext in em2] self.assertIs(plugins1[0], plugins2[0]) def test_use_cache(self): # If we insert something into the cache of entry points, # the manager should not have to call into entrypoints # to find the plugins. cache = extension.ExtensionManager.ENTRY_POINT_CACHE cache['stevedore.test.faux'] = [] with mock.patch('stevedore._cache.get_group_all', side_effect= AssertionError('called get_group_all')): em = extension.ExtensionManager('stevedore.test.faux') names = em.names() self.assertEqual(names, []) def test_iterable(self): em = extension.ExtensionManager('stevedore.test.extension') names = sorted(e.name for e in em) self.assertEqual(names, ALL_NAMES) def test_invoke_on_load(self): em = extension.ExtensionManager('stevedore.test.extension', invoke_on_load=True, invoke_args=('a',), invoke_kwds={'b': 'B'}, ) self.assertEqual(len(em.extensions), 2) for e in em.extensions: self.assertEqual(e.obj.args, ('a',)) self.assertEqual(e.obj.kwds, {'b': 'B'}) def test_map_return_values(self): def mapped(ext, *args, **kwds): return ext.name em = extension.ExtensionManager('stevedore.test.extension', invoke_on_load=True, ) results = em.map(mapped) self.assertEqual(sorted(results), WORKING_NAMES) def test_map_arguments(self): objs = [] def mapped(ext, *args, **kwds): objs.append((ext, args, kwds)) em = extension.ExtensionManager('stevedore.test.extension', invoke_on_load=True, ) em.map(mapped, 1, 2, a='A', b='B') self.assertEqual(len(objs), 2) names = sorted([o[0].name for o in objs]) self.assertEqual(names, WORKING_NAMES) for o in objs: self.assertEqual(o[1], (1, 2)) self.assertEqual(o[2], {'a': 'A', 'b': 'B'}) def test_map_eats_errors(self): def mapped(ext, *args, **kwds): raise RuntimeError('hard coded error') em = extension.ExtensionManager('stevedore.test.extension', invoke_on_load=True, ) results = em.map(mapped, 1, 2, a='A', b='B') self.assertEqual(results, []) def test_map_propagate_exceptions(self): def mapped(ext, *args, **kwds): raise RuntimeError('hard coded error') em = extension.ExtensionManager('stevedore.test.extension', invoke_on_load=True, propagate_map_exceptions=True ) try: em.map(mapped, 1, 2, a='A', b='B') assert False except RuntimeError: pass def test_map_errors_when_no_plugins(self): expected_str = 'No stevedore.test.extension.none extensions found' def mapped(ext, *args, **kwds): pass em = extension.ExtensionManager('stevedore.test.extension.none', invoke_on_load=True, ) try: em.map(mapped, 1, 2, a='A', b='B') except exception.NoMatches as err: self.assertEqual(expected_str, str(err)) def test_map_method(self): em = extension.ExtensionManager('stevedore.test.extension', invoke_on_load=True, ) result = em.map_method('get_args_and_data', 42) self.assertEqual(set(r[2] for r in result), set([42])) def test_items(self): em = extension.ExtensionManager('stevedore.test.extension') expected_output = set([(name, em[name]) for name in ALL_NAMES]) self.assertEqual(expected_output, set(em.items())) class TestLoadRequirementsNewSetuptools(utils.TestCase): # setuptools 11.3 and later def setUp(self): super(TestLoadRequirementsNewSetuptools, self).setUp() self.mock_ep = mock.Mock(spec=['require', 'resolve', 'load', 'name']) self.em = extension.ExtensionManager.make_test_instance([]) def test_verify_requirements(self): self.em._load_one_plugin(self.mock_ep, False, (), {}, verify_requirements=True) self.mock_ep.require.assert_called_once_with() self.mock_ep.resolve.assert_called_once_with() def test_no_verify_requirements(self): self.em._load_one_plugin(self.mock_ep, False, (), {}, verify_requirements=False) self.assertEqual(0, self.mock_ep.require.call_count) self.mock_ep.resolve.assert_called_once_with() class TestLoadRequirementsOldSetuptools(utils.TestCase): # Before setuptools 11.3 def setUp(self): super(TestLoadRequirementsOldSetuptools, self).setUp() self.mock_ep = mock.Mock(spec=['load', 'name']) self.em = extension.ExtensionManager.make_test_instance([]) def test_verify_requirements(self): self.em._load_one_plugin(self.mock_ep, False, (), {}, verify_requirements=True) self.mock_ep.load.assert_called_once_with() def test_no_verify_requirements(self): self.em._load_one_plugin(self.mock_ep, False, (), {}, verify_requirements=False) self.mock_ep.load.assert_called_once_with() class TestExtensionProperties(utils.TestCase): def setUp(self): self.ext1 = extension.Extension( 'name', importlib_metadata.EntryPoint( 'name', 'module.name:attribute.name [extra]', 'group_name', ), mock.Mock(), None, ) self.ext2 = extension.Extension( 'name', importlib_metadata.EntryPoint( 'name', 'module:attribute', 'group_name', ), mock.Mock(), None, ) def test_module_name(self): self.assertEqual('module.name', self.ext1.module_name) self.assertEqual('module', self.ext2.module_name) def test_extras(self): self.assertEqual(['[extra]'], self.ext1.extras) self.assertEqual([], self.ext2.extras) def test_attr(self): self.assertEqual('attribute.name', self.ext1.attr) self.assertEqual('attribute', self.ext2.attr) def test_entry_point_target(self): self.assertEqual('module.name:attribute.name [extra]', self.ext1.entry_point_target) self.assertEqual('module:attribute', self.ext2.entry_point_target) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/test_hook.py0000664000175000017500000000326100000000000021257 0ustar00zuulzuul00000000000000# 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. from stevedore import hook from stevedore.tests import utils class TestHook(utils.TestCase): def test_hook(self): em = hook.HookManager( 'stevedore.test.extension', 't1', invoke_on_load=True, invoke_args=('a',), invoke_kwds={'b': 'B'}, ) self.assertEqual(len(em.extensions), 1) self.assertEqual(em.names(), ['t1']) def test_get_by_name(self): em = hook.HookManager( 'stevedore.test.extension', 't1', invoke_on_load=True, invoke_args=('a',), invoke_kwds={'b': 'B'}, ) e_list = em['t1'] self.assertEqual(len(e_list), 1) e = e_list[0] self.assertEqual(e.name, 't1') def test_get_by_name_missing(self): em = hook.HookManager( 'stevedore.test.extension', 't1', invoke_on_load=True, invoke_args=('a',), invoke_kwds={'b': 'B'}, ) try: em['t2'] except KeyError: pass else: assert False, 'Failed to raise KeyError' ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/test_named.py0000664000175000017500000000643400000000000021410 0ustar00zuulzuul00000000000000# 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. from unittest import mock from stevedore import named from stevedore.tests import utils class TestNamed(utils.TestCase): def test_named(self): em = named.NamedExtensionManager( 'stevedore.test.extension', names=['t1'], invoke_on_load=True, invoke_args=('a',), invoke_kwds={'b': 'B'}, ) actual = em.names() self.assertEqual(actual, ['t1']) def test_enabled_before_load(self): # Set up the constructor for the FauxExtension to cause an # AssertionError so the test fails if the class is instantiated, # which should only happen if it is loaded before the name of the # extension is compared against the names that should be loaded by # the manager. init_name = 'stevedore.tests.test_extension.FauxExtension.__init__' with mock.patch(init_name) as m: m.side_effect = AssertionError em = named.NamedExtensionManager( 'stevedore.test.extension', # Look for an extension that does not exist so the # __init__ we mocked should never be invoked. names=['no-such-extension'], invoke_on_load=True, invoke_args=('a',), invoke_kwds={'b': 'B'}, ) actual = em.names() self.assertEqual(actual, []) def test_extensions_listed_in_name_order(self): # Since we don't know the "natural" order of the extensions, run # the test both ways: if the sorting is broken, one of them will # fail em = named.NamedExtensionManager( 'stevedore.test.extension', names=['t1', 't2'], name_order=True ) actual = em.names() self.assertEqual(actual, ['t1', 't2']) em = named.NamedExtensionManager( 'stevedore.test.extension', names=['t2', 't1'], name_order=True ) actual = em.names() self.assertEqual(actual, ['t2', 't1']) def test_load_fail_ignored_when_sorted(self): em = named.NamedExtensionManager( 'stevedore.test.extension', names=['e1', 't2', 'e2', 't1'], name_order=True, invoke_on_load=True, invoke_args=('a',), invoke_kwds={'b': 'B'}, ) actual = em.names() self.assertEqual(['t2', 't1'], actual) em = named.NamedExtensionManager( 'stevedore.test.extension', names=['e1', 't1'], name_order=False, invoke_on_load=True, invoke_args=('a',), invoke_kwds={'b': 'B'}, ) actual = em.names() self.assertEqual(['t1'], actual) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/test_sphinxext.py0000664000175000017500000001001400000000000022343 0ustar00zuulzuul00000000000000# 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. """Tests for the sphinx extension """ try: # For python 3.8 and later import importlib.metadata as importlib_metadata except ImportError: # For everyone else import importlib_metadata from stevedore import extension from stevedore import sphinxext from stevedore.tests import utils def _make_ext(name, docstring): def inner(): pass inner.__doc__ = docstring m1 = importlib_metadata.EntryPoint( name, '{}_module:{}'.format(name, name), 'group', ) return extension.Extension(name, m1, inner, None) class TestSphinxExt(utils.TestCase): def setUp(self): super(TestSphinxExt, self).setUp() self.exts = [ _make_ext('test1', 'One-line docstring'), _make_ext('test2', 'Multi-line docstring\n\nAnother para'), ] self.em = extension.ExtensionManager.make_test_instance(self.exts) def test_simple_list(self): results = list(sphinxext._simple_list(self.em)) self.assertEqual( [ ('* test1 -- One-line docstring', 'test1_module'), ('* test2 -- Multi-line docstring', 'test2_module'), ], results, ) def test_simple_list_no_docstring(self): ext = [_make_ext('nodoc', None)] em = extension.ExtensionManager.make_test_instance(ext) results = list(sphinxext._simple_list(em)) self.assertEqual( [ ('* nodoc -- ', 'nodoc_module'), ], results, ) def test_detailed_list(self): results = list(sphinxext._detailed_list(self.em)) self.assertEqual( [ ('test1', 'test1_module'), ('-----', 'test1_module'), ('\n', 'test1_module'), ('One-line docstring', 'test1_module'), ('\n', 'test1_module'), ('test2', 'test2_module'), ('-----', 'test2_module'), ('\n', 'test2_module'), ('Multi-line docstring\n\nAnother para', 'test2_module'), ('\n', 'test2_module'), ], results, ) def test_detailed_list_format(self): results = list(sphinxext._detailed_list(self.em, over='+', under='+')) self.assertEqual( [ ('+++++', 'test1_module'), ('test1', 'test1_module'), ('+++++', 'test1_module'), ('\n', 'test1_module'), ('One-line docstring', 'test1_module'), ('\n', 'test1_module'), ('+++++', 'test2_module'), ('test2', 'test2_module'), ('+++++', 'test2_module'), ('\n', 'test2_module'), ('Multi-line docstring\n\nAnother para', 'test2_module'), ('\n', 'test2_module'), ], results, ) def test_detailed_list_no_docstring(self): ext = [_make_ext('nodoc', None)] em = extension.ExtensionManager.make_test_instance(ext) results = list(sphinxext._detailed_list(em)) self.assertEqual( [ ('nodoc', 'nodoc_module'), ('-----', 'nodoc_module'), ('\n', 'nodoc_module'), (('.. warning:: No documentation found for ' 'nodoc in nodoc_module:nodoc'), 'nodoc_module'), ('\n', 'nodoc_module'), ], results, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/test_test_manager.py0000664000175000017500000002253100000000000022771 0ustar00zuulzuul00000000000000# 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. from unittest.mock import Mock from unittest.mock import sentinel from stevedore.dispatch import DispatchExtensionManager from stevedore.dispatch import NameDispatchExtensionManager from stevedore.extension import Extension from stevedore.tests import utils from stevedore import DriverManager from stevedore import EnabledExtensionManager from stevedore import ExtensionManager from stevedore import HookManager from stevedore import NamedExtensionManager test_extension = Extension('test_extension', None, None, None) test_extension2 = Extension('another_one', None, None, None) mock_entry_point = Mock(module_name='test.extension', attrs=['obj']) a_driver = Extension('test_driver', mock_entry_point, sentinel.driver_plugin, sentinel.driver_obj) # base ExtensionManager class TestTestManager(utils.TestCase): def test_instance_should_use_supplied_extensions(self): extensions = [test_extension, test_extension2] em = ExtensionManager.make_test_instance(extensions) self.assertEqual(extensions, em.extensions) def test_instance_should_have_default_namespace(self): em = ExtensionManager.make_test_instance([]) self.assertEqual(em.namespace, 'TESTING') def test_instance_should_use_supplied_namespace(self): namespace = 'testing.1.2.3' em = ExtensionManager.make_test_instance([], namespace=namespace) self.assertEqual(namespace, em.namespace) def test_extension_name_should_be_listed(self): em = ExtensionManager.make_test_instance([test_extension]) self.assertIn(test_extension.name, em.names()) def test_iterator_should_yield_extension(self): em = ExtensionManager.make_test_instance([test_extension]) self.assertEqual(test_extension, next(iter(em))) def test_manager_should_allow_name_access(self): em = ExtensionManager.make_test_instance([test_extension]) self.assertEqual(test_extension, em[test_extension.name]) def test_manager_should_call(self): em = ExtensionManager.make_test_instance([test_extension]) func = Mock() em.map(func) func.assert_called_once_with(test_extension) def test_manager_should_call_all(self): em = ExtensionManager.make_test_instance([test_extension2, test_extension]) func = Mock() em.map(func) func.assert_any_call(test_extension2) func.assert_any_call(test_extension) def test_manager_return_values(self): def mapped(ext, *args, **kwds): return ext.name em = ExtensionManager.make_test_instance([test_extension2, test_extension]) results = em.map(mapped) self.assertEqual(sorted(results), ['another_one', 'test_extension']) def test_manager_should_eat_exceptions(self): em = ExtensionManager.make_test_instance([test_extension]) func = Mock(side_effect=RuntimeError('hard coded error')) results = em.map(func, 1, 2, a='A', b='B') self.assertEqual(results, []) def test_manager_should_propagate_exceptions(self): em = ExtensionManager.make_test_instance([test_extension], propagate_map_exceptions=True) self.skipTest('Skipping temporarily') func = Mock(side_effect=RuntimeError('hard coded error')) em.map(func, 1, 2, a='A', b='B') # NamedExtensionManager def test_named_manager_should_use_supplied_extensions(self): extensions = [test_extension, test_extension2] em = NamedExtensionManager.make_test_instance(extensions) self.assertEqual(extensions, em.extensions) def test_named_manager_should_have_default_namespace(self): em = NamedExtensionManager.make_test_instance([]) self.assertEqual(em.namespace, 'TESTING') def test_named_manager_should_use_supplied_namespace(self): namespace = 'testing.1.2.3' em = NamedExtensionManager.make_test_instance([], namespace=namespace) self.assertEqual(namespace, em.namespace) def test_named_manager_should_populate_names(self): extensions = [test_extension, test_extension2] em = NamedExtensionManager.make_test_instance(extensions) self.assertEqual(em.names(), ['test_extension', 'another_one']) # HookManager def test_hook_manager_should_use_supplied_extensions(self): extensions = [test_extension, test_extension2] em = HookManager.make_test_instance(extensions) self.assertEqual(extensions, em.extensions) def test_hook_manager_should_be_first_extension_name(self): extensions = [test_extension, test_extension2] em = HookManager.make_test_instance(extensions) # This will raise KeyError if the names don't match assert(em[test_extension.name]) def test_hook_manager_should_have_default_namespace(self): em = HookManager.make_test_instance([test_extension]) self.assertEqual(em.namespace, 'TESTING') def test_hook_manager_should_use_supplied_namespace(self): namespace = 'testing.1.2.3' em = HookManager.make_test_instance([test_extension], namespace=namespace) self.assertEqual(namespace, em.namespace) def test_hook_manager_should_return_named_extensions(self): hook1 = Extension('captain', None, None, None) hook2 = Extension('captain', None, None, None) em = HookManager.make_test_instance([hook1, hook2]) self.assertEqual([hook1, hook2], em['captain']) # DriverManager def test_driver_manager_should_use_supplied_extension(self): em = DriverManager.make_test_instance(a_driver) self.assertEqual([a_driver], em.extensions) def test_driver_manager_should_have_default_namespace(self): em = DriverManager.make_test_instance(a_driver) self.assertEqual(em.namespace, 'TESTING') def test_driver_manager_should_use_supplied_namespace(self): namespace = 'testing.1.2.3' em = DriverManager.make_test_instance(a_driver, namespace=namespace) self.assertEqual(namespace, em.namespace) def test_instance_should_use_driver_name(self): em = DriverManager.make_test_instance(a_driver) self.assertEqual(['test_driver'], em.names()) def test_instance_call(self): def invoke(ext, *args, **kwds): return ext.name, args, kwds em = DriverManager.make_test_instance(a_driver) result = em(invoke, 'a', b='C') self.assertEqual(result, ('test_driver', ('a',), {'b': 'C'})) def test_instance_driver_property(self): em = DriverManager.make_test_instance(a_driver) self.assertEqual(sentinel.driver_obj, em.driver) # EnabledExtensionManager def test_enabled_instance_should_use_supplied_extensions(self): extensions = [test_extension, test_extension2] em = EnabledExtensionManager.make_test_instance(extensions) self.assertEqual(extensions, em.extensions) # DispatchExtensionManager def test_dispatch_instance_should_use_supplied_extensions(self): extensions = [test_extension, test_extension2] em = DispatchExtensionManager.make_test_instance(extensions) self.assertEqual(extensions, em.extensions) def test_dispatch_map_should_invoke_filter_for_extensions(self): em = DispatchExtensionManager.make_test_instance([test_extension, test_extension2]) filter_func = Mock(return_value=False) args = ('A',) kw = {'big': 'Cheese'} em.map(filter_func, None, *args, **kw) filter_func.assert_any_call(test_extension, *args, **kw) filter_func.assert_any_call(test_extension2, *args, **kw) # NameDispatchExtensionManager def test_name_dispatch_instance_should_use_supplied_extensions(self): extensions = [test_extension, test_extension2] em = NameDispatchExtensionManager.make_test_instance(extensions) self.assertEqual(extensions, em.extensions) def test_name_dispatch_instance_should_build_extension_name_map(self): extensions = [test_extension, test_extension2] em = NameDispatchExtensionManager.make_test_instance(extensions) self.assertEqual(test_extension, em.by_name[test_extension.name]) self.assertEqual(test_extension2, em.by_name[test_extension2.name]) def test_named_dispatch_map_should_invoke_filter_for_extensions(self): em = NameDispatchExtensionManager.make_test_instance([test_extension, test_extension2]) func = Mock() args = ('A',) kw = {'BIGGER': 'Cheese'} em.map(['test_extension'], func, *args, **kw) func.assert_called_once_with(test_extension, *args, **kw) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/stevedore/tests/utils.py0000664000175000017500000000115100000000000020414 0ustar00zuulzuul00000000000000# 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. import unittest class TestCase(unittest.TestCase): pass ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1634550441.8687553 stevedore-3.5.0/stevedore.egg-info/0000775000175000017500000000000000000000000017234 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550441.0 stevedore-3.5.0/stevedore.egg-info/PKG-INFO0000664000175000017500000000446400000000000020341 0ustar00zuulzuul00000000000000Metadata-Version: 1.2 Name: stevedore Version: 3.5.0 Summary: Manage dynamic plugins for Python applications Home-page: https://docs.openstack.org/stevedore/latest/ Author: OpenStack Author-email: openstack-discuss@lists.openstack.org License: UNKNOWN Description: =========================================================== stevedore -- Manage dynamic plugins for Python applications =========================================================== .. image:: https://img.shields.io/pypi/v/stevedore.svg :target: https://pypi.org/project/stevedore/ :alt: Latest Version .. image:: https://governance.openstack.org/tc/badges/stevedore.svg :target: https://governance.openstack.org/tc/reference/tags/index.html Python makes loading code dynamically easy, allowing you to configure and extend your application by discovering and loading extensions ("*plugins*") at runtime. Many applications implement their own library for doing this, using ``__import__`` or ``importlib``. stevedore avoids creating yet another extension mechanism by building on top of `setuptools entry points`_. The code for managing entry points tends to be repetitive, though, so stevedore provides manager classes for implementing common patterns for using dynamically loaded extensions. .. _setuptools entry points: http://setuptools.readthedocs.io/en/latest/pkg_resources.html?#entry-points * Free software: Apache license * Documentation: https://docs.openstack.org/stevedore/latest * Source: https://opendev.org/openstack/stevedore * Bugs: https://bugs.launchpad.net/python-stevedore Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: License :: OSI Approved :: Apache Software License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 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: Intended Audience :: Developers Classifier: Environment :: Console Requires-Python: >=3.6 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550441.0 stevedore-3.5.0/stevedore.egg-info/SOURCES.txt0000664000175000017500000000615600000000000021130 0ustar00zuulzuul00000000000000.pre-commit-config.yaml .stestr.conf .zuul.yaml AUTHORS CONTRIBUTING.rst ChangeLog LICENSE README.rst bindep.txt requirements.txt setup.cfg setup.py test-requirements.txt tox.ini doc/Makefile doc/requirements.txt doc/source/conf.py doc/source/index.rst doc/source/install/index.rst doc/source/reference/index.rst doc/source/user/history.rst doc/source/user/index.rst doc/source/user/patterns_enabling.rst doc/source/user/patterns_loading.rst doc/source/user/sphinxext.rst doc/source/user/essays/api-enforcement.jpg doc/source/user/essays/ceilometer-design.jpg doc/source/user/essays/discovery.jpg doc/source/user/essays/enabling.jpg doc/source/user/essays/importing.jpg doc/source/user/essays/integration.jpg doc/source/user/essays/invocation.jpg doc/source/user/essays/pycon2013.rst doc/source/user/tutorial/creating_plugins.rst doc/source/user/tutorial/driver_output.txt doc/source/user/tutorial/extension_output.txt doc/source/user/tutorial/index.rst doc/source/user/tutorial/loading.rst doc/source/user/tutorial/naming.rst doc/source/user/tutorial/testing.rst releasenotes/notes/add-reno-996dd44974d53238.yaml releasenotes/notes/add-skip-caching-aa13be0299cc8b8c.yaml releasenotes/notes/drop-python2-support-3f0f717570cad8cb.yaml releasenotes/notes/entry-point-type-change-06ca3b301ba7aad1.yaml releasenotes/notes/expose-entry-point-properties-6f2d868d4342fc0d.yaml releasenotes/notes/module-name-property-d3b2d092259dadec.yaml releasenotes/source/conf.py releasenotes/source/index.rst releasenotes/source/ocata.rst releasenotes/source/pike.rst releasenotes/source/queens.rst releasenotes/source/rocky.rst releasenotes/source/stein.rst releasenotes/source/train.rst releasenotes/source/unreleased.rst releasenotes/source/ussuri.rst releasenotes/source/victoria.rst releasenotes/source/wallaby.rst releasenotes/source/xena.rst releasenotes/source/_static/.placeholder releasenotes/source/_templates/.placeholder stevedore/__init__.py stevedore/_cache.py stevedore/dispatch.py stevedore/driver.py stevedore/enabled.py stevedore/exception.py stevedore/extension.py stevedore/hook.py stevedore/named.py stevedore/sphinxext.py stevedore.egg-info/PKG-INFO stevedore.egg-info/SOURCES.txt stevedore.egg-info/dependency_links.txt stevedore.egg-info/entry_points.txt stevedore.egg-info/not-zip-safe stevedore.egg-info/pbr.json stevedore.egg-info/requires.txt stevedore.egg-info/top_level.txt stevedore/example/__init__.py stevedore/example/base.py stevedore/example/load_as_driver.py stevedore/example/load_as_extension.py stevedore/example/setup.py stevedore/example/simple.py stevedore/example2/__init__.py stevedore/example2/fields.py stevedore/example2/setup.py stevedore/tests/__init__.py stevedore/tests/extension_unimportable.py stevedore/tests/manager.py stevedore/tests/test_cache.py stevedore/tests/test_callback.py stevedore/tests/test_dispatch.py stevedore/tests/test_driver.py stevedore/tests/test_enabled.py stevedore/tests/test_example_fields.py stevedore/tests/test_example_simple.py stevedore/tests/test_extension.py stevedore/tests/test_hook.py stevedore/tests/test_named.py stevedore/tests/test_sphinxext.py stevedore/tests/test_test_manager.py stevedore/tests/utils.py././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550441.0 stevedore-3.5.0/stevedore.egg-info/dependency_links.txt0000664000175000017500000000000100000000000023302 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550441.0 stevedore-3.5.0/stevedore.egg-info/entry_points.txt0000664000175000017500000000060400000000000022532 0ustar00zuulzuul00000000000000[stevedore.example.formatter] field = stevedore.example2.fields:FieldList plain = stevedore.example.simple:Simple simple = stevedore.example.simple:Simple [stevedore.test.extension] e1 = stevedore.tests.test_extension:BrokenExtension e2 = stevedore.tests.notfound:UnimportableExtension t1 = stevedore.tests.test_extension:FauxExtension t2 = stevedore.tests.test_extension:FauxExtension ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550441.0 stevedore-3.5.0/stevedore.egg-info/not-zip-safe0000664000175000017500000000000100000000000021462 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550441.0 stevedore-3.5.0/stevedore.egg-info/pbr.json0000664000175000017500000000005600000000000020713 0ustar00zuulzuul00000000000000{"git_version": "442f157", "is_release": true}././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550441.0 stevedore-3.5.0/stevedore.egg-info/requires.txt0000664000175000017500000000011000000000000021624 0ustar00zuulzuul00000000000000pbr!=2.1.0,>=2.0.0 [:(python_version<'3.8')] importlib_metadata>=1.7.0 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550441.0 stevedore-3.5.0/stevedore.egg-info/top_level.txt0000664000175000017500000000001200000000000021757 0ustar00zuulzuul00000000000000stevedore ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/test-requirements.txt0000664000175000017500000000063200000000000020004 0ustar00zuulzuul00000000000000# The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. coverage!=4.4,>=4.0 # Apache-2.0 stestr>=2.0.0 # Apache-2.0 # sphinx is needed for testing the sphinxext module sphinx>=2.0.0,!=2.1.0 # BSD bandit>=1.6.0,<1.7.0 # Apache-2.0 pre-commit>=2.6.0 # MIT ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1634550395.0 stevedore-3.5.0/tox.ini0000664000175000017500000000311100000000000015051 0ustar00zuulzuul00000000000000[tox] minversion = 3.2 envlist = py3,pep8,docs ignore_basepython_conflict = true [testenv] basepython = python3 deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/test-requirements.txt -r{toxinidir}/requirements.txt commands = stestr run {posargs} [testenv:venv] deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/test-requirements.txt -r{toxinidir}/doc/requirements.txt -r{toxinidir}/requirements.txt commands = {posargs} [testenv:pep8] ignore = E251 commands = pre-commit run -a # Run security linter bandit -r stevedore -x tests -n5 [flake8] ignore = E251,H405 show-source = True exclude=.venv,.git,.tox,dist,*lib/python*,*egg,build [testenv:docs] deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/doc/requirements.txt commands = sphinx-build -a -E -W doc/source doc/build/html [testenv:releasenotes] deps = {[testenv:docs]deps} commands = sphinx-build -a -E -W releasenotes/source releasenotes/build/html [testenv:bindep] # Do not install any requirements. We want this to be fast and work even if # system dependencies are missing, since it's used to tell you what system # dependencies are missing! This also means that bindep must be installed # separately, outside of the requirements files, and develop mode disabled # explicitly to avoid unnecessarily installing the checked-out repo too (this # further relies on "tox.skipsdist = True" above). deps = bindep commands = bindep test usedevelop = False