From 5ab62cd904d4dc520134caaf597a659e81bf1967 Mon Sep 17 00:00:00 2001 From: Ahmed Aly Date: Tue, 28 Nov 2017 16:27:00 +0100 Subject: [PATCH] sst02 mit connector --- dev/odoo-server-dev-aa.conf | 9 + ext/3rd-party-addons/component/README.rst | 90 + ext/3rd-party-addons/component/__init__.py | 6 + .../component/__manifest__.py | 19 + ext/3rd-party-addons/component/builder.py | 107 + .../component/components/__init__.py | 2 + .../component/components/base.py | 15 + ext/3rd-party-addons/component/core.py | 857 +++++ ext/3rd-party-addons/component/exception.py | 15 + .../component/models/__init__.py | 3 + .../component/models/collection.py | 97 + .../component/tests/__init__.py | 6 + .../component/tests/common.py | 207 ++ .../component/tests/test_build_component.py | 272 ++ .../component/tests/test_component.py | 287 ++ .../component/tests/test_lookup.py | 194 ++ .../component/tests/test_work_on.py | 55 + .../component_event/README.rst | 106 + .../component_event/__init__.py | 7 + .../component_event/__manifest__.py | 19 + .../component_event/components/__init__.py | 2 + .../component_event/components/event.py | 294 ++ ext/3rd-party-addons/component_event/core.py | 153 + .../component_event/models/__init__.py | 2 + .../component_event/models/base.py | 111 + .../component_event/tests/__init__.py | 2 + .../component_event/tests/test_event.py | 432 +++ ext/3rd-party-addons/connector/AUTHORS | 24 + ext/3rd-party-addons/connector/CHANGES.rst | 201 ++ ext/3rd-party-addons/connector/README.rst | 86 + ext/3rd-party-addons/connector/__init__.py | 3 + .../connector/__manifest__.py | 25 + .../connector/components/__init__.py | 7 + .../connector/components/backend_adapter.py | 64 + .../connector/components/binder.py | 140 + .../connector/components/core.py | 130 + .../connector/components/listener.py | 50 + .../connector/components/mapper.py | 1011 ++++++ .../connector/components/synchronizer.py | 112 + ext/3rd-party-addons/connector/database.py | 79 + ext/3rd-party-addons/connector/doc/Makefile | 153 + .../connector/doc/_static/09_datamodel.png | Bin 0 -> 383631 bytes .../connector/doc/_static/connector_style.css | 4 + .../LogicSupply_Orange_260x80_transparent.png | Bin 0 -> 2451 bytes .../doc/_static/img/akretion_logo.png | Bin 0 -> 13203 bytes .../_static/img/c2c_square_baseline_192.jpg | Bin 0 -> 24535 bytes .../doc/_static/img/logo-debonix.jpg | Bin 0 -> 29079 bytes .../doc/_static/img/magentoerpconnect.png | Bin 0 -> 76283 bytes .../doc/_static/img/magentoerpconnect150.png | Bin 0 -> 18102 bytes .../doc/_static/img/prestashoperpconnect.png | Bin 0 -> 69453 bytes .../_static/img/prestashoperpconnect150.png | Bin 0 -> 15299 bytes .../connector/doc/_templates/layout.html | 14 + .../connector/doc/_templates/navbar.html | 31 + .../connector/doc/_themes/.gitignore | 3 + .../connector/doc/api/api_backend.rst | 26 + .../connector/doc/api/api_channels.rst | 14 + .../connector/doc/api/api_components.rst | 91 + .../connector/doc/api/api_event.rst | 37 + .../connector/doc/api/api_exception.rst | 8 + .../connector/doc/api/api_queue.rst | 28 + ext/3rd-party-addons/connector/doc/bazaar | 27 + ext/3rd-party-addons/connector/doc/conf.py | 381 +++ .../doc/guides/bootstrap_connector.rst | 153 + .../connector/doc/guides/code_overview.rst | 188 ++ .../connector/doc/guides/concepts.rst | 255 ++ .../connector/doc/guides/jobrunner.rst | 39 + .../connector/doc/guides/migration_guide.rst | 900 +++++ ext/3rd-party-addons/connector/doc/index.rst | 125 + .../doc/locale/fr/LC_MESSAGES/api.po | 2946 +++++++++++++++++ .../doc/locale/fr/LC_MESSAGES/guides.po | 1214 +++++++ .../doc/locale/fr/LC_MESSAGES/index.po | 281 ++ .../doc/locale/fr/LC_MESSAGES/project.po | 777 +++++ ext/3rd-party-addons/connector/doc/make.bat | 190 ++ .../connector/doc/project/changes.rst | 9 + .../connector/doc/project/contribute.rst | 100 + .../connector/doc/project/contributors.rst | 55 + .../connector/doc/project/license.rst | 674 ++++ .../connector/doc/project/roadmap.rst | 13 + ext/3rd-party-addons/connector/exception.py | 46 + ext/3rd-party-addons/connector/i18n/am.po | 317 ++ ext/3rd-party-addons/connector/i18n/ar.po | 317 ++ ext/3rd-party-addons/connector/i18n/ca.po | 317 ++ .../connector/i18n/connector.pot | 560 ++++ ext/3rd-party-addons/connector/i18n/cs.po | 317 ++ ext/3rd-party-addons/connector/i18n/de.po | 317 ++ ext/3rd-party-addons/connector/i18n/el_GR.po | 317 ++ ext/3rd-party-addons/connector/i18n/es.po | 317 ++ ext/3rd-party-addons/connector/i18n/es_CR.po | 317 ++ ext/3rd-party-addons/connector/i18n/es_EC.po | 317 ++ ext/3rd-party-addons/connector/i18n/es_ES.po | 317 ++ ext/3rd-party-addons/connector/i18n/es_MX.po | 317 ++ ext/3rd-party-addons/connector/i18n/es_VE.po | 317 ++ ext/3rd-party-addons/connector/i18n/et.po | 317 ++ ext/3rd-party-addons/connector/i18n/fi.po | 317 ++ ext/3rd-party-addons/connector/i18n/fr.po | 322 ++ ext/3rd-party-addons/connector/i18n/gl.po | 317 ++ ext/3rd-party-addons/connector/i18n/hr.po | 317 ++ ext/3rd-party-addons/connector/i18n/hr_HR.po | 317 ++ ext/3rd-party-addons/connector/i18n/hu.po | 317 ++ ext/3rd-party-addons/connector/i18n/it.po | 317 ++ ext/3rd-party-addons/connector/i18n/lt.po | 317 ++ ext/3rd-party-addons/connector/i18n/nl.po | 317 ++ ext/3rd-party-addons/connector/i18n/nl_BE.po | 317 ++ ext/3rd-party-addons/connector/i18n/pl.po | 317 ++ ext/3rd-party-addons/connector/i18n/pt.po | 317 ++ ext/3rd-party-addons/connector/i18n/pt_BR.po | 317 ++ ext/3rd-party-addons/connector/i18n/pt_PT.po | 317 ++ ext/3rd-party-addons/connector/i18n/ro.po | 317 ++ ext/3rd-party-addons/connector/i18n/ru.po | 317 ++ ext/3rd-party-addons/connector/i18n/sl.po | 317 ++ ext/3rd-party-addons/connector/i18n/th.po | 317 ++ ext/3rd-party-addons/connector/i18n/tr.po | 317 ++ ext/3rd-party-addons/connector/i18n/vi.po | 317 ++ ext/3rd-party-addons/connector/i18n/zh_CN.po | 317 ++ .../connector/models/__init__.py | 5 + .../connector/models/backend_model.py | 120 + .../connector/models/checkpoint.py | 174 + .../connector/models/queue_job.py | 52 + .../connector/models/setting.py | 12 + .../connector/security/connector_security.xml | 19 + .../connector/security/ir.model.access.csv | 2 + .../connector/static/description/icon.png | Bin 0 -> 9455 bytes .../connector/tests/__init__.py | 5 + .../connector/tests/test_advisory_lock.py | 75 + .../connector/tests/test_listener.py | 53 + .../connector/tests/test_mapper.py | 926 ++++++ .../connector/views/checkpoint_views.xml | 121 + .../connector/views/connector_menu.xml | 17 + .../connector/views/res_partner_views.xml | 18 + .../connector/views/setting_views.xml | 45 + ext/3rd-party-addons/queue_job/README.rst | 187 ++ ext/3rd-party-addons/queue_job/__init__.py | 5 + .../queue_job/__manifest__.py | 23 + .../queue_job/controllers/__init__.py | 1 + .../queue_job/controllers/main.py | 124 + .../queue_job/data/queue_data.xml | 33 + ext/3rd-party-addons/queue_job/exception.py | 48 + ext/3rd-party-addons/queue_job/fields.py | 73 + ext/3rd-party-addons/queue_job/job.py | 722 ++++ .../queue_job/jobrunner/__init__.py | 96 + .../queue_job/jobrunner/channels.py | 1059 ++++++ .../queue_job/jobrunner/runner.py | 406 +++ .../migrations/10.0.1.0.0/pre-migration.py | 29 + .../queue_job/models/__init__.py | 4 + ext/3rd-party-addons/queue_job/models/base.py | 71 + .../queue_job/models/queue_job.py | 357 ++ .../queue_job/security/ir.model.access.csv | 4 + .../queue_job/security/security.xml | 29 + .../queue_job/static/description/icon.png | Bin 0 -> 1803 bytes .../queue_job/static/description/icon.svg | 127 + .../queue_job/tests/__init__.py | 5 + .../queue_job/tests/common.py | 1 + .../queue_job/tests/test_json_field.py | 79 + .../queue_job/tests/test_runner_channels.py | 11 + .../queue_job/tests/test_runner_runner.py | 11 + .../queue_job/views/queue_job_views.xml | 290 ++ ext/custom-addons/dp_custom/models/product.py | 29 + .../dp_custom/models/res_partner.py | 45 +- .../dp_custom/views/res_partner_views.xml | 1 + 159 files changed, 30938 insertions(+), 2 deletions(-) create mode 100644 ext/3rd-party-addons/component/README.rst create mode 100644 ext/3rd-party-addons/component/__init__.py create mode 100644 ext/3rd-party-addons/component/__manifest__.py create mode 100644 ext/3rd-party-addons/component/builder.py create mode 100644 ext/3rd-party-addons/component/components/__init__.py create mode 100644 ext/3rd-party-addons/component/components/base.py create mode 100644 ext/3rd-party-addons/component/core.py create mode 100644 ext/3rd-party-addons/component/exception.py create mode 100644 ext/3rd-party-addons/component/models/__init__.py create mode 100644 ext/3rd-party-addons/component/models/collection.py create mode 100644 ext/3rd-party-addons/component/tests/__init__.py create mode 100644 ext/3rd-party-addons/component/tests/common.py create mode 100644 ext/3rd-party-addons/component/tests/test_build_component.py create mode 100644 ext/3rd-party-addons/component/tests/test_component.py create mode 100644 ext/3rd-party-addons/component/tests/test_lookup.py create mode 100644 ext/3rd-party-addons/component/tests/test_work_on.py create mode 100644 ext/3rd-party-addons/component_event/README.rst create mode 100644 ext/3rd-party-addons/component_event/__init__.py create mode 100644 ext/3rd-party-addons/component_event/__manifest__.py create mode 100644 ext/3rd-party-addons/component_event/components/__init__.py create mode 100644 ext/3rd-party-addons/component_event/components/event.py create mode 100644 ext/3rd-party-addons/component_event/core.py create mode 100644 ext/3rd-party-addons/component_event/models/__init__.py create mode 100644 ext/3rd-party-addons/component_event/models/base.py create mode 100644 ext/3rd-party-addons/component_event/tests/__init__.py create mode 100644 ext/3rd-party-addons/component_event/tests/test_event.py create mode 100644 ext/3rd-party-addons/connector/AUTHORS create mode 100644 ext/3rd-party-addons/connector/CHANGES.rst create mode 100644 ext/3rd-party-addons/connector/README.rst create mode 100644 ext/3rd-party-addons/connector/__init__.py create mode 100644 ext/3rd-party-addons/connector/__manifest__.py create mode 100644 ext/3rd-party-addons/connector/components/__init__.py create mode 100644 ext/3rd-party-addons/connector/components/backend_adapter.py create mode 100644 ext/3rd-party-addons/connector/components/binder.py create mode 100644 ext/3rd-party-addons/connector/components/core.py create mode 100644 ext/3rd-party-addons/connector/components/listener.py create mode 100644 ext/3rd-party-addons/connector/components/mapper.py create mode 100644 ext/3rd-party-addons/connector/components/synchronizer.py create mode 100644 ext/3rd-party-addons/connector/database.py create mode 100644 ext/3rd-party-addons/connector/doc/Makefile create mode 100644 ext/3rd-party-addons/connector/doc/_static/09_datamodel.png create mode 100644 ext/3rd-party-addons/connector/doc/_static/connector_style.css create mode 100644 ext/3rd-party-addons/connector/doc/_static/img/LogicSupply_Orange_260x80_transparent.png create mode 100644 ext/3rd-party-addons/connector/doc/_static/img/akretion_logo.png create mode 100644 ext/3rd-party-addons/connector/doc/_static/img/c2c_square_baseline_192.jpg create mode 100644 ext/3rd-party-addons/connector/doc/_static/img/logo-debonix.jpg create mode 100644 ext/3rd-party-addons/connector/doc/_static/img/magentoerpconnect.png create mode 100644 ext/3rd-party-addons/connector/doc/_static/img/magentoerpconnect150.png create mode 100644 ext/3rd-party-addons/connector/doc/_static/img/prestashoperpconnect.png create mode 100644 ext/3rd-party-addons/connector/doc/_static/img/prestashoperpconnect150.png create mode 100644 ext/3rd-party-addons/connector/doc/_templates/layout.html create mode 100644 ext/3rd-party-addons/connector/doc/_templates/navbar.html create mode 100644 ext/3rd-party-addons/connector/doc/_themes/.gitignore create mode 100644 ext/3rd-party-addons/connector/doc/api/api_backend.rst create mode 100644 ext/3rd-party-addons/connector/doc/api/api_channels.rst create mode 100644 ext/3rd-party-addons/connector/doc/api/api_components.rst create mode 100644 ext/3rd-party-addons/connector/doc/api/api_event.rst create mode 100644 ext/3rd-party-addons/connector/doc/api/api_exception.rst create mode 100644 ext/3rd-party-addons/connector/doc/api/api_queue.rst create mode 100644 ext/3rd-party-addons/connector/doc/bazaar create mode 100644 ext/3rd-party-addons/connector/doc/conf.py create mode 100644 ext/3rd-party-addons/connector/doc/guides/bootstrap_connector.rst create mode 100644 ext/3rd-party-addons/connector/doc/guides/code_overview.rst create mode 100644 ext/3rd-party-addons/connector/doc/guides/concepts.rst create mode 100644 ext/3rd-party-addons/connector/doc/guides/jobrunner.rst create mode 100644 ext/3rd-party-addons/connector/doc/guides/migration_guide.rst create mode 100644 ext/3rd-party-addons/connector/doc/index.rst create mode 100644 ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/api.po create mode 100644 ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/guides.po create mode 100644 ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/index.po create mode 100644 ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/project.po create mode 100644 ext/3rd-party-addons/connector/doc/make.bat create mode 100644 ext/3rd-party-addons/connector/doc/project/changes.rst create mode 100644 ext/3rd-party-addons/connector/doc/project/contribute.rst create mode 100644 ext/3rd-party-addons/connector/doc/project/contributors.rst create mode 100644 ext/3rd-party-addons/connector/doc/project/license.rst create mode 100644 ext/3rd-party-addons/connector/doc/project/roadmap.rst create mode 100644 ext/3rd-party-addons/connector/exception.py create mode 100644 ext/3rd-party-addons/connector/i18n/am.po create mode 100644 ext/3rd-party-addons/connector/i18n/ar.po create mode 100644 ext/3rd-party-addons/connector/i18n/ca.po create mode 100644 ext/3rd-party-addons/connector/i18n/connector.pot create mode 100644 ext/3rd-party-addons/connector/i18n/cs.po create mode 100644 ext/3rd-party-addons/connector/i18n/de.po create mode 100644 ext/3rd-party-addons/connector/i18n/el_GR.po create mode 100644 ext/3rd-party-addons/connector/i18n/es.po create mode 100644 ext/3rd-party-addons/connector/i18n/es_CR.po create mode 100644 ext/3rd-party-addons/connector/i18n/es_EC.po create mode 100644 ext/3rd-party-addons/connector/i18n/es_ES.po create mode 100644 ext/3rd-party-addons/connector/i18n/es_MX.po create mode 100644 ext/3rd-party-addons/connector/i18n/es_VE.po create mode 100644 ext/3rd-party-addons/connector/i18n/et.po create mode 100644 ext/3rd-party-addons/connector/i18n/fi.po create mode 100644 ext/3rd-party-addons/connector/i18n/fr.po create mode 100644 ext/3rd-party-addons/connector/i18n/gl.po create mode 100644 ext/3rd-party-addons/connector/i18n/hr.po create mode 100644 ext/3rd-party-addons/connector/i18n/hr_HR.po create mode 100644 ext/3rd-party-addons/connector/i18n/hu.po create mode 100644 ext/3rd-party-addons/connector/i18n/it.po create mode 100644 ext/3rd-party-addons/connector/i18n/lt.po create mode 100644 ext/3rd-party-addons/connector/i18n/nl.po create mode 100644 ext/3rd-party-addons/connector/i18n/nl_BE.po create mode 100644 ext/3rd-party-addons/connector/i18n/pl.po create mode 100644 ext/3rd-party-addons/connector/i18n/pt.po create mode 100644 ext/3rd-party-addons/connector/i18n/pt_BR.po create mode 100644 ext/3rd-party-addons/connector/i18n/pt_PT.po create mode 100644 ext/3rd-party-addons/connector/i18n/ro.po create mode 100644 ext/3rd-party-addons/connector/i18n/ru.po create mode 100644 ext/3rd-party-addons/connector/i18n/sl.po create mode 100644 ext/3rd-party-addons/connector/i18n/th.po create mode 100644 ext/3rd-party-addons/connector/i18n/tr.po create mode 100644 ext/3rd-party-addons/connector/i18n/vi.po create mode 100644 ext/3rd-party-addons/connector/i18n/zh_CN.po create mode 100644 ext/3rd-party-addons/connector/models/__init__.py create mode 100644 ext/3rd-party-addons/connector/models/backend_model.py create mode 100644 ext/3rd-party-addons/connector/models/checkpoint.py create mode 100644 ext/3rd-party-addons/connector/models/queue_job.py create mode 100644 ext/3rd-party-addons/connector/models/setting.py create mode 100644 ext/3rd-party-addons/connector/security/connector_security.xml create mode 100644 ext/3rd-party-addons/connector/security/ir.model.access.csv create mode 100644 ext/3rd-party-addons/connector/static/description/icon.png create mode 100644 ext/3rd-party-addons/connector/tests/__init__.py create mode 100644 ext/3rd-party-addons/connector/tests/test_advisory_lock.py create mode 100644 ext/3rd-party-addons/connector/tests/test_listener.py create mode 100644 ext/3rd-party-addons/connector/tests/test_mapper.py create mode 100644 ext/3rd-party-addons/connector/views/checkpoint_views.xml create mode 100644 ext/3rd-party-addons/connector/views/connector_menu.xml create mode 100644 ext/3rd-party-addons/connector/views/res_partner_views.xml create mode 100644 ext/3rd-party-addons/connector/views/setting_views.xml create mode 100644 ext/3rd-party-addons/queue_job/README.rst create mode 100644 ext/3rd-party-addons/queue_job/__init__.py create mode 100644 ext/3rd-party-addons/queue_job/__manifest__.py create mode 100644 ext/3rd-party-addons/queue_job/controllers/__init__.py create mode 100644 ext/3rd-party-addons/queue_job/controllers/main.py create mode 100644 ext/3rd-party-addons/queue_job/data/queue_data.xml create mode 100644 ext/3rd-party-addons/queue_job/exception.py create mode 100644 ext/3rd-party-addons/queue_job/fields.py create mode 100644 ext/3rd-party-addons/queue_job/job.py create mode 100644 ext/3rd-party-addons/queue_job/jobrunner/__init__.py create mode 100644 ext/3rd-party-addons/queue_job/jobrunner/channels.py create mode 100644 ext/3rd-party-addons/queue_job/jobrunner/runner.py create mode 100644 ext/3rd-party-addons/queue_job/migrations/10.0.1.0.0/pre-migration.py create mode 100644 ext/3rd-party-addons/queue_job/models/__init__.py create mode 100644 ext/3rd-party-addons/queue_job/models/base.py create mode 100644 ext/3rd-party-addons/queue_job/models/queue_job.py create mode 100644 ext/3rd-party-addons/queue_job/security/ir.model.access.csv create mode 100644 ext/3rd-party-addons/queue_job/security/security.xml create mode 100644 ext/3rd-party-addons/queue_job/static/description/icon.png create mode 100644 ext/3rd-party-addons/queue_job/static/description/icon.svg create mode 100644 ext/3rd-party-addons/queue_job/tests/__init__.py create mode 100644 ext/3rd-party-addons/queue_job/tests/common.py create mode 100644 ext/3rd-party-addons/queue_job/tests/test_json_field.py create mode 100644 ext/3rd-party-addons/queue_job/tests/test_runner_channels.py create mode 100644 ext/3rd-party-addons/queue_job/tests/test_runner_runner.py create mode 100644 ext/3rd-party-addons/queue_job/views/queue_job_views.xml diff --git a/dev/odoo-server-dev-aa.conf b/dev/odoo-server-dev-aa.conf index a9bf5a9a..ad8880a1 100644 --- a/dev/odoo-server-dev-aa.conf +++ b/dev/odoo-server-dev-aa.conf @@ -15,3 +15,12 @@ timezone = Europe/Vienna #dbfilter_test = ['.*',] show_debug = 1 + +workers = 0 +server_wide_modules = web,base_sparse_field,queue_job + +portal_url = https://erp.tzaustria.info +portal_secret = secret + +[queue_job] +channels = root:4 diff --git a/ext/3rd-party-addons/component/README.rst b/ext/3rd-party-addons/component/README.rst new file mode 100644 index 00000000..9a6a4088 --- /dev/null +++ b/ext/3rd-party-addons/component/README.rst @@ -0,0 +1,90 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl + :alt: License: AGPL-3 + +========== +Components +========== + +This module implements a component system and is a base block for the Connector +Framework. It can be used without using the full Connector though. + +Documentation: http://odoo-connector.com/ + +Installation +============ + +* Install ``component`` + +Configuration +============= + +The module does nothing by itself and has no configuration. + +Usage +===== + +As a developer, you have access to a component system. You can find the +documentation in the code or on http://odoo-connector.com + +In a nutshell, you can create components:: + + + from odoo.addons.component.core import Component + + class MagentoPartnerAdapter(Component): + _name = 'magento.partner.adapter' + _inherit = 'magento.adapter' + + _usage = 'backend.adapter' + _collection = 'magento.backend' + _apply_on = ['res.partner'] + +And later, find the component you need at runtime (dynamic dispatch at +component level):: + + def run(self, external_id): + backend_adapter = self.component(usage='backend.adapter') + external_data = backend_adapter.read(external_id) + + +Known issues / Roadmap +====================== + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smash it by providing detailed and welcomed feedback. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Guewen Baconnier + +Do not contact contributors directly about support or help with technical issues. + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/ext/3rd-party-addons/component/__init__.py b/ext/3rd-party-addons/component/__init__.py new file mode 100644 index 00000000..afa4a292 --- /dev/null +++ b/ext/3rd-party-addons/component/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from . import core + +from . import components +from . import builder +from . import models diff --git a/ext/3rd-party-addons/component/__manifest__.py b/ext/3rd-party-addons/component/__manifest__.py new file mode 100644 index 00000000..5601832a --- /dev/null +++ b/ext/3rd-party-addons/component/__manifest__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +{'name': 'Components', + 'version': '11.0.1.0.0', + 'author': 'Camptocamp,' + 'Odoo Community Association (OCA)', + 'website': 'https://www.camptocamp.com', + 'license': 'AGPL-3', + 'category': 'Generic Modules', + 'depends': ['base', + ], + 'external_dependencies': { + 'python': ['cachetools'], + }, + 'data': [], + 'installable': True, + } diff --git a/ext/3rd-party-addons/component/builder.py b/ext/3rd-party-addons/component/builder.py new file mode 100644 index 00000000..7e537755 --- /dev/null +++ b/ext/3rd-party-addons/component/builder.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" + +Components Builder +================== + +Build the components at the build of a registry. + +""" +import odoo +from odoo import api, models +from .core import ( + _component_databases, + ComponentRegistry, + DEFAULT_CACHE_SIZE, +) + + +class ComponentBuilder(models.AbstractModel): + """ Build the component classes + + And register them in a global registry. + + Every time an Odoo registry is built, the know components are cleared and + rebuilt as well. The Component classes are built using the same mechanism + than Odoo's Models: a final class is created, taking every Components with + a ``_name`` and applying Components with an ``_inherits`` upon them. + + The final Component classes are registered in global registry. + + This class is an Odoo model, allowing us to hook the build of the + components at the end of the Odoo's registry loading, using + ``_register_hook``. This method is called after all modules are loaded, so + we are sure that we have all the components Classes and in the correct + order. + + """ + _name = 'component.builder' + _description = 'Component Builder' + + _components_registry_cache_size = DEFAULT_CACHE_SIZE + + @api.model_cr + def _register_hook(self): + # This method is called by Odoo when the registry is built, + # so in case the registry is rebuilt (cache invalidation, ...), + # we have to to rebuild the components. We use a new + # registry so we have an empty cache and we'll add components in it. + components_registry = self._init_global_registry() + self.build_registry(components_registry) + components_registry.ready = True + + def _init_global_registry(self): + components_registry = ComponentRegistry( + cachesize=self._components_registry_cache_size + ) + _component_databases[self.env.cr.dbname] = components_registry + return components_registry + + def build_registry(self, components_registry, states=None, + exclude_addons=None): + if not states: + states = ('installed', 'to upgrade') + # lookup all the installed (or about to be) addons and generate + # the graph, so we can load the components following the order + # of the addons' dependencies + graph = odoo.modules.graph.Graph() + graph.add_module(self.env.cr, 'base') + + query = ( + "SELECT name " + "FROM ir_module_module " + "WHERE state IN %s " + ) + params = [tuple(states)] + if exclude_addons: + query += " AND name NOT IN %s " + params.append(tuple(exclude_addons)) + self.env.cr.execute(query, params) + + module_list = [name for (name,) in self.env.cr.fetchall() + if name not in graph] + graph.add_modules(self.env.cr, module_list) + + for module in graph: + self.load_components(module.name, + components_registry=components_registry) + + def load_components(self, module, components_registry=None): + """ Build every component known by MetaComponent for an odoo module + + The final component (composed by all the Component classes in this + module) will be pushed into the registry. + + :param module: the name of the addon for which we want to load + the components + :type module: str | unicode + :param registry: the registry in which we want to put the Component + :type registry: :py:class:`~.core.ComponentRegistry` + """ + components_registry = ( + components_registry or + _component_databases[self.env.cr.dbname]) + components_registry.load_components(module) diff --git a/ext/3rd-party-addons/component/components/__init__.py b/ext/3rd-party-addons/component/components/__init__.py new file mode 100644 index 00000000..a61d43eb --- /dev/null +++ b/ext/3rd-party-addons/component/components/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import base diff --git a/ext/3rd-party-addons/component/components/base.py b/ext/3rd-party-addons/component/components/base.py new file mode 100644 index 00000000..081b6a15 --- /dev/null +++ b/ext/3rd-party-addons/component/components/base.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from ..core import AbstractComponent + + +class BaseComponent(AbstractComponent): + """ This is the base component for every component + + It is implicitely inherited by all components. + + All your base are belong to us + """ + _name = 'base' diff --git a/ext/3rd-party-addons/component/core.py b/ext/3rd-party-addons/component/core.py new file mode 100644 index 00000000..87761a93 --- /dev/null +++ b/ext/3rd-party-addons/component/core.py @@ -0,0 +1,857 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# Copyright 2017 Odoo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" + +Core +==== + +Core classes for the components. +The most common classes used publicly are: + +* :class:`Component` +* :class:`AbstractComponent` +* :class:`WorkContext` + +""" + +import logging +import operator + +from collections import defaultdict, OrderedDict + +from odoo import models +from odoo.tools import OrderedSet, LastOrderedSet +from .exception import NoComponentError, SeveralComponentError + + +_logger = logging.getLogger(__name__) + +try: + from cachetools import LRUCache, cachedmethod +except ImportError: + _logger.debug("Cannot import 'cachetools'.") + + +# The Cache size represents the number of items, so the number +# of components (include abstract components) we will keep in the LRU +# cache. We would need stats to know what is the average but this is a bit +# early. +DEFAULT_CACHE_SIZE = 512 + + +# this is duplicated from odoo.models.MetaModel._get_addon_name() which we +# unfortunately can't use because it's an instance method and should have been +# a @staticmethod +def _get_addon_name(full_name): + # The (Odoo) module name can be in the ``odoo.addons`` namespace + # or not. For instance, module ``sale`` can be imported as + # ``odoo.addons.sale`` (the right way) or ``sale`` (for backward + # compatibility). + module_parts = full_name.split('.') + if len(module_parts) > 2 and module_parts[:2] == ['odoo', 'addons']: + addon_name = full_name.split('.')[2] + else: + addon_name = full_name.split('.')[0] + return addon_name + + +class ComponentDatabases(dict): + """ Holds a registry of components for each database """ + + +class ComponentRegistry(object): + """ Store all the components and allow to find them using criteria + + The key is the ``_name`` of the components. + + This is an OrderedDict, because we want to keep the registration order of + the components, addons loaded first have their components found first. + + The :attr:`ready` attribute must be set to ``True`` when all the components + are loaded. + + """ + + def __init__(self, cachesize=DEFAULT_CACHE_SIZE): + self._cache = LRUCache(maxsize=cachesize) + self._components = OrderedDict() + self._loaded_modules = set() + self.ready = False + + def __getitem__(self, key): + return self._components[key] + + def __setitem__(self, key, value): + self._components[key] = value + + def __contains__(self, key): + return key in self._components + + def get(self, key, default=None): + return self._components.get(key, default) + + def __iter__(self): + return iter(self._components) + + def load_components(self, module): + if module in self._loaded_modules: + return + for component_class in MetaComponent._modules_components[module]: + component_class._build_component(self) + self._loaded_modules.add(module) + + @cachedmethod(operator.attrgetter('_cache')) + def lookup(self, collection_name=None, usage=None, model_name=None): + """ Find and return a list of components for a usage + + If a component is not registered in a particular collection (no + ``_collection``), it might will be returned in any case (as far as + the ``usage`` and ``model_name`` match). This is useful to share + generic components across different collections. + + If no collection name is given, components from any collection + will be returned. + + Then, the components of a collection are filtered by usage and/or + model. The ``_usage`` is mandatory on the components. When the + ``_model_name`` is empty, it means it can be used for every models, + and it will ignore the ``model_name`` argument. + + The abstract components are never returned. + + This is a rather low-level function, usually you will use the + high-level :meth:`AbstractComponent.component`, + :meth:`AbstractComponent.many_components` or even + :meth:`AbstractComponent.component_by_name`. + + :param collection_name: the name of the collection the component is + registered into. + :param usage: the usage of component we are looking for + :param model_name: filter on components that apply on this model + + """ + + # keep the order so addons loaded first have components used first + candidates = ( + component for component in self._components.values() + if not component._abstract + ) + + if collection_name is not None: + candidates = ( + component for component in candidates + if (component._collection == collection_name or + component._collection is None) + ) + + if usage is not None: + candidates = (component for component in candidates + if component._usage == usage) + + if model_name is not None: + candidates = (c for c in candidates + if c.apply_on_models is None or + model_name in c.apply_on_models) + + return list(candidates) + + +# We will store a ComponentRegistry per database here, +# it will be cleared and updated when the odoo's registry is rebuilt +_component_databases = ComponentDatabases() + + +class WorkContext(object): + """ Transport the context required to work with components + + It is propagated through all the components, so any + data or instance (like a random RPC client) that need + to be propagated transversally to the components + should be kept here. + + Including: + + .. attribute:: model_name + + Name of the model we are working with. It means that any lookup for a + component will be done for this model. It also provides a shortcut + as a `model` attribute to use directly with the Odoo model from + the components + + .. attribute:: collection + + The collection we are working with. The collection is an Odoo + Model that inherit from 'collection.base'. The collection attribute + can be a record or an "empty" model. + + .. attribute:: model + + Odoo Model for ``model_name`` with the same Odoo + :class:`~odoo.api.Environment` than the ``collection`` attribute. + + This is also the entrypoint to work with the components. + + :: + + collection = self.env['my.collection'].browse(1) + work = WorkContext(model_name='res.partner', collection=collection) + component = work.component(usage='record.importer') + + Usually you will use the context manager on the ``collection.base`` Model: + + :: + + collection = self.env['my.collection'].browse(1) + with collection.work_on('res.partner') as work: + component = work.component(usage='record.importer') + + It supports any arbitrary keyword arguments that will become attributes of + the instance, and be propagated throughout all the components. + + :: + + collection = self.env['my.collection'].browse(1) + with collection.work_on('res.partner', hello='world') as work: + assert work.hello == 'world' + + When you need to work on a different model, a new work instance will be + created for you when you are using the high-level API. This is what + happens under the hood: + + :: + + collection = self.env['my.collection'].browse(1) + with collection.work_on('res.partner', hello='world') as work: + assert work.model_name == 'res.partner' + assert work.hello == 'world' + work2 = work.work_on('res.users') + # => spawn a new WorkContext with a copy of the attributes + assert work2.model_name == 'res.users' + assert work2.hello == 'world' + + """ + + def __init__(self, model_name=None, collection=None, + components_registry=None, **kwargs): + self.collection = collection + self.model_name = model_name + self.model = self.env[model_name] + # lookup components in an alternative registry, used by the tests + if components_registry is not None: + self.components_registry = components_registry + else: + dbname = self.env.cr.dbname + try: + self.components_registry = _component_databases[dbname] + except KeyError: + _logger.error( + 'No component registry for database %s. ' + 'Probably because the Odoo registry has not been built ' + 'yet.' + ) + raise + self._propagate_kwargs = [ + 'collection', + 'model_name', + 'components_registry', + ] + for attr_name, value in kwargs.items(): + setattr(self, attr_name, value) + self._propagate_kwargs.append(attr_name) + + @property + def env(self): + """ Return the current Odoo env + + This is the environment of the current collection. + """ + return self.collection.env + + def work_on(self, model_name=None, collection=None): + """ Create a new work context for another model keeping attributes + + Used when one need to lookup components for another model. + """ + kwargs = {attr_name: getattr(self, attr_name) + for attr_name in self._propagate_kwargs} + if collection is not None: + kwargs['collection'] = collection + if model_name is not None: + kwargs['model_name'] = model_name + return self.__class__(**kwargs) + + def _component_class_by_name(self, name): + components_registry = self.components_registry + component_class = components_registry.get(name) + if not component_class: + raise NoComponentError("No component with name '%s' found." % name) + return component_class + + def component_by_name(self, name, model_name=None): + """ Return a component by its name + + If the component exists, an instance of it will be returned, + initialized with the current :class:`WorkContext`. + + A :exc:`odoo.addons.component.exception.NoComponentError` is raised + if: + + * no component with this name exists + * the ``_apply_on`` of the found component does not match + with the current working model + + In the latter case, it can be an indication that you need to switch to + a different model, you can do so by providing the ``model_name`` + argument. + + """ + if isinstance(model_name, models.BaseModel): + model_name = model_name._name + component_class = self._component_class_by_name(name) + work_model = model_name or self.model_name + if (component_class._collection and + self.collection._name != component_class._collection): + raise NoComponentError( + "Component with name '%s' can't be used for collection '%s'." + (name, self.collection._name) + ) + + if (component_class.apply_on_models and + work_model not in component_class.apply_on_models): + if len(component_class.apply_on_models) == 1: + hint_models = "'%s'" % (component_class.apply_on_models[0],) + else: + hint_models = "" % ( + component_class.apply_on_models, + ) + raise NoComponentError( + "Component with name '%s' can't be used for model '%s'.\n" + "Hint: you might want to use: " + "component_by_name('%s', model_name=%s)" % + (name, work_model, name, hint_models) + ) + + if work_model == self.model_name: + work_context = self + else: + work_context = self.work_on(model_name) + return component_class(work_context) + + def _lookup_components(self, usage=None, model_name=None): + component_classes = self.components_registry.lookup( + self.collection._name, + usage=usage, + model_name=model_name, + ) + + return [cls for cls in component_classes if cls._component_match(self)] + + def component(self, usage=None, model_name=None): + """ Find a component by usage and model for the current collection + + It searches a component using the rules of + :meth:`ComponentRegistry.lookup`. When a component is found, + it initialize it with the current :class:`WorkContext` and returned. + + A :exc:`odoo.addons.component.exception.SeveralComponentError` is + raised if more than one component match for the provided + ``usage``/``model_name``. + + A :exc:`odoo.addons.component.exception.NoComponentError` is raised + if no component is found for the provided ``usage``/``model_name``. + + """ + if isinstance(model_name, models.BaseModel): + model_name = model_name._name + model_name = model_name or self.model_name + component_classes = self._lookup_components( + usage=usage, model_name=model_name + ) + if not component_classes: + raise NoComponentError( + "No component found for collection '%s', " + "usage '%s', model_name '%s'." % + (self.collection._name, usage, model_name) + ) + elif len(component_classes) > 1: + raise SeveralComponentError( + "Several components found for collection '%s', " + "usage '%s', model_name '%s'. Found: %r" % + (self.collection._name, usage or '', + model_name or '', component_classes) + ) + if model_name == self.model_name: + work_context = self + else: + work_context = self.work_on(model_name) + return component_classes[0](work_context) + + def many_components(self, usage=None, model_name=None): + """ Find many components by usage and model for the current collection + + It searches a component using the rules of + :meth:`ComponentRegistry.lookup`. When components are found, they + initialized with the current :class:`WorkContext` and returned as a + list. + + If no component is found, an empty list is returned. + + """ + if isinstance(model_name, models.BaseModel): + model_name = model_name._name + model_name = model_name or self.model_name + component_classes = self._lookup_components( + usage=usage, model_name=model_name + ) + if model_name == self.model_name: + work_context = self + else: + work_context = self.work_on(model_name) + return [comp(work_context) for comp in component_classes] + + def __str__(self): + return "WorkContext(%s, %s)" % (self.model_name, repr(self.collection)) + + __repr__ = __str__ + + +class MetaComponent(type): + """ Metaclass for Components + + Every new :class:`Component` will be added to ``_modules_components``, + that will be used by the component builder. + + """ + + _modules_components = defaultdict(list) + + def __init__(self, name, bases, attrs): + if not self._register: + self._register = True + super(MetaComponent, self).__init__(name, bases, attrs) + return + + if not hasattr(self, '_module'): + self._module = _get_addon_name(self.__module__) + + self._modules_components[self._module].append(self) + + @property + def apply_on_models(self): + # None means all models + if self._apply_on is None: + return None + # always return a list, used for the lookup + elif isinstance(self._apply_on, str): + return [self._apply_on] + return self._apply_on + + +class AbstractComponent(object, metaclass=MetaComponent): + """ Main Component Model + + All components have a Python inheritance either on + :class:`AbstractComponent` or either on :class:`Component`. + + Abstract Components will not be returned by lookups on components, however + they can be used as a base for other Components through inheritance (using + ``_inherit``). + + Inheritance mechanism + The inheritance mechanism is like the Odoo's one for Models. Each + component has a ``_name``. This is the absolute minimum in a Component + class. + + :: + + class MyComponent(Component): + _name = 'my.component' + + def speak(self, message): + print message + + Every component implicitly inherit from the `'base'` component. + + There are two close but distinct inheritance types, which look + familiar if you already know Odoo. The first uses ``_inherit`` with + an existing name, the name of the component we want to extend. With + the following example, ``my.component`` is now able to speak and to + yell. + + :: + + class MyComponent(Component): # name of the class does not matter + _inherit = 'my.component' + + def yell(self, message): + print message.upper() + + The second has a different ``_name``, it creates a new component, + including the behavior of the inherited component, but without + modifying it. In the following example, ``my.component`` is still able + to speak and to yell (brough by the previous inherit), but not to + sing. ``another.component`` is able to speak, to yell and to sing. + + :: + + class AnotherComponent(Component): + _name = 'another.component' + _inherit = 'my.component' + + def sing(self, message): + print message.upper() + + Registration and lookups + It is handled by 3 attributes on the class: + + _collection + The name of the collection where we want to register the + component. This is not strictly mandatory as a component can be + shared across several collections. But usually, you want to set a + collection to segregate the components for a domain. A collection + can be for instance ``magento.backend``. It is also the name of a + model that inherits from ``collection.base``. See also + :class:`~WorkContext` and + :class:`~odoo.addons.component.models.collection.Collection`. + + _apply_on + List of names or name of the Odoo model(s) for which the component + can be used. When not set, the component can be used on any model. + + _usage + The collection and the model (``_apply_on``) will help to filter + the candidate components according to our working context (e.g. I'm + working on ``magento.backend`` with the model + ``magento.res.partner``). The usage will define **what** kind of + task the component we are looking for serves to. For instance, it + might be ``record.importer``, ``export.mapper```... but you can be + as creative as you want. + + Now, to get a component, you'll likely use + :meth:`WorkContext.component` when you start to work with components + in your flow, but then from within your components, you are more + likely to use one of: + + * :meth:`component` + * :meth:`many_components` + * :meth:`component_by_name` (more rarely though) + + Declaration of some Components can look like:: + + class FooBar(models.Model): + _name = 'foo.bar.collection' + _inherit = 'collection.base' # this inherit is required + + + class FooBarBase(AbstractComponent): + _name = 'foo.bar.base' + _collection = 'foo.bar.collection' # name of the model above + + + class Foo(Component): + _name = 'foo' + _inherit = 'foo.bar.base' # we will inherit the _collection + _apply_on = 'res.users' + _usage = 'speak' + + def utter(self, message): + print message + + + class Bar(Component): + _name = 'bar' + _inherit = 'foo.bar.base' # we will inherit the _collection + _apply_on = 'res.users' + _usage = 'yell' + + def utter(self, message): + print message.upper() + '!!!' + + + class Vocalizer(Component): + _name = 'vocalizer' + _inherit = 'foo.bar.base' + _usage = 'vocalizer' + # can be used for any model + + def vocalize(action, message): + self.component(usage=action).utter(message) + + + And their usage:: + + >>> coll = self.env['foo.bar.collection'].browse(1) + >>> with coll.work_on('res.users') as work: + ... vocalizer = work.component(usage='vocalizer') + ... vocalizer.vocalize('speak', 'hello world') + ... + hello world + ... vocalizer.vocalize('yell', 'hello world') + HELLO WORLD!!! + + Hints: + + * If you want to create components without ``_apply_on``, choose a + ``_usage`` that will not conflict other existing components. + * Unless this is what you want and in that case you use + :meth:`many_components` which will return all components for a usage + with a matching or a not set ``_apply_on``. + * It is advised to namespace the names of the components (e.g. + ``magento.xxx``) to prevent conflicts between addons. + + """ + + _register = False + _abstract = True + + # used for inheritance + _name = None + _inherit = None + + # name of the collection to subscribe in + _collection = None + + # None means any Model, can be a list ['res.users', ...] + _apply_on = None + # component purpose ('import.mapper', ...) + _usage = None + + def __init__(self, work_context): + super(AbstractComponent, self).__init__() + self.work = work_context + + @classmethod + def _component_match(cls, work): + """ Evaluated on candidate components + + When a component lookup is done and candidate(s) have + been found for a usage, a final call is done on this method. + If the method return False, the candidate component is ignored. + + It can be used for instance to dynamically choose a component + according to a value in the :class:`WorkContext`. + + Beware, if the lookups from usage, model and collection are + cached, the calls to :meth:`_component_match` are executed + each time we get components. Heavy computation should be + avoided. + + :param work: the :class:`WorkContext` we are working with + + """ + return True + + @property + def collection(self): + """ Collection we are working with """ + return self.work.collection + + @property + def env(self): + """ Current Odoo environment, the one of the collection record """ + return self.work.env + + @property + def model(self): + """ The model instance we are working with """ + return self.work.model + + def component_by_name(self, name, model_name=None): + """ Return a component by its name + + Shortcut to meth:`~WorkContext.component_by_name` + """ + return self.work.component_by_name(name, model_name=model_name) + + def component(self, usage=None, model_name=None): + """ Return a component + + Shortcut to meth:`~WorkContext.component` + """ + return self.work.component(usage=usage, model_name=model_name) + + def many_components(self, usage=None, model_name=None): + """ Return several components + + Shortcut to meth:`~WorkContext.many_components` + """ + return self.work.many_components(usage=usage, model_name=model_name) + + def __str__(self): + return "Component(%s)" % self._name + + __repr__ = __str__ + + @classmethod + def _build_component(cls, registry): + """ Instantiate a given Component in the components registry. + + This method is called at the end of the Odoo's registry build. The + caller is :meth:`component.builder.ComponentBuilder.load_components`. + + It generates new classes, which will be the Component classes we will + be using. The new classes are generated following the inheritance + of ``_inherit``. It ensures that the ``__bases__`` of the generated + Component classes follow the ``_inherit`` chain. + + Once a Component class is created, it adds it in the Component Registry + (:class:`ComponentRegistry`), so it will be available for + lookups. + + At the end of new class creation, a hook method + :meth:`_complete_component_build` is called, so you can customize + further the created components. An example can be found in + :meth:`odoo.addons.connector.components.mapper.Mapper._complete_component_build` + + The following code is roughly the same than the Odoo's one for + building Models. + + """ + + # In the simplest case, the component's registry class inherits from + # cls and the other classes that define the component in a flat + # hierarchy. The registry contains the instance ``component`` (on the + # left). Its class, ``ComponentClass``, carries inferred metadata that + # is shared between all the component's instances for this registry + # only. + # + # class A1(Component): Component + # _name = 'a' / | \ + # A3 A2 A1 + # class A2(Component): \ | / + # _inherit = 'a' ComponentClass + # + # class A3(Component): + # _inherit = 'a' + # + # When a component is extended by '_inherit', its base classes are + # modified to include the current class and the other inherited + # component classes. + # Note that we actually inherit from other ``ComponentClass``, so that + # extensions to an inherited component are immediately visible in the + # current component class, like in the following example: + # + # class A1(Component): + # _name = 'a' Component + # / / \ \ + # class B1(Component): / A2 A1 \ + # _name = 'b' / \ / \ + # B2 ComponentA B1 + # class B2(Component): \ | / + # _name = 'b' \ | / + # _inherit = ['b', 'a'] \ | / + # ComponentB + # class A2(Component): + # _inherit = 'a' + + # determine inherited components + parents = cls._inherit + if isinstance(parents, str): + parents = [parents] + elif parents is None: + parents = [] + + if cls._name in registry and not parents: + raise TypeError('Component %r (in class %r) already exists. ' + 'Consider using _inherit instead of _name ' + 'or using a different _name.' % (cls._name, cls)) + + # determine the component's name + name = cls._name or (len(parents) == 1 and parents[0]) + + if not name: + raise TypeError('Component %r must have a _name' % cls) + + # all components except 'base' implicitly inherit from 'base' + if name != 'base': + parents = list(parents) + ['base'] + + # create or retrieve the component's class + if name in parents: + if name not in registry: + raise TypeError("Component %r does not exist in registry." % + name) + ComponentClass = registry[name] + ComponentClass._build_component_check_base(cls) + check_parent = ComponentClass._build_component_check_parent + else: + ComponentClass = type( + name, (AbstractComponent,), + {'_name': name, + '_register': False, + # names of children component + '_inherit_children': OrderedSet()}, + ) + check_parent = cls._build_component_check_parent + + # determine all the classes the component should inherit from + bases = LastOrderedSet([cls]) + for parent in parents: + if parent not in registry: + raise TypeError( + "Component %r inherits from non-existing component %r." % + (name, parent) + ) + parent_class = registry[parent] + if parent == name: + for base in parent_class.__bases__: + bases.add(base) + else: + check_parent(cls, parent_class) + bases.add(parent_class) + parent_class._inherit_children.add(name) + ComponentClass.__bases__ = tuple(bases) + + ComponentClass._complete_component_build() + + registry[name] = ComponentClass + + return ComponentClass + + @classmethod + def _build_component_check_base(cls, extend_cls): + """ Check whether ``cls`` can be extended with ``extend_cls``. """ + if cls._abstract and not extend_cls._abstract: + msg = ("%s transforms the abstract component %r into a " + "non-abstract component. " + "That class should either inherit from AbstractComponent, " + "or set a different '_name'.") + raise TypeError(msg % (extend_cls, cls._name)) + + @classmethod + def _build_component_check_parent(component_class, cls, parent_class): + """ Check whether ``model_class`` can inherit from ``parent_class``. + """ + if component_class._abstract and not parent_class._abstract: + msg = ("In %s, the abstract Component %r cannot inherit " + "from the non-abstract Component %r.") + raise TypeError( + msg % (cls, component_class._name, parent_class._name) + ) + + @classmethod + def _complete_component_build(cls): + """ Complete build of the new component class + + After the component has been built from its bases, this method is + called, and can be used to customize the class before it can be used. + + Nothing is done in the base Component, but a Component can inherit + the method to add its own behavior. + """ + + +class Component(AbstractComponent): + """ Concrete Component class + + This is the class you inherit from when you want your component to + be registered in the component collections. + + Look in :class:`AbstractComponent` for more details. + + """ + _register = False + _abstract = False diff --git a/ext/3rd-party-addons/component/exception.py b/ext/3rd-party-addons/component/exception.py new file mode 100644 index 00000000..71fcd38b --- /dev/null +++ b/ext/3rd-party-addons/component/exception.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + + +class ComponentException(Exception): + """ Base Exception for the components """ + + +class NoComponentError(ComponentException): + """ No component has been found """ + + +class SeveralComponentError(ComponentException): + """ More than one component have been found """ diff --git a/ext/3rd-party-addons/component/models/__init__.py b/ext/3rd-party-addons/component/models/__init__.py new file mode 100644 index 00000000..4343b4ae --- /dev/null +++ b/ext/3rd-party-addons/component/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import collection diff --git a/ext/3rd-party-addons/component/models/collection.py b/ext/3rd-party-addons/component/models/collection.py new file mode 100644 index 00000000..22033696 --- /dev/null +++ b/ext/3rd-party-addons/component/models/collection.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" + +Collection Model +================ + +This is the base Model shared by all the Collections. +In the context of the Connector, a collection is the Backend. +The `_name` given to the Collection Model will be the name +to use in the `_collection` of the Components usable for the Backend. + +""" + +from contextlib import contextmanager + +from odoo import models, api +from ..core import WorkContext + + +class Collection(models.AbstractModel): + """ The model on which components are subscribed + + It would be for instance the ``backend`` for the connectors. + + Example:: + + class MagentoBackend(models.Model): + _name = 'magento.backend' # name of the collection + _inherit = 'collection.base' + + + class MagentoSaleImporter(Component): + _name = 'magento.sale.importer' + _apply_on = 'magento.sale.order' + _collection = 'magento.backend' # name of the collection + + def run(self, magento_id): + mapper = self.component(usage='import.mapper') + extra_mappers = self.many_components( + usage='import.mapper.extra', + ) + # ... + + Use it:: + + >>> backend = self.env['magento.backend'].browse(1) + >>> with backend.work_on('magento.sale.order') as work: + ... importer = work.component(usage='magento.sale.importer') + ... importer.run(1) + + See also: :class:`odoo.addons.component.core.WorkContext` + + + """ + _name = 'collection.base' + _description = 'Base Abstract Collection' + + @contextmanager + @api.multi + def work_on(self, model_name, **kwargs): + """ Entry-point for the components, context manager + + Start a work using the components on the model. + Any keyword argument will be assigned to the work context. + See documentation of :class:`odoo.addons.component.core.WorkContext`. + + It is a context manager, so you can attach objects and clean them + at the end of the work session, such as:: + + @contextmanager + @api.multi + def work_on(self, model_name, **kwargs): + self.ensure_one() + magento_location = MagentoLocation( + self.location, + self.username, + self.password, + ) + # We create a Magento Client API here, so we can create the + # client once (lazily on the first use) and propagate it + # through all the sync session, instead of recreating a client + # in each backend adapter usage. + with MagentoAPI(magento_location) as magento_api: + _super = super(MagentoBackend, self) + # from the components we'll be able to do: + # self.work.magento_api + with _super.work_on( + model_name, magento_api=magento_api, **kwargs + ) as work: + yield work + + """ + self.ensure_one() + yield WorkContext(model_name=model_name, collection=self, **kwargs) diff --git a/ext/3rd-party-addons/component/tests/__init__.py b/ext/3rd-party-addons/component/tests/__init__.py new file mode 100644 index 00000000..ef6a6108 --- /dev/null +++ b/ext/3rd-party-addons/component/tests/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from . import test_build_component +from . import test_component +from . import test_lookup +from . import test_work_on diff --git a/ext/3rd-party-addons/component/tests/common.py b/ext/3rd-party-addons/component/tests/common.py new file mode 100644 index 00000000..7a462186 --- /dev/null +++ b/ext/3rd-party-addons/component/tests/common.py @@ -0,0 +1,207 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +import copy + +from contextlib import contextmanager + +import unittest +import odoo +from odoo import api +from odoo.tests import common +from odoo.addons.component.core import ( + ComponentRegistry, + MetaComponent, + _get_addon_name, +) + + +@contextmanager +def new_rollbacked_env(): + registry = odoo.registry(common.get_db_name()) + uid = odoo.SUPERUSER_ID + cr = registry.cursor() + try: + yield api.Environment(cr, uid, {}) + finally: + cr.rollback() # we shouldn't have to commit anything + cr.close() + + +class ComponentMixin(object): + + @classmethod + def setUpComponent(cls): + with new_rollbacked_env() as env: + builder = env['component.builder'] + # build the components of every installed addons + comp_registry = builder._init_global_registry() + cls._components_registry = comp_registry + # ensure that we load only the components of the 'installed' + # modules, not 'to install', which means we load only the + # dependencies of the tested addons, not the siblings or + # chilren addons + builder.build_registry(comp_registry, states=('installed',)) + # build the components of the current tested addon + current_addon = _get_addon_name(cls.__module__) + env['component.builder'].load_components(current_addon) + + def setUp(self): + # should be ready only during tests, never during installation + # of addons + self._components_registry.ready = True + + @self.addCleanup + def notready(): + self._components_registry.ready = False + + +class TransactionComponentCase(common.TransactionCase, ComponentMixin): + """ A TransactionCase that loads all the components + + It it used like an usual Odoo's TransactionCase, but it ensures + that all the components of the current addon and its dependencies + are loaded. + + """ + + @classmethod + def setUpClass(cls): + super(TransactionComponentCase, cls).setUpClass() + cls.setUpComponent() + + def setUp(self): + # resolve an inheritance issue (common.TransactionCase does not call + # super) + common.TransactionCase.setUp(self) + ComponentMixin.setUp(self) + + +class SavepointComponentCase(common.SavepointCase, ComponentMixin): + """ A SavepointCase that loads all the components + + It it used like an usual Odoo's SavepointCase, but it ensures + that all the components of the current addon and its dependencies + are loaded. + + """ + + @classmethod + def setUpClass(cls): + super(SavepointComponentCase, cls).setUpClass() + cls.setUpComponent() + + def setUp(self): + # resolve an inheritance issue (common.SavepointCase does not call + # super) + common.SavepointCase.setUp(self) + ComponentMixin.setUp(self) + + +class ComponentRegistryCase(unittest.TestCase): + """ This test case can be used as a base for writings tests on components + + This test case is meant to test components in a special component registry, + where you want to have maximum control on which components are loaded + or not, or when you want to create additional components in your tests. + + If you only want to *use* the components of the tested addon in your tests, + then consider using one of: + + * :class:`TransactionComponentCase` + * :class:`SavepointComponentCase` + + This test case creates a special + :class:`odoo.addons.component.core.ComponentRegistry` for the purpose of + the tests. By default, it loads all the components of the dependencies, but + not the components of the current addon (which you have to handle + manually). In your tests, you can add more components in 2 manners. + + All the components of an Odoo module:: + + self._load_module_components('connector') + + Only specific components:: + + self._build_components(MyComponent1, MyComponent2) + + Note: for the lookups of the components, the default component + registry is a global registry for the database. Here, you will + need to explicitly pass ``self.comp_registry`` in the + :class:`~odoo.addons.component.core.WorkContext`:: + + work = WorkContext(model_name='res.users', + collection='my.collection', + components_registry=self.comp_registry) + + Or:: + + collection_record = self.env['my.collection'].browse(1) + with collection_record.work_on( + 'res.partner', + components_registry=self.comp_registry) as work: + + """ + + def setUp(self): + super(ComponentRegistryCase, self).setUp() + + # keep the original classes registered by the metaclass + # so we'll restore them at the end of the tests, it avoid + # to pollute it with Stub / Test components + self._original_components = copy.deepcopy( + MetaComponent._modules_components + ) + + # it will be our temporary component registry for our test session + self.comp_registry = ComponentRegistry() + + # it builds the 'final component' for every component of the + # 'component' addon and push them in the component registry + self.comp_registry.load_components('component') + # build the components of every installed addons already installed + # but the current addon (when running with pytest/nosetest, we + # simulate the --test-enable behavior by excluding the current addon + # which is in 'to install' / 'to upgrade' with --test-enable). + current_addon = _get_addon_name(self.__module__) + with new_rollbacked_env() as env: + env['component.builder'].build_registry( + self.comp_registry, + states=('installed',), + exclude_addons=[current_addon], + ) + + # Fake that we are ready to work with the registry + # normally, it is set to True and the end of the build + # of the components. Here, we'll add components later in + # the components registry, but we don't mind for the tests. + self.comp_registry.ready = True + + def tearDown(self): + super(ComponentRegistryCase, self).tearDown() + # restore the original metaclass' classes + MetaComponent._modules_components = self._original_components + + def _load_module_components(self, module): + self.comp_registry.load_components(module) + + def _build_components(self, *classes): + for cls in classes: + cls._build_component(self.comp_registry) + + +class TransactionComponentRegistryCase(common.TransactionCase, + ComponentRegistryCase): + """ Adds Odoo Transaction in the base Component TestCase """ + + def setUp(self): + # resolve an inheritance issue (common.TransactionCase does not use + # super) + common.TransactionCase.setUp(self) + ComponentRegistryCase.setUp(self) + self.collection = self.env['collection.base'] + + def teardown(self): + common.TransactionCase.tearDown(self) + ComponentRegistryCase.tearDown(self) diff --git a/ext/3rd-party-addons/component/tests/test_build_component.py b/ext/3rd-party-addons/component/tests/test_build_component.py new file mode 100644 index 00000000..0d7bc35f --- /dev/null +++ b/ext/3rd-party-addons/component/tests/test_build_component.py @@ -0,0 +1,272 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +import mock +from odoo.addons.component.core import AbstractComponent, Component +from .common import ComponentRegistryCase + + +class TestBuildComponent(ComponentRegistryCase): + """ Test build of components + + All the tests in this suite are based on the same principle with + variations: + + * Create new Components (classes inheriting from + :class:`component.core.Component` or + :class:`component.core.AbstractComponent` + * Call :meth:`component.core.Component._build_component` on them + in order to build the 'final class' composed from all the ``_inherit`` + and push it in the components registry (``self.comp_registry`` here) + * Assert that classes are built, registered, have correct ``__bases__``... + + """ + + def test_no_name(self): + """ Ensure that a component has a _name """ + class Component1(Component): + pass + + msg = '.*must have a _name.*' + with self.assertRaisesRegex(TypeError, msg): + Component1._build_component(self.comp_registry) + + def test_register(self): + """ Able to register components in components registry """ + class Component1(Component): + _name = 'component1' + + class Component2(Component): + _name = 'component2' + + # build the 'final classes' for the components and check that we find + # them in the components registry + Component1._build_component(self.comp_registry) + Component2._build_component(self.comp_registry) + self.assertEqual( + ['base', 'component1', 'component2'], + list(self.comp_registry) + ) + + def test_inherit_bases(self): + """ Check __bases__ of Component with _inherit """ + class Component1(Component): + _name = 'component1' + + class Component2(Component): + _inherit = 'component1' + + class Component3(Component): + _inherit = 'component1' + + Component1._build_component(self.comp_registry) + Component2._build_component(self.comp_registry) + Component3._build_component(self.comp_registry) + self.assertEqual( + (Component3, + Component2, + Component1, + self.comp_registry['base']), + self.comp_registry['component1'].__bases__ + ) + + def test_prototype_inherit_bases(self): + """ Check __bases__ of Component with _inherit and different _name """ + class Component1(Component): + _name = 'component1' + + class Component2(Component): + _name = 'component2' + _inherit = 'component1' + + class Component3(Component): + _name = 'component3' + _inherit = 'component1' + + class Component4(Component): + _name = 'component4' + _inherit = ['component2', 'component3'] + + Component1._build_component(self.comp_registry) + Component2._build_component(self.comp_registry) + Component3._build_component(self.comp_registry) + Component4._build_component(self.comp_registry) + self.assertEqual( + (Component1, + self.comp_registry['base']), + self.comp_registry['component1'].__bases__ + ) + self.assertEqual( + (Component2, + self.comp_registry['component1'], + self.comp_registry['base']), + self.comp_registry['component2'].__bases__ + ) + self.assertEqual( + (Component3, + self.comp_registry['component1'], + self.comp_registry['base']), + self.comp_registry['component3'].__bases__ + ) + self.assertEqual( + (Component4, + self.comp_registry['component2'], + self.comp_registry['component3'], + self.comp_registry['base']), + self.comp_registry['component4'].__bases__ + ) + + def test_custom_build(self): + """ Check that we can hook at the end of a Component build """ + class Component1(Component): + _name = 'component1' + + @classmethod + def _complete_component_build(cls): + # This method should be called after the Component + # is built, and before it is pushed in the registry + cls._build_done = True + + Component1._build_component(self.comp_registry) + # we inspect that our custom build has been executed + self.assertTrue( + self.comp_registry['component1']._build_done + ) + + def test_inherit_attrs(self): + """ Check attributes inheritance of Components with _inherit """ + class Component1(Component): + _name = 'component1' + + msg = 'ping' + + def say(self): + return 'foo' + + class Component2(Component): + _name = 'component2' + _inherit = 'component1' + + msg = 'pong' + + def say(self): + return super(Component2, self).say() + ' bar' + + Component1._build_component(self.comp_registry) + Component2._build_component(self.comp_registry) + # we initialize the components, normally we should pass + # an instance of WorkContext, but we don't need a real one + # for this test + component1 = self.comp_registry['component1'](mock.Mock()) + component2 = self.comp_registry['component2'](mock.Mock()) + self.assertEqual('ping', component1.msg) + self.assertEqual('pong', component2.msg) + self.assertEqual('foo', component1.say()) + self.assertEqual('foo bar', component2.say()) + + def test_duplicate_component(self): + """ Check that we can't have 2 components with the same name """ + class Component1(Component): + _name = 'component1' + + class Component2(Component): + _name = 'component1' + + Component1._build_component(self.comp_registry) + msg = 'Component.*already exists.*' + with self.assertRaisesRegex(TypeError, msg): + Component2._build_component(self.comp_registry) + + def test_no_parent(self): + """ Ensure we can't _inherit a non-existent component """ + class Component1(Component): + _name = 'component1' + _inherit = 'component1' + + msg = 'Component.*does not exist in registry.*' + with self.assertRaisesRegex(TypeError, msg): + Component1._build_component(self.comp_registry) + + def test_no_parent2(self): + """ Ensure we can't _inherit by prototype a non-existent component """ + class Component1(Component): + _name = 'component1' + + class Component2(Component): + _name = 'component2' + _inherit = ['component1', 'component3'] + + Component1._build_component(self.comp_registry) + msg = 'Component.*inherits from non-existing component.*' + with self.assertRaisesRegex(TypeError, msg): + Component2._build_component(self.comp_registry) + + def test_add_inheritance(self): + """ Ensure we can add a new inheritance """ + class Component1(Component): + _name = 'component1' + + class Component2(Component): + _name = 'component2' + + class Component2bis(Component): + _name = 'component2' + _inherit = ['component2', 'component1'] + + Component1._build_component(self.comp_registry) + Component2._build_component(self.comp_registry) + Component2bis._build_component(self.comp_registry) + + self.assertEqual( + (Component2bis, + Component2, + self.comp_registry['component1'], + self.comp_registry['base']), + self.comp_registry['component2'].__bases__ + ) + + def test_check_parent_component_over_abstract(self): + """ Component can inherit from AbstractComponent """ + class Component1(AbstractComponent): + _name = 'component1' + + class Component2(Component): + _name = 'component2' + _inherit = 'component1' + + Component1._build_component(self.comp_registry) + Component2._build_component(self.comp_registry) + self.assertTrue( + self.comp_registry['component1']._abstract + ) + self.assertFalse( + self.comp_registry['component2']._abstract + ) + + def test_check_parent_abstract_over_component(self): + """ Prevent AbstractComponent to inherit from Component """ + class Component1(Component): + _name = 'component1' + + class Component2(AbstractComponent): + _name = 'component2' + _inherit = 'component1' + + Component1._build_component(self.comp_registry) + msg = '.*cannot inherit from the non-abstract.*' + with self.assertRaisesRegex(TypeError, msg): + Component2._build_component(self.comp_registry) + + def test_check_transform_abstract_to_component(self): + """ Prevent AbstractComponent to be transformed to Component """ + class Component1(AbstractComponent): + _name = 'component1' + + class Component1bis(Component): + _inherit = 'component1' + + Component1._build_component(self.comp_registry) + msg = '.*transforms the abstract component.*into a non-abstract.*' + with self.assertRaisesRegex(TypeError, msg): + Component1bis._build_component(self.comp_registry) diff --git a/ext/3rd-party-addons/component/tests/test_component.py b/ext/3rd-party-addons/component/tests/test_component.py new file mode 100644 index 00000000..ebc04e68 --- /dev/null +++ b/ext/3rd-party-addons/component/tests/test_component.py @@ -0,0 +1,287 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from contextlib import contextmanager +from odoo.addons.component.core import ( + Component, +) +from .common import TransactionComponentRegistryCase +from odoo.addons.component.exception import ( + NoComponentError, + SeveralComponentError, +) + + +class TestComponent(TransactionComponentRegistryCase): + """ Test usage of components + + These tests are a bit more broad that mere unit tests. + We test the chain odoo Model -> generate a WorkContext instance -> Work + with Component. + + Tests are inside Odoo transactions, so we can work + with Odoo's env / models. + """ + + def setUp(self): + super(TestComponent, self).setUp() + self.collection = self.env['collection.base'] + + # create some Component to play with + class Component1(Component): + _name = 'component1' + _collection = 'collection.base' + _usage = 'for.test' + _apply_on = ['res.partner'] + + class Component2(Component): + _name = 'component2' + _collection = 'collection.base' + _usage = 'for.test' + _apply_on = ['res.users'] + + # build the components and register them in our + # test component registry + Component1._build_component(self.comp_registry) + Component2._build_component(self.comp_registry) + + # our collection, in a less abstract use case, it + # could be a record of 'magento.backend' for instance + self.collection_record = self.collection.new() + + @contextmanager + def get_base(): + # Our WorkContext, it will be passed along in every + # components so we can share data transversally. + # We are working with res.partner in the following tests, + # unless we change it in the test. + with self.collection_record.work_on( + 'res.partner', + # we use a custom registry only + # for the sake of the tests + components_registry=self.comp_registry + ) as work: + # We get the 'base' component, handy to test the base + # methods component, many_components, ... + yield work.component_by_name('base') + self.get_base = get_base + + def test_component_attrs(self): + """ Basic access to a Component's attribute """ + with self.get_base() as base: + # as we are working on res.partner, we should get 'component1' + comp = base.work.component(usage='for.test') + # but this is not what we test here, we test the attributes: + self.assertEqual(self.collection_record, comp.collection) + self.assertEqual(base.work, comp.work) + self.assertEqual(self.env, comp.env) + self.assertEqual(self.env['res.partner'], comp.model) + + def test_component_get_by_name_same_model(self): + """ Use component_by_name with current working model """ + with self.get_base() as base: + # we ask a component directly by it's name, considering + # we work with res.partner, we should get 'component1' + # this is ok because it's _apply_on contains res.partner + comp = base.component_by_name('component1') + self.assertEqual('component1', comp._name) + self.assertEqual(self.env['res.partner'], comp.model) + + def test_component_get_by_name_other_model(self): + """ Use component_by_name with another model """ + with self.get_base() as base: + # we ask a component directly by it's name, but we + # want to work with 'res.users', this is ok since + # component2's _apply_on contains res.users + comp = base.component_by_name( + 'component2', model_name='res.users' + ) + self.assertEqual('component2', comp._name) + self.assertEqual(self.env['res.users'], comp.model) + # what happens under the hood, is that a new WorkContext + # has been created for this model, with all the other values + # identical to the previous WorkContext (the one for res.partner) + # We can check that with: + self.assertNotEqual(base.work, comp.work) + self.assertEqual('res.partner', base.work.model_name) + self.assertEqual('res.users', comp.work.model_name) + + def test_component_get_by_name_wrong_model(self): + """ Use component_by_name with a model not in _apply_on """ + msg = ("Component with name 'component2' can't be used " + "for model 'res.partner'.*") + with self.get_base() as base: + with self.assertRaisesRegex(NoComponentError, msg): + # we ask for the model 'component2' but we are working + # with res.partner, and it only accepts res.users + base.component_by_name('component2') + + def test_component_get_by_name_not_exist(self): + """ Use component_by_name on a component that do not exist """ + msg = "No component with name 'foo' found." + with self.get_base() as base: + with self.assertRaisesRegex(NoComponentError, msg): + base.component_by_name('foo') + + def test_component_by_usage_same_model(self): + """ Use component(usage=...) on the same model """ + # we ask for a component having _usage == 'for.test', and + # model being res.partner (the model in the current WorkContext) + with self.get_base() as base: + comp = base.component(usage='for.test') + self.assertEqual('component1', comp._name) + self.assertEqual(self.env['res.partner'], comp.model) + + def test_component_by_usage_other_model(self): + """ Use component(usage=...) on a different model (name) """ + # we ask for a component having _usage == 'for.test', and + # a different model (res.users) + with self.get_base() as base: + comp = base.component(usage='for.test', model_name='res.users') + self.assertEqual('component2', comp._name) + self.assertEqual(self.env['res.users'], comp.model) + # what happens under the hood, is that a new WorkContext + # has been created for this model, with all the other values + # identical to the previous WorkContext (the one for res.partner) + # We can check that with: + self.assertNotEqual(base.work, comp.work) + self.assertEqual('res.partner', base.work.model_name) + self.assertEqual('res.users', comp.work.model_name) + + def test_component_by_usage_other_model_env(self): + """ Use component(usage=...) on a different model (instance) """ + with self.get_base() as base: + comp = base.component(usage='for.test', + model_name=self.env['res.users']) + self.assertEqual('component2', comp._name) + self.assertEqual(self.env['res.users'], comp.model) + + def test_component_error_several(self): + """ Use component(usage=...) when more than one component match """ + # we create a new Component with _usage 'for.test', in the same + # collection and no _apply_on + class Component3(Component): + _name = 'component3' + _collection = 'collection.base' + _usage = 'for.test' + + Component3._build_component(self.comp_registry) + + with self.get_base() as base: + with self.assertRaises(SeveralComponentError): + # When a component has no _apply_on, it means it can be applied + # on *any* model. Here, the candidates components would be: + # component1 (because we are working with res.partner), + # component3 (because it has no _apply_on so apply in any case) + base.component(usage='for.test') + + def test_many_components(self): + """ Use many_components(usage=...) on the same model """ + class Component3(Component): + _name = 'component3' + _collection = 'collection.base' + _usage = 'for.test' + + Component3._build_component(self.comp_registry) + + with self.get_base() as base: + comps = base.many_components(usage='for.test') + + # When a component has no _apply_on, it means it can be applied + # on *any* model. So here, both component1 and component3 match + self.assertEqual( + ['component1', 'component3'], + [c._name for c in comps] + ) + + def test_many_components_other_model(self): + """ Use many_components(usage=...) on a different model (name) """ + class Component3(Component): + _name = 'component3' + _collection = 'collection.base' + _apply_on = 'res.users' + _usage = 'for.test' + + Component3._build_component(self.comp_registry) + + with self.get_base() as base: + comps = base.many_components(usage='for.test', + model_name='res.users') + + self.assertEqual( + ['component2', 'component3'], + [c._name for c in comps] + ) + + def test_many_components_other_model_env(self): + """ Use many_components(usage=...) on a different model (instance) """ + class Component3(Component): + _name = 'component3' + _collection = 'collection.base' + _apply_on = 'res.users' + _usage = 'for.test' + + Component3._build_component(self.comp_registry) + + with self.get_base() as base: + comps = base.many_components(usage='for.test', + model_name=self.env['res.users']) + + self.assertEqual( + ['component2', 'component3'], + [c._name for c in comps] + ) + + def test_no_component(self): + """ No component found for asked usage """ + with self.get_base() as base: + with self.assertRaises(NoComponentError): + base.component(usage='foo') + + def test_no_many_component(self): + """ No component found for asked usage for many_components() """ + with self.get_base() as base: + self.assertEqual([], base.many_components(usage='foo')) + + def test_work_on_component(self): + """ Check WorkContext.component() (shortcut to Component.component) """ + with self.get_base() as base: + comp = base.work.component(usage='for.test') + self.assertEqual('component1', comp._name) + + def test_work_on_many_components(self): + """ Check WorkContext.many_components() + + (shortcut to Component.many_components) + """ + with self.get_base() as base: + comps = base.work.many_components(usage='for.test') + self.assertEqual('component1', comps[0]._name) + + def test_component_match(self): + """ Lookup with match method """ + class Foo(Component): + _name = 'foo' + _collection = 'collection.base' + _usage = 'speaker' + _apply_on = ['res.partner'] + + @classmethod + def _component_match(cls, work): + return False + + class Bar(Component): + _name = 'bar' + _collection = 'collection.base' + _usage = 'speaker' + _apply_on = ['res.partner'] + + self._build_components(Foo, Bar) + + with self.get_base() as base: + # both components would we returned without the + # _component_match method + comp = base.component(usage='speaker', + model_name=self.env['res.partner']) + self.assertEqual('bar', comp._name) diff --git a/ext/3rd-party-addons/component/tests/test_lookup.py b/ext/3rd-party-addons/component/tests/test_lookup.py new file mode 100644 index 00000000..a4ae7071 --- /dev/null +++ b/ext/3rd-party-addons/component/tests/test_lookup.py @@ -0,0 +1,194 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo.addons.component.core import ( + AbstractComponent, + Component, +) +from .common import ComponentRegistryCase + + +class TestLookup(ComponentRegistryCase): + """ Test the ComponentRegistry + + Tests in this testsuite mainly do: + + * Create new Components (classes inheriting from + :class:`component.core.Component` or + :class:`component.core.AbstractComponent` + * Call :meth:`component.core.Component._build_component` on them + in order to build the 'final class' composed from all the ``_inherit`` + and push it in the components registry (``self.comp_registry`` here) + * Use the lookup method of the components registry and check + that we get the correct result + + """ + + def test_lookup_collection(self): + """ Lookup components of a collection """ + # we register 2 components in foobar and one in other + class Foo(Component): + _name = 'foo' + _collection = 'foobar' + + class Bar(Component): + _name = 'bar' + _collection = 'foobar' + + class Homer(Component): + _name = 'homer' + _collection = 'other' + + self._build_components(Foo, Bar, Homer) + + # we should no see the component in 'other' + components = self.comp_registry.lookup('foobar') + self.assertEqual( + ['foo', 'bar'], + [c._name for c in components] + ) + + def test_lookup_usage(self): + """ Lookup components by usage """ + class Foo(Component): + _name = 'foo' + _collection = 'foobar' + _usage = 'speaker' + + class Bar(Component): + _name = 'bar' + _collection = 'foobar' + _usage = 'speaker' + + class Baz(Component): + _name = 'baz' + _collection = 'foobar' + _usage = 'listener' + + self._build_components(Foo, Bar, Baz) + + components = self.comp_registry.lookup('foobar', usage='listener') + self.assertEqual('baz', components[0]._name) + + components = self.comp_registry.lookup('foobar', usage='speaker') + self.assertEqual( + ['foo', 'bar'], + [c._name for c in components] + ) + + def test_lookup_no_component(self): + """ No component """ + # we just expect an empty list when no component match, the error + # handling is handled at an higher level + self.assertEqual( + [], + self.comp_registry.lookup('something', usage='something') + ) + + def test_get_by_name(self): + """ Get component by name """ + class Foo(AbstractComponent): + _name = 'foo' + _collection = 'foobar' + + self._build_components(Foo) + # this is just a dict access + self.assertEqual('foo', self.comp_registry['foo']._name) + + def test_lookup_abstract(self): + """ Do not include abstract components in lookup """ + class Foo(AbstractComponent): + _name = 'foo' + _collection = 'foobar' + _usage = 'speaker' + + class Bar(Component): + _name = 'bar' + _inherit = 'foo' + + self._build_components(Foo, Bar) + + comp_registry = self.comp_registry + + # we should never have 'foo' in the returned components + # as it is abstract + components = comp_registry.lookup('foobar', usage='speaker') + self.assertEqual('bar', components[0]._name) + + components = comp_registry.lookup('foobar', usage='speaker') + self.assertEqual( + ['bar'], + [c._name for c in components] + ) + + def test_lookup_model_name(self): + """ Lookup with model names """ + class Foo(Component): + _name = 'foo' + _collection = 'foobar' + _usage = 'speaker' + # support list + _apply_on = ['res.partner'] + + class Bar(Component): + _name = 'bar' + _collection = 'foobar' + _usage = 'speaker' + # support string + _apply_on = 'res.users' + + class Any(Component): + # can be used with any model as far as we look it up + # with its usage + _name = 'any' + _collection = 'foobar' + _usage = 'listener' + + self._build_components(Foo, Bar, Any) + + components = self.comp_registry.lookup('foobar', + usage='speaker', + model_name='res.partner') + self.assertEqual('foo', components[0]._name) + + components = self.comp_registry.lookup('foobar', + usage='speaker', + model_name='res.users') + self.assertEqual('bar', components[0]._name) + + components = self.comp_registry.lookup('foobar', + usage='listener', + model_name='res.users') + self.assertEqual('any', components[0]._name) + + def test_lookup_cache(self): + """ Lookup uses a cache """ + class Foo(Component): + _name = 'foo' + _collection = 'foobar' + + self._build_components(Foo) + + components = self.comp_registry.lookup('foobar') + self.assertEqual(['foo'], [c._name for c in components]) + + # we add a new component + class Bar(Component): + _name = 'bar' + _collection = 'foobar' + + self._build_components(Bar) + + # As the lookups are cached, we should still see only foo, + # even if we added a new component. + # We do this for testing, but in a real use case, we can't + # add new Component classes on the fly, and when we install + # new addons, the registry is rebuilt and cache cleared. + components = self.comp_registry.lookup('foobar') + self.assertEqual(['foo'], [c._name for c in components]) + + self.comp_registry._cache.clear() + # now we should find them both as the cache has been cleared + components = self.comp_registry.lookup('foobar') + self.assertEqual(['foo', 'bar'], [c._name for c in components]) diff --git a/ext/3rd-party-addons/component/tests/test_work_on.py b/ext/3rd-party-addons/component/tests/test_work_on.py new file mode 100644 index 00000000..645ff854 --- /dev/null +++ b/ext/3rd-party-addons/component/tests/test_work_on.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo.addons.component.core import WorkContext, ComponentRegistry +from .common import TransactionComponentCase + + +class TestWorkOn(TransactionComponentCase): + """ Test on WorkContext + + This model is mostly a container, so we check the access + to the attributes and properties. + + """ + + def setUp(self): + super(TestWorkOn, self).setUp() + self.collection = self.env['collection.base'] + + def test_collection_work_on(self): + """ Create a new instance and test attributes access """ + collection_record = self.collection.new() + with collection_record.work_on('res.partner') as work: + self.assertEqual(collection_record, work.collection) + self.assertEqual('collection.base', work.collection._name) + self.assertEqual('res.partner', work.model_name) + self.assertEqual(self.env['res.partner'], work.model) + self.assertEqual(self.env, work.env) + + def test_propagate_work_on(self): + """ Check custom attributes and their propagation """ + registry = ComponentRegistry() + work = WorkContext( + model_name='res.partner', + collection=self.collection, + # we can customize the lookup registry, but used mostly for tests + components_registry=registry, + # we can pass our own keyword args that will set as attributes + test_keyword='value', + ) + self.assertIs(registry, work.components_registry) + # check that our custom keyword is set as attribute + self.assertEqual('value', work.test_keyword) + + # when we want to work on another model, work_on() create + # another instance and propagate the attributes to it + work2 = work.work_on('res.users') + self.assertNotEqual(work, work2) + self.assertEqual(self.env, work2.env) + self.assertEqual(self.collection, work2.collection) + self.assertEqual('res.users', work2.model_name) + self.assertIs(registry, work2.components_registry) + # test_keyword has been propagated to the new WorkContext instance + self.assertEqual('value', work2.test_keyword) diff --git a/ext/3rd-party-addons/component_event/README.rst b/ext/3rd-party-addons/component_event/README.rst new file mode 100644 index 00000000..d3d986b2 --- /dev/null +++ b/ext/3rd-party-addons/component_event/README.rst @@ -0,0 +1,106 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl + :alt: License: AGPL-3 + +=================== +Components - Events +=================== + +This module implements an event system (`Observer pattern`_) and is a +base block for the Connector Framework. It can be used without +using the full Connector though. It is built upon the ``component`` module. + +Documentation: http://odoo-connector.com/ + +.. _Observer pattern: https://en.wikipedia.org/wiki/Observer_pattern + +Installation +============ + +* Install ``component_event`` + +Configuration +============= + +The module does nothing by itself and has no configuration. + +Usage +===== + +As a developer, you have access to a events system. You can find the +documentation in the code or on http://odoo-connector.com + +In a nutshell, you can create trigger events:: + + class Base(models.AbstractModel): + _inherit = 'base' + + @api.model + def create(self, vals): + record = super(Base, self).create(vals) + self._event('on_record_create').notify(record, fields=vals.keys()) + return record + +And subscribe listeners to the events:: + + from odoo.addons.component.core import Component + from odoo.addons.component_event import skip_if + + class MagentoListener(Component): + _name = 'magento.event.listener' + _inherit = 'base.connector.listener' + + @skip_if(lambda self, record, **kwargs: self.no_connector_export(record)) + def on_record_create(self, record, fields=None): + """ Called when a record is created """ + record.with_delay().export_record(fields=fields) + + +This module triggers 3 events: + +* ``on_record_create(record, fields=None)`` +* ``on_record_write(record, fields=None)`` +* ``on_record_unlink(record)`` + + +Known issues / Roadmap +====================== + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smash it by providing detailed and welcomed feedback. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Guewen Baconnier + +Do not contact contributors directly about support or help with technical issues. + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. + diff --git a/ext/3rd-party-addons/component_event/__init__.py b/ext/3rd-party-addons/component_event/__init__.py new file mode 100644 index 00000000..47e8136c --- /dev/null +++ b/ext/3rd-party-addons/component_event/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +from . import core +from . import components +from . import models + +# allow public API 'from odoo.addons.component_event import skip_if' +from .components.event import skip_if # noqa diff --git a/ext/3rd-party-addons/component_event/__manifest__.py b/ext/3rd-party-addons/component_event/__manifest__.py new file mode 100644 index 00000000..86c3a1d9 --- /dev/null +++ b/ext/3rd-party-addons/component_event/__manifest__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +{'name': 'Components Events', + 'version': '11.0.1.0.0', + 'author': 'Camptocamp,' + 'Odoo Community Association (OCA)', + 'website': 'https://www.camptocamp.com', + 'license': 'AGPL-3', + 'category': 'Generic Modules', + 'depends': ['component', + ], + 'external_dependencies': { + 'python': ['cachetools'], + }, + 'data': [], + 'installable': True, + } diff --git a/ext/3rd-party-addons/component_event/components/__init__.py b/ext/3rd-party-addons/component_event/components/__init__.py new file mode 100644 index 00000000..7351619d --- /dev/null +++ b/ext/3rd-party-addons/component_event/components/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import event diff --git a/ext/3rd-party-addons/component_event/components/event.py b/ext/3rd-party-addons/component_event/components/event.py new file mode 100644 index 00000000..54806934 --- /dev/null +++ b/ext/3rd-party-addons/component_event/components/event.py @@ -0,0 +1,294 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" +Events +====== + +Events are a notification system. + +On one side, one or many listeners await for an event to happen. On +the other side, when such event happen, a notification is sent to +the listeners. + +An example of event is: 'when a record has been created'. + +The event system allows to write the notification code in only one place, in +one Odoo addon, and to write as many listeners as we want, in different places, +different addons. + +We'll see below how the ``on_record_create`` is implemented. + +Notifier +-------- + +The first thing is to find where/when the notification should be sent. +For the creation of a record, it is in :meth:`odoo.models.BaseModel.create`. +We can inherit from the `'base'` model to add this line: + +:: + + class Base(models.AbstractModel): + _inherit = 'base' + + @api.model + def create(self, vals): + record = super(Base, self).create(vals) + self._event('on_record_create').notify(record, fields=vals.keys()) + return record + +The :meth:`..models.base.Base._event` method has been added to the `'base'` +model, so an event can be notified from any model. The +:meth:`CollectedEvents.notify` method triggers the event and forward the +arguments to the listeners. + +This should be done only once. See :class:`..models.base.Base` for a list of +events that are implemented in the `'base'` model. + +Listeners +--------- + +Listeners are Components that respond to the event names. +The components must have a ``_usage`` equals to ``'event.listener'``, but it +doesn't to be set manually if the component inherits from +``'base.event.listener'`` + +Here is how we would log something each time a record is created:: + + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self, record, fields=None): + _logger.info("%r has been created", record) + +Many listeners such as this one could be added for the same event. + + +Collection and models +--------------------- + +In the example above, the listeners is global. It will be executed for any +model and collection. You can also restrict a listener to only a collection or +model, using the ``_collection`` or ``_apply_on`` attributes. + +:: + + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + _collection = 'magento.backend' + + def on_record_create(self, record, fields=None): + _logger.info("%r has been created", record) + + + class MyModelEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + _apply_on = ['res.users'] + + def on_record_create(self, record, fields=None): + _logger.info("%r has been created", record) + + +If you want an event to be restricted to a collection, the +notification must also precise the collection, otherwise all listeners +will be executed:: + + + collection = self.env['magento.backend'] + self._event('on_foo_created', collection=collection).notify(record, vals) + +An event can be skipped based on a condition evaluated from the notified +arguments. See :func:`skip_if` + + +""" + +import logging +import operator + +from collections import defaultdict +from functools import wraps + +from odoo.addons.component.core import AbstractComponent, Component + +_logger = logging.getLogger(__name__) + +try: + from cachetools import LRUCache, cachedmethod, keys +except ImportError: + _logger.debug("Cannot import 'cachetools'.") + +# Number of items we keep in LRU cache when we collect the events. +# 1 item means: for an event name, model_name, collection, return +# the event methods +DEFAULT_EVENT_CACHE_SIZE = 512 + + +def skip_if(cond): + """ Decorator allowing to skip an event based on a condition + + The condition is a python lambda expression, which takes the + same arguments than the event. + + Example:: + + @skip_if(lambda self, *args, **kwargs: + self.env.context.get('connector_no_export')) + def on_record_write(self, record, fields=None): + _logger('I'll delay a job, but only if we didn't disabled ' + ' the export with a context key') + record.with_delay().export_record() + + @skip_if(lambda self, record, kind: kind == 'complete') + def on_record_write(self, record, kind): + _logger("I'll delay a job, but only if the kind is 'complete'") + record.with_delay().export_record() + + """ + def skip_if_decorator(func): + @wraps(func) + def func_wrapper(*args, **kwargs): + if cond(*args, **kwargs): + return + else: + return func(*args, **kwargs) + + return func_wrapper + return skip_if_decorator + + +class CollectedEvents(object): + """ Event methods ready to be notified + + This is a rather internal class. An instance of this class + is prepared by the :class:`EventCollecter` when we need to notify + the listener that the event has been triggered. + + :meth:`EventCollecter.collect_events` collects the events, + feed them to the instance, so we can use the :meth:`notify` method + that will forward the arguments and keyword arguments to the + listeners of the event. + :: + + >>> # collecter is an instance of CollectedEvents + >>> collecter.collect_events('on_record_create').notify(something) + + """ + + def __init__(self, events): + self.events = events + + def notify(self, *args, **kwargs): + """ Forward the arguments to every listeners of an event """ + for event in self.events: + event(*args, **kwargs) + + +class EventCollecter(Component): + """ Component that collects the event from an event name + + For doing so, it searches all the components that respond to the + ``event.listener`` ``_usage`` and having an event of the same + name. + + Then it feeds the events to an instance of :class:`EventCollecter` + and return it to the caller. + + It keeps the results in a cache, the Component is rebuilt when + the Odoo's registry is rebuilt, hence the cache is cleared as well. + + An event always starts with ``on_``. + + Note that the special + :class:`odoo.addons.component_event.core.EventWorkContext` class should be + used for this Component, because it can work + without a collection. + + It is used by :meth:`odoo.addons.component_event.models.base.Base._event`. + + """ + _name = 'base.event.collecter' + + @classmethod + def _complete_component_build(cls): + """ Create a cache on the class when the component is built """ + super(EventCollecter, cls)._complete_component_build() + # the _cache being on the component class, which is + # dynamically rebuild when odoo registry is rebuild, we + # are sure that the result is always the same for a lookup + # until the next rebuild of odoo's registry + cls._cache = LRUCache(maxsize=DEFAULT_EVENT_CACHE_SIZE) + + @cachedmethod(operator.attrgetter('_cache'), + key=lambda self, name: keys.hashkey( + self.work.collection._name + if self.work._collection is not None else None, + self.work.model_name, + name) + ) + def _collect_events(self, name): + events = defaultdict(set) + collection_name = (self.work.collection._name + if self.work._collection is not None + else None) + component_classes = self.work.components_registry.lookup( + collection_name=collection_name, + usage='event.listener', + model_name=self.work.model_name, + ) + for cls in component_classes: + if cls.has_event(name): + events[cls].add(name) + return events + + def _init_collected_events(self, class_events): + events = set() + for cls, names in class_events.items(): + for name in names: + component = cls(self.work) + events.add(getattr(component, name)) + return events + + def collect_events(self, name): + """ Collect the events of a given name """ + if not name.startswith('on_'): + raise ValueError("an event name always starts with 'on_'") + + events = self._init_collected_events(self._collect_events(name)) + return CollectedEvents(events) + + +class EventListener(AbstractComponent): + """ Base Component for the Event listeners + + Events must be methods starting with ``on_``. + + Example: :class:`RecordsEventListener` + + """ + _name = 'base.event.listener' + _usage = 'event.listener' + + @classmethod + def has_event(cls, name): + """ Indicate if the class has an event of this name """ + return name in cls._events + + @classmethod + def _build_event_listener_component(cls): + """ Make a list of events listeners for this class """ + events = set([]) + if not cls._abstract: + for attr_name in dir(cls): + if attr_name.startswith('on_'): + events.add(attr_name) + cls._events = events + + @classmethod + def _complete_component_build(cls): + super(EventListener, cls)._complete_component_build() + cls._build_event_listener_component() diff --git a/ext/3rd-party-addons/component_event/core.py b/ext/3rd-party-addons/component_event/core.py new file mode 100644 index 00000000..fd76375e --- /dev/null +++ b/ext/3rd-party-addons/component_event/core.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" +Events Internals +================ + +Core classes for the events system. + + +""" + + +from odoo.addons.component.core import WorkContext + + +class EventWorkContext(WorkContext): + """ Work context used by the Events internals + + Should not be used outside of the events internals. + The work context to use generally is + :class:`odoo.addons.component.core.WorkContext` or your own + subclass. + + The events are a special kind of components because they are + not attached to any collection (they can but not the main use case). + + So the work context must not need to have a collection, but when + it has no collection, it must at least have an 'env'. + + When no collection is provided, the methods to get the Components + cannot be used, but :meth:`work_on` can be used to switch back to + a :class:`odoo.addons.component.core.WorkContext` with collection. + This is needed when one want to get a component for a collection + from inside an event listener. + + """ + + def __init__(self, model_name=None, collection=None, env=None, + components_registry=None, **kwargs): + if not (collection is not None or env): + raise ValueError('collection or env is required') + if collection and env: + # when a collection is used, the env will be the one of + # the collection + raise ValueError('collection and env cannot both be provided') + + self.env = env + super(EventWorkContext, self).__init__( + model_name=model_name, collection=collection, + components_registry=components_registry, + **kwargs + ) + if self._env: + self._propagate_kwargs.remove('collection') + self._propagate_kwargs.append('env') + + @property + def env(self): + """ Return the current Odoo env """ + if self._env: + return self._env + return super(EventWorkContext, self).env + + @env.setter + def env(self, value): + self._env = value + + @property + def collection(self): + """ Return the current Odoo env """ + if self._collection is not None: + return self._collection + raise ValueError('No collection, it is optional for EventWorkContext') + + @collection.setter + def collection(self, value): + self._collection = value + + def work_on(self, model_name=None, collection=None): + """ Create a new work context for another model keeping attributes + + Used when one need to lookup components for another model. + + Used on an EventWorkContext, it switch back to a normal + WorkContext. It means we are inside an event listener, and + we want to get a component. We need to set a collection + to be able to get components. + """ + if self._collection is None and collection is None: + raise ValueError('you must provide a collection to work with') + if collection is not None: + if self.env is not collection.env: + raise ValueError('the Odoo env of the collection must be ' + 'the same than the current one') + kwargs = {attr_name: getattr(self, attr_name) + for attr_name in self._propagate_kwargs} + kwargs.pop('env', None) + if collection is not None: + kwargs['collection'] = collection + if model_name is not None: + kwargs['model_name'] = model_name + return WorkContext(**kwargs) + + def component_by_name(self, name, model_name=None): + if self._collection is not None: + # switch to a normal WorkContext + work = self.work_on(collection=self._collection, + model_name=model_name) + else: + raise TypeError( + "Can't be used on an EventWorkContext without collection. " + "The collection must be known to find components.\n" + "Hint: you can set the collection and get a component with:\n" + ">>> work.work_on(collection=self.env[...].browse(...))\n" + ">>> work.component_by_name(name, model_name=model_name)" + ) + return work.component_by_name(name, model_name=model_name) + + def component(self, usage=None, model_name=None): + if self._collection is not None: + # switch to a normal WorkContext + work = self.work_on(collection=self._collection, + model_name=model_name) + else: + raise TypeError( + "Can't be used on an EventWorkContext without collection. " + "The collection must be known to find components.\n" + "Hint: you can set the collection and get a component with:\n" + ">>> work.work_on(collection=self.env[...].browse(...))\n" + ">>> work.component(usage=usage, model_name=model_name)" + ) + return work.component(usage=usage, model_name=model_name) + + def many_components(self, usage=None, model_name=None): + if self._collection is not None: + # switch to a normal WorkContext + work = self.work_on(collection=self._collection, + model_name=model_name) + else: + raise TypeError( + "Can't be used on an EventWorkContext without collection. " + "The collection must be known to find components.\n" + "Hint: you can set the collection and get a component with:\n" + ">>> work.work_on(collection=self.env[...].browse(...))\n" + ">>> work.many_components(usage=usage, model_name=model_name)" + ) + return work.component(usage=usage, model_name=model_name) + + def __str__(self): + return ("EventWorkContext(%s,%s)" % + (repr(self._env or self._collection), self.model_name)) diff --git a/ext/3rd-party-addons/component_event/models/__init__.py b/ext/3rd-party-addons/component_event/models/__init__.py new file mode 100644 index 00000000..a61d43eb --- /dev/null +++ b/ext/3rd-party-addons/component_event/models/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import base diff --git a/ext/3rd-party-addons/component_event/models/base.py b/ext/3rd-party-addons/component_event/models/base.py new file mode 100644 index 00000000..e4879f6b --- /dev/null +++ b/ext/3rd-party-addons/component_event/models/base.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" +Base Model +========== + +Extend the 'base' Odoo Model to add Events related features. + + +""" + +from odoo import api, models +from odoo.addons.component.core import _component_databases +from ..components.event import CollectedEvents +from ..core import EventWorkContext + + +class Base(models.AbstractModel): + """ The base model, which is implicitly inherited by all models. + + Add an :meth:`_event` method to all Models. This method allows to + trigger events. + + It also notifies the following events: + + * ``on_record_create(self, record, fields=None)`` + * ``on_record_write(self, record, fields=none)`` + * ``on_record_unlink(self, record)`` + + ``on_record_unlink`` is notified just *before* the unlink is done. + + """ + _inherit = 'base' + + def _event(self, name, collection=None, components_registry=None): + """ Collect events for notifications + + Usage:: + + @api.multi + def button_do_something(self): + for record in self: + # do something + self._event('on_do_something').notify('something') + + With this line, every listener having a ``on_do_something`` method + with be called and receive 'something' as argument. + + See: :mod:`..components.event` + + :param name: name of the event, start with 'on_' + :param collection: optional collection to filter on, only + listeners with similar ``_collection`` will be + notified + :param components_registry: component registry for lookups, + mainly used for tests + :type components_registry: + :class:`odoo.addons.components.core.ComponentRegistry` + + + """ + dbname = self.env.cr.dbname + comp_registry = ( + components_registry or _component_databases.get(dbname) + ) + if not comp_registry or not comp_registry.ready: + # No event should be triggered before the registry has been loaded + # This is a very special case, when the odoo registry is being + # built, it calls odoo.modules.loading.load_modules(). + # This function might trigger events (by writing on records, ...). + # But at this point, the component registry is not guaranteed + # to be ready, and anyway we should probably not trigger events + # during the initialization. Hence we return an empty list of + # events, the 'notify' calls will do nothing. + return CollectedEvents([]) + + model_name = self._name + if collection is not None: + work = EventWorkContext(collection=collection, + model_name=model_name, + components_registry=components_registry) + else: + work = EventWorkContext(env=self.env, model_name=model_name, + components_registry=components_registry) + + collecter = work._component_class_by_name('base.event.collecter')(work) + return collecter.collect_events(name) + + @api.model + def create(self, vals): + record = super(Base, self).create(vals) + fields = list(vals.keys()) + self._event('on_record_create').notify(record, fields=fields) + return record + + @api.multi + def write(self, vals): + result = super(Base, self).write(vals) + fields = list(vals.keys()) + for record in self: + self._event('on_record_write').notify(record, fields=fields) + return result + + @api.multi + def unlink(self): + for record in self: + self._event('on_record_unlink').notify(record) + result = super(Base, self).unlink() + return result diff --git a/ext/3rd-party-addons/component_event/tests/__init__.py b/ext/3rd-party-addons/component_event/tests/__init__.py new file mode 100644 index 00000000..3fa87e4d --- /dev/null +++ b/ext/3rd-party-addons/component_event/tests/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import test_event diff --git a/ext/3rd-party-addons/component_event/tests/test_event.py b/ext/3rd-party-addons/component_event/tests/test_event.py new file mode 100644 index 00000000..e92e532f --- /dev/null +++ b/ext/3rd-party-addons/component_event/tests/test_event.py @@ -0,0 +1,432 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +import mock +import unittest + +from odoo.addons.component.tests.common import ( + ComponentRegistryCase, + TransactionComponentRegistryCase, +) +from odoo.addons.component.core import Component +from odoo.addons.component_event.core import EventWorkContext +from odoo.addons.component_event.components.event import skip_if + + +class TestEventWorkContext(unittest.TestCase): + """ Test Events Components """ + + def setUp(self): + super(TestEventWorkContext, self).setUp() + self.env = mock.MagicMock(name='env') + self.record = mock.MagicMock(name='record') + self.components_registry = mock.MagicMock(name='ComponentRegistry') + + def test_env(self): + """ WorkContext with env """ + work = EventWorkContext(model_name='res.users', env=self.env, + components_registry=self.components_registry) + self.assertEqual(self.env, work.env) + self.assertEqual('res.users', work.model_name) + with self.assertRaises(ValueError): + # pylint: disable=W0104 + work.collection # noqa + + def test_collection(self): + """ WorkContext with collection """ + env = mock.MagicMock(name='env') + collection = mock.MagicMock(name='collection') + collection.env = env + work = EventWorkContext(model_name='res.users', collection=collection, + components_registry=self.components_registry) + self.assertEqual(collection, work.collection) + self.assertEqual(env, work.env) + self.assertEqual('res.users', work.model_name) + + def test_env_and_collection(self): + """ WorkContext with collection and env is forbidden """ + env = mock.MagicMock(name='env') + collection = mock.MagicMock(name='collection') + collection.env = env + with self.assertRaises(ValueError): + EventWorkContext(model_name='res.users', collection=collection, + env=env, + components_registry=self.components_registry) + + def test_missing(self): + """ WorkContext with collection and env is forbidden """ + with self.assertRaises(ValueError): + EventWorkContext(model_name='res.users', + components_registry=self.components_registry) + + def test_env_work_on(self): + """ WorkContext propagated through work_on """ + env = mock.MagicMock(name='env') + collection = mock.MagicMock(name='collection') + collection.env = env + work = EventWorkContext(env=env, model_name='res.users', + components_registry=self.components_registry) + work2 = work.work_on(model_name='res.partner', collection=collection) + self.assertEqual('WorkContext', work2.__class__.__name__) + self.assertEqual(env, work2.env) + self.assertEqual('res.partner', work2.model_name) + self.assertEqual(self.components_registry, work2.components_registry) + with self.assertRaises(ValueError): + # pylint: disable=W0104 + work.collection # noqa + + def test_collection_work_on(self): + """ WorkContext propagated through work_on """ + env = mock.MagicMock(name='env') + collection = mock.MagicMock(name='collection') + collection.env = env + work = EventWorkContext(collection=collection, model_name='res.users', + components_registry=self.components_registry) + work2 = work.work_on(model_name='res.partner') + self.assertEqual('WorkContext', work2.__class__.__name__) + self.assertEqual(collection, work2.collection) + self.assertEqual(env, work2.env) + self.assertEqual('res.partner', work2.model_name) + self.assertEqual(self.components_registry, work2.components_registry) + + def test_collection_work_on_collection(self): + """ WorkContext collection changed with work_on """ + env = mock.MagicMock(name='env') + collection = mock.MagicMock(name='collection') + collection.env = env + work = EventWorkContext(model_name='res.users', env=env, + components_registry=self.components_registry) + work2 = work.work_on(collection=collection) + # when work_on is used inside an event component, we want + # to switch back to a normal WorkContext, because we don't + # need anymore the EventWorkContext + self.assertEqual('WorkContext', work2.__class__.__name__) + self.assertEqual(collection, work2.collection) + self.assertEqual(env, work2.env) + self.assertEqual('res.users', work2.model_name) + self.assertEqual(self.components_registry, work2.components_registry) + + +class TestEvent(ComponentRegistryCase): + """ Test Events Components """ + + def setUp(self): + super(TestEvent, self).setUp() + self._load_module_components('component_event') + + # get the collecter to notify the event + # we don't mind about the collection and the model here, + # the events we test are global + env = mock.MagicMock() + self.work = EventWorkContext(model_name='res.users', env=env, + components_registry=self.comp_registry) + self.collecter = self.comp_registry['base.event.collecter'](self.work) + + def test_event(self): + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self, recipient, something, fields=None): + recipient.append(('OK', something, fields)) + + MyEventListener._build_component(self.comp_registry) + + something = object() + fields = ['name', 'code'] + + # as there is no return value by the event, we + # modify this recipient to check it has been called + recipient = [] + + # collect the event and notify it + self.collecter.collect_events('on_record_create').notify( + recipient, something, fields=fields + ) + self.assertEqual([('OK', something, fields)], recipient) + + def test_collect_several(self): + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self, recipient, something, fields=None): + recipient.append(('OK', something, fields)) + + class MyOtherEventListener(Component): + _name = 'my.other.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self, recipient, something, fields=None): + recipient.append(('OK', something, fields)) + + MyEventListener._build_component(self.comp_registry) + MyOtherEventListener._build_component(self.comp_registry) + + something = object() + fields = ['name', 'code'] + + # as there is no return value by the event, we + # modify this recipient to check it has been called + recipient = [] + + # collect the event and notify them + collected = self.collecter.collect_events('on_record_create') + self.assertEqual(2, len(collected.events)) + + collected.notify(recipient, something, fields=fields) + self.assertEqual([('OK', something, fields), + ('OK', something, fields)], recipient) + + def test_event_cache(self): + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self): + pass + + MyEventListener._build_component(self.comp_registry) + + # collect the event + collected = self.collecter.collect_events('on_record_create') + # CollectedEvents.events contains the collected events + self.assertEqual(1, len(collected.events)) + event = list(collected.events)[0] + self.assertEqual(self.work, event.__self__.work) + self.assertEqual(self.work.env, event.__self__.work.env) + + # build and register a new listener + class MyOtherEventListener(Component): + _name = 'my.other.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self): + pass + + MyOtherEventListener._build_component(self.comp_registry) + + # get a new collecter and check that we it finds the same + # events even if we built a new one: it means the cache works + env = mock.MagicMock() + work = EventWorkContext(model_name='res.users', env=env, + components_registry=self.comp_registry) + collecter = self.comp_registry['base.event.collecter'](work) + collected = collecter.collect_events('on_record_create') + # CollectedEvents.events contains the collected events + self.assertEqual(1, len(collected.events)) + event = list(collected.events)[0] + self.assertEqual(work, event.__self__.work) + self.assertEqual(env, event.__self__.work.env) + + # if we empty the cache, as it on the class, both collecters + # should now find the 2 events + collecter._cache.clear() + self.comp_registry._cache.clear() + # CollectedEvents.events contains the collected events + self.assertEqual( + 2, + len(collecter.collect_events('on_record_create').events) + ) + self.assertEqual( + 2, + len(self.collecter.collect_events('on_record_create').events) + ) + + def test_event_cache_collection(self): + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self): + pass + + MyEventListener._build_component(self.comp_registry) + + # collect the event + collected = self.collecter.collect_events('on_record_create') + # CollectedEvents.events contains the collected events + self.assertEqual(1, len(collected.events)) + + # build and register a new listener + class MyOtherEventListener(Component): + _name = 'my.other.event.listener' + _inherit = 'base.event.listener' + _collection = 'base.collection' + + def on_record_create(self): + pass + + MyOtherEventListener._build_component(self.comp_registry) + + # get a new collecter and check that we it finds the same + # events even if we built a new one: it means the cache works + collection = mock.MagicMock(name='base.collection') + collection._name = 'base.collection' + collection.env = mock.MagicMock() + work = EventWorkContext(model_name='res.users', collection=collection, + components_registry=self.comp_registry) + collecter = self.comp_registry['base.event.collecter'](work) + collected = collecter.collect_events('on_record_create') + # for a different collection, we should not have the same + # cache entry + self.assertEqual(2, len(collected.events)) + + def test_event_cache_model_name(self): + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self): + pass + + MyEventListener._build_component(self.comp_registry) + + # collect the event + collected = self.collecter.collect_events('on_record_create') + # CollectedEvents.events contains the collected events + self.assertEqual(1, len(collected.events)) + + # build and register a new listener + class MyOtherEventListener(Component): + _name = 'my.other.event.listener' + _inherit = 'base.event.listener' + _apply_on = ['res.country'] + + def on_record_create(self): + pass + + MyOtherEventListener._build_component(self.comp_registry) + + # get a new collecter and check that we it finds the same + # events even if we built a new one: it means the cache works + env = mock.MagicMock() + work = EventWorkContext(model_name='res.country', env=env, + components_registry=self.comp_registry) + collecter = self.comp_registry['base.event.collecter'](work) + collected = collecter.collect_events('on_record_create') + # for a different collection, we should not have the same + # cache entry + self.assertEqual(2, len(collected.events)) + + def test_skip_if(self): + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self, msg): + assert True + + class MyOtherEventListener(Component): + _name = 'my.other.event.listener' + _inherit = 'base.event.listener' + + @skip_if(lambda self, msg: msg == 'foo') + def on_record_create(self, msg): + assert False + + self._build_components(MyEventListener, MyOtherEventListener) + + # collect the event and notify it + collected = self.collecter.collect_events('on_record_create') + self.assertEqual(2, len(collected.events)) + collected.notify('foo') + + +class TestEventFromModel(TransactionComponentRegistryCase): + """ Test Events Components from Models """ + + def setUp(self): + super(TestEventFromModel, self).setUp() + self._load_module_components('component_event') + + def test_event_from_model(self): + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_foo(self, record, name): + record.name = name + + MyEventListener._build_component(self.comp_registry) + + partner = self.env['res.partner'].create({'name': 'test'}) + # Normally you would not pass a components_registry, + # this is for the sake of the test, letting it empty + # will use the global registry. + # In a real code it would look like: + # partner._event('on_foo').notify('bar') + events = partner._event('on_foo', + components_registry=self.comp_registry) + events.notify(partner, 'bar') + self.assertEqual('bar', partner.name) + + def test_event_filter_on_model(self): + class GlobalListener(Component): + _name = 'global.event.listener' + _inherit = 'base.event.listener' + + def on_foo(self, record, name): + record.name = name + + class PartnerListener(Component): + _name = 'partner.event.listener' + _inherit = 'base.event.listener' + _apply_on = ['res.partner'] + + def on_foo(self, record, name): + record.ref = name + + class UserListener(Component): + _name = 'user.event.listener' + _inherit = 'base.event.listener' + _apply_on = ['res.users'] + + def on_foo(self, record, name): + assert False + + self._build_components(GlobalListener, PartnerListener, UserListener) + + partner = self.env['res.partner'].create({'name': 'test'}) + partner._event( + 'on_foo', + components_registry=self.comp_registry + ).notify(partner, 'bar') + self.assertEqual('bar', partner.name) + self.assertEqual('bar', partner.ref) + + def test_event_filter_on_collection(self): + class GlobalListener(Component): + _name = 'global.event.listener' + _inherit = 'base.event.listener' + + def on_foo(self, record, name): + record.name = name + + class PartnerListener(Component): + _name = 'partner.event.listener' + _inherit = 'base.event.listener' + _collection = 'collection.base' + + def on_foo(self, record, name): + record.ref = name + + class UserListener(Component): + _name = 'user.event.listener' + _inherit = 'base.event.listener' + _collection = 'magento.backend' + + def on_foo(self, record, name): + assert False + + self._build_components(GlobalListener, PartnerListener, UserListener) + + partner = self.env['res.partner'].create({'name': 'test'}) + events = partner._event( + 'on_foo', collection=self.env['collection.base'], + components_registry=self.comp_registry + ) + events.notify(partner, 'bar') + self.assertEqual('bar', partner.name) + self.assertEqual('bar', partner.ref) diff --git a/ext/3rd-party-addons/connector/AUTHORS b/ext/3rd-party-addons/connector/AUTHORS new file mode 100644 index 00000000..b311dd43 --- /dev/null +++ b/ext/3rd-party-addons/connector/AUTHORS @@ -0,0 +1,24 @@ +* Guewen Baconnier at Camptocamp +* Alexandre Fayolle at Camptocamp +* Benoit Guillot at Akretion +* Nicolas Bessi at Camptocamp +* Joël Grand-Guillaume at Camptocamp +* Arthur Vuillard at Akretion +* Sebastien Beau at Akretion +* Laurent Mignon at Acsone +* Leonardo Pistone at Camptocamp +* David Béal at Akretion +* Christophe Combelles at Anybox +* Stéphane Bidoul at Acsone +* Malte Jacobi at IBO / HTW +* Laetitia Gangloff at Acsone +* David Lefever at Taktik S.A. +* Jos de Graeve at Apertoso NV +* Jean-Sébastien Suzanne at Anybox +* Leonardo Donelli at MONK Software +* Mathias Colpaert +* Yannick Vaucher at Camptocamp +* Nicolas Piganeau at NDP Systèmes +* Florent Thomas at Mind And Go +* Matthieu Dietrich at Camptocamp +* Olivier Laurent at Acsone diff --git a/ext/3rd-party-addons/connector/CHANGES.rst b/ext/3rd-party-addons/connector/CHANGES.rst new file mode 100644 index 00000000..43bf9adf --- /dev/null +++ b/ext/3rd-party-addons/connector/CHANGES.rst @@ -0,0 +1,201 @@ +Changelog +--------- + +.. Future (?) +.. ~~~~~~~~~~ +.. +.. * + +Future (?) +~~~~~~~~~~ + +* Fix backend_to_m2o to extract id of the binding (https://github.com/OCA/connector/pull/194) +* Remove cancellation of jobs / active flag on jobs, now jobs are only set to + Done when NothingToDoJob is raised. + +9.0.1.0.2 (2016-03-03) +~~~~~~~~~~~~~~~~~~~~~~ + +* Fix: adapt to upstream api change to obtain db connection (https://github.com/OCA/connector/pull/179) + +9.0.1.0.1 (2016-03-03) +~~~~~~~~~~~~~~~~~~~~~~ + +* Enabled the JobRunner by default, with a default channels configuration of root:1 +* Removed the old workers +* Removed the broken dbfilter support (https://github.com/OCA/connector/issues/58) +* Cleaned the methods that have been deprecated in version 3.x + + +8.0.3.3.0 (2016-02-29) +~~~~~~~~~~~~~~~~~~~~~~ + +* Allow to define seconds when raising a RetryableJobError (https://github.com/OCA/connector/pull/124) +* Allow to ignore the retry counter when raising a RetryableJobError (https://github.com/OCA/connector/pull/124) +* Add 'mock_job_delay_to_direct' to ease tests on jobs (https://github.com/OCA/connector/pull/123) +* Add helper function to acquire Posgres advisory locks (https://github.com/OCA/connector/pull/138, https://github.com/OCA/connector/pull/139) +* Improvement of 'is_module_installed' which now uses the registry instead of db + cache (https://github.com/OCA/connector/pull/130) +* Security: Prevent to unpickle globals which are not jobs or whitelisted types (https://github.com/OCA/connector/pull/170) +* Fix: Manage non-ascii Postgres errors (https://github.com/OCA/connector/pull/167) +* Fix: ignore dbfilter containing %d or %h (https://github.com/OCA/connector/pull/166) +* Fix: correctly obtain the list of database with odoo is started with --no-database-list (https://github.com/OCA/connector/pull/164) +* Fix: Set job back to 'pending' in case of exception (https://github.com/OCA/connector/pull/150, https://github.com/OCA/connector/pull/151, https://github.com/OCA/connector/pull/152, https://github.com/OCA/connector/pull/155) +* Fix: Clear environment caches and recomputations upon failures (https://github.com/OCA/connector/pull/131) +* Fix: when a job fails, inactive users are no longer added to its followers (https://github.com/OCA/connector/pull/137) +* Fix: Set job to failed after non-retryable OperationalError (https://github.com/OCA/connector/pull/132) +* Fix: wrong model in connector_base_product's views (https://github.com/OCA/connector/pull/119) +* Various documentation improvements + + +3.2.0 (2015-09-10) +~~~~~~~~~~~~~~~~~~ + +* method 'install_in_connector' is now deprecated (https://github.com/OCA/connector/pull/74) +* Add a retry pattern for jobs (https://github.com/OCA/connector/pull/75, https://github.com/OCA/connector/pull/92) +* Use custom connector environments and instantiate them with needed attributes (https://github.com/OCA/connector/pull/108) +* A new default implementation for the binder (https://github.com/OCA/connector/pull/76) +* Translations are now automatically synchronized from Transifex +* Mapper: add modifier to follow m2o relations with dot notation (https://github.com/OCA/connector/pull/94) +* Mapper: add 'changed_by_fields' which indicates which source fields will output data (https://github.com/OCA/connector/pull/73) +* Allow to assign a default channel on @job functions (https://github.com/OCA/connector/pull/71) +* Fix: connector-runner: manages retryable errors (https://github.com/OCA/connector/pull/87) +* Fix: connector-runner: logging error when a capacity is None (https://github.com/OCA/connector/pull/98) +* Fix: connector-runner: shows a wrong job result on retried jobs (https://github.com/OCA/connector/pull/101) +* Fix: add an index on queue_job.worker_id (https://github.com/OCA/connector/pull/89) +* Fix: Tests: common.DB is gone in 8.0 stable (https://github.com/OCA/connector/pull/79) +* Fix: connector-runner: graceful stop mechanism (https://github.com/OCA/connector/pull/69) +* Fix: connector-runner: Wrong arguments position in a log message (https://github.com/OCA/connector/pull/67) + + +3.1.0 (2015-05-15) +~~~~~~~~~~~~~~~~~~ + +* New jobs runner (details on https://github.com/OCA/connector/pull/52) +* French documentation (https://github.com/OCA/connector/pull/57) +* Add ConnectorSession.from_env() (https://github.com/OCA/connector/pull/66) +* Fix: missing indexes on jobs (https://github.com/OCA/connector/pull/65) + + +3.0.0 (2015-04-01) +~~~~~~~~~~~~~~~~~~ + +/!\ Backwards incompatible changes inside. + +* Add ``openerp.api.Environment`` in ``Session`` + It is accessible in ``self.env`` in ``Session`` and all + ``ConnectorUnit`` instances. + Also in ``ConnectorUnit``, ``model`` returns the current (new api!) model: + + .. code-block:: python + + # On the current model + self.model.search([]) + self.model.browse(ids) + # on another model + self.env['res.users'].search([]) + self.env['res.users'].browse(ids) + +* Deprecate the CRUD methods in ``Session`` + + .. code-block:: python + + # NO + self.session.search('res.partner', []) + self.session.browse('res.partner', ids) + + # YES + self.env['res.partner'].search([]) + self.env['res.partner'].browse(ids) + +* ``Environment.set_lang()`` is removed. It was modifying the context + in place which is not possible with the new frozendict context. It + should be done with: + + .. code-block:: python + + with self.session.change_context(lang=lang_code): + ... + +* Add an argument on the Binders methods to return a browse record + + .. code-block:: python + + binder.to_openerp(magento_id, browse=True) + +* Shorten ``ConnectorUnit.get_binder_for_model`` to + ``ConnectorUnit.binder_for`` +* Shorten ``ConnectorUnit.get_connector_unit_for_model`` to + ``ConnectorUnit.unit_for`` +* Renamed ``Environment`` to ``ConnectorEnvironment`` to avoid + confusion with ``openerp.api.Environment`` +* Renamed the class attribute ``ConnectorUnit.model_name`` to + ``ConnectorUnit.for_model_name``. +* Added ``_base_binder``, ``_base_mapper``, ``_base_backend_adapter`` in + the synchronizers (Importer, Exporter) so it is no longer required to + override the ``binder``, ``mapper``, ``backend_adapter`` property + methods +* ``Session.change_context()`` now supports the same + argument/keyword arguments semantics than + ``openerp.model.BaseModel.with_context()``. +* Renamed ``ExportSynchronizer`` to ``Exporter`` +* Renamed ``ImportSynchronizer`` to ``Importer`` +* Renamed ``DeleteSynchronizer`` to ``Deleter`` +* ``Session.commit`` do not commit when tests are running +* Cleaned the methods that have been deprecated in version 2.x + + +2.2.0 (2014-05-26) +~~~~~~~~~~~~~~~~~~ + +* Job arguments can now contain unicode strings (thanks to Stéphane Bidoul) lp:1288187 +* List view of the jobs improved +* Jobs now support multicompany (thanks to Laurent Mignon) https://lists.launchpad.net/openerp-connector-community/msg00253.html) +* An action can be assigned to a job. The action is called with a button on the job and could be something like open a form view or an url. + +2.1.1 (2014-02-06) +~~~~~~~~~~~~~~~~~~ + +* A user can be blocked because he has no access to the model queue.job when a + job has been delayed. The creation of a job is low level and should not be + restrained by the accesses of the user. (lp:1276182) + +2.1.0 (2014-01-15 - warning: breaks compatibility) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Add a new optional keyword argument 'description' to the delay() function of a + job. If given, the description is used as name of the queue.job record stored + in OpenERP and displayed in the list of jobs. +* Fix: assignment of jobs to workers respect the priority of the jobs (lp:1252681) +* Pass a new parameter to listeners of 'on_record_create' ( vals: field values + of the new record, e.g {'field_name': field_value, ...}) +* Replace the list of updated fields passed to listeners of 'on_record_write' + by a dictionary of updated field values e.g {'field_name': field_value, ...} +* Add the possibility to use 'Modifiers' functions in the 'direct + mappings' (details in the documentation of the Mapper class) +* When a job a delayed, the job's UUID is returned by the delay() function +* Refactoring of mappers. Much details here: + https://code.launchpad.net/~openerp-connector-core-editors/openerp-connector/7.0-connector-mapper-refactor/+merge/194485 + +2.0.1 (2013-09-12) +~~~~~~~~~~~~~~~~~~ + +* Developers of addons do no longer need to create an AbstractModel with a _name 'name_of_the_module.installed', + instead, they just have to call connector.connector.install_in_connector() lp:1196859 +* Added a script `openerp-connector-worker` to start processes for Jobs Workers when running OpenERP is multiprocessing +* Fix: inheritance broken when an orm.Model inherit from an orm.AbstractModel. One effect was that the mail.thread features were no longer working (lp:1233355) +* Fix: do no fail to start when OpenERP has access to a not-OpenERP database (lp:1233388) + + +2.0.0 +~~~~~ + +* First release + + +.. + Model: + 2.0.1 (date of release) + ~~~~~~~~~~~~~~~~~~~~~~~ + + * change 1 + * change 2 diff --git a/ext/3rd-party-addons/connector/README.rst b/ext/3rd-party-addons/connector/README.rst new file mode 100644 index 00000000..ec2be42f --- /dev/null +++ b/ext/3rd-party-addons/connector/README.rst @@ -0,0 +1,86 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :alt: License + +Connector +========= + +This is a framework designed to build connectors with external systems, +usually called ``Backends`` in the documentation. + +Documentation: http://odoo-connector.com + +It features: + +* A jobs queue + + In which the connectors can push functions (synchronization tasks) + to be executed later. + +* An event pattern + + The connectors can subscribe listener functions on the events, + executed when the events are fired. + +* Connector base classes + + Called ``ConnectorUnit``. + + Include base classes for the use in connectors, ready to be extended: + + * ``Synchronizer``: flow of an import or export + * ``Mapper``: transform a record according to mapping rules + * ``Binder``: link external IDs with local IDS + * ``BackendAdapter``: adapter interface for the exchanges with the backend + * But ``ConnectorUnit`` can be extended to accomplish any task + +* A multi-backend support + + Each ``ConnectorUnit`` can be registered amongst a backend type (eg. + Magento) and a backend version (allow to have a different ``Mapper`` + for each backend's version for instance) + +It is used for example used to connect Magento_ and Prestashop_, but +also used with Solr, CMIS, ... + +.. _Magento: http://odoo-magento-connector.com +.. _Prestashop: https://github.com/OCA/connector-prestashop + +Configuration and usage +======================= + +This module does nothing on its own. It is a ground for developing +advanced connector modules. For further information, please go on: +http://odoo-connector.com + + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed feedback +`here `_. + + +Credits +======= + +Contributors +------------ + +Read the `contributors list`_ + +.. _contributors list: ./AUTHORS + +Maintainer +---------- + +.. image:: http://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: http://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. + +To contribute to this module, please visit http://odoo-community.org. diff --git a/ext/3rd-party-addons/connector/__init__.py b/ext/3rd-party-addons/connector/__init__.py new file mode 100644 index 00000000..57a162a3 --- /dev/null +++ b/ext/3rd-party-addons/connector/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- +from . import components +from . import models diff --git a/ext/3rd-party-addons/connector/__manifest__.py b/ext/3rd-party-addons/connector/__manifest__.py new file mode 100644 index 00000000..c801e407 --- /dev/null +++ b/ext/3rd-party-addons/connector/__manifest__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Copyright 2013-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +{'name': 'Connector', + 'version': '11.0.1.0.0', + 'author': 'Camptocamp,Openerp Connector Core Editors,' + 'Odoo Community Association (OCA)', + 'website': 'http://odoo-connector.com', + 'license': 'AGPL-3', + 'category': 'Generic Modules', + 'depends': ['mail', + 'queue_job', + 'component', + 'component_event', + ], + 'data': ['security/connector_security.xml', + 'security/ir.model.access.csv', + 'views/checkpoint_views.xml', + 'views/connector_menu.xml', + 'views/setting_views.xml', + 'views/res_partner_views.xml', + ], + 'installable': True, + } diff --git a/ext/3rd-party-addons/connector/components/__init__.py b/ext/3rd-party-addons/connector/components/__init__.py new file mode 100644 index 00000000..a8e062d3 --- /dev/null +++ b/ext/3rd-party-addons/connector/components/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +from . import core +from . import backend_adapter +from . import binder +from . import mapper +from . import listener +from . import synchronizer diff --git a/ext/3rd-party-addons/connector/components/backend_adapter.py b/ext/3rd-party-addons/connector/components/backend_adapter.py new file mode 100644 index 00000000..70883056 --- /dev/null +++ b/ext/3rd-party-addons/connector/components/backend_adapter.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# Copyright 2013-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" + +Backend Adapter +=============== + +An external adapter has a common interface to speak with the backend. +It translates the basic orders (search, read, write) to the protocol +used by the backend. + +""" + +from odoo.addons.component.core import AbstractComponent + + +class BackendAdapter(AbstractComponent): + """ Base Backend Adapter for the connectors """ + + _name = 'base.backend.adapter' + _inherit = 'base.connector' + _usage = 'backend.adapter' + + +class CRUDAdapter(AbstractComponent): + """ Base External Adapter specialized in the handling + of records on external systems. + + This is an empty shell, Components can inherit and implement their own + implementation for the methods. + + """ + + _name = 'base.backend.adapter.crud' + _inherit = 'base.backend.adapter' + _usage = 'backend.adapter' + + def search(self, *args, **kwargs): + """ Search records according to some criterias + and returns a list of ids """ + raise NotImplementedError + + def read(self, *args, **kwargs): + """ Returns the information of a record """ + raise NotImplementedError + + def search_read(self, *args, **kwargs): + """ Search records according to some criterias + and returns their information""" + raise NotImplementedError + + def create(self, *args, **kwargs): + """ Create a record on the external system """ + raise NotImplementedError + + def write(self, *args, **kwargs): + """ Update records on the external system """ + raise NotImplementedError + + def delete(self, *args, **kwargs): + """ Delete a record on the external system """ + raise NotImplementedError diff --git a/ext/3rd-party-addons/connector/components/binder.py b/ext/3rd-party-addons/connector/components/binder.py new file mode 100644 index 00000000..fd89363c --- /dev/null +++ b/ext/3rd-party-addons/connector/components/binder.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2013-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" +Binders +======= + +Binders are components that know how to find the external ID for an +Odoo ID, how to find the Odoo ID for an external ID and how to +create the binding between them. + +""" + +from odoo import fields, models, tools +from odoo.addons.component.core import AbstractComponent + + +class Binder(AbstractComponent): + """ For one record of a model, capable to find an external or + internal id, or create the binding (link) between them + + This is a default implementation that can be inherited or reimplemented + in the connectors. + + This implementation assumes that binding models are ``_inherits`` of + the models they are binding. + + """ + + _name = 'base.binder' + _inherit = 'base.connector' + _usage = 'binder' + + _external_field = 'external_id' # override in sub-classes + _backend_field = 'backend_id' # override in sub-classes + _odoo_field = 'odoo_id' # override in sub-classes + _sync_date_field = 'sync_date' # override in sub-classes + + def to_internal(self, external_id, unwrap=False): + """ Give the Odoo recordset for an external ID + + :param external_id: external ID for which we want + the Odoo ID + :param unwrap: if True, returns the normal record + else return the binding record + :return: a recordset, depending on the value of unwrap, + or an empty recordset if the external_id is not mapped + :rtype: recordset + """ + bindings = self.model.with_context(active_test=False).search( + [(self._external_field, '=', tools.ustr(external_id)), + (self._backend_field, '=', self.backend_record.id)] + ) + if not bindings: + if unwrap: + return self.model.browse()[self._odoo_field] + return self.model.browse() + bindings.ensure_one() + if unwrap: + bindings = bindings[self._odoo_field] + return bindings + + def to_external(self, binding, wrap=False): + """ Give the external ID for an Odoo binding ID + + :param binding: Odoo binding for which we want the external id + :param wrap: if True, binding is a normal record, the + method will search the corresponding binding and return + the external id of the binding + :return: external ID of the record + """ + if isinstance(binding, models.BaseModel): + binding.ensure_one() + else: + binding = self.model.browse(binding) + if wrap: + binding = self.model.with_context(active_test=False).search( + [(self._odoo_field, '=', binding.id), + (self._backend_field, '=', self.backend_record.id), + ] + ) + if not binding: + return None + binding.ensure_one() + return binding[self._external_field] + return binding[self._external_field] + + def bind(self, external_id, binding): + """ Create the link between an external ID and an Odoo ID + + :param external_id: external id to bind + :param binding: Odoo record to bind + :type binding: int + """ + # Prevent False, None, or "", but not 0 + assert (external_id or external_id is 0) and binding, ( + "external_id or binding missing, " + "got: %s, %s" % (external_id, binding) + ) + # avoid to trigger the export when we modify the `external_id` + now_fmt = fields.Datetime.now() + if isinstance(binding, models.BaseModel): + binding.ensure_one() + else: + binding = self.model.browse(binding) + binding.with_context(connector_no_export=True).write( + {self._external_field: tools.ustr(external_id), + self._sync_date_field: now_fmt, + }) + + def unwrap_binding(self, binding): + """ For a binding record, gives the normal record. + + Example: when called with a ``magento.product.product`` id, + it will return the corresponding ``product.product`` id. + + :param browse: when True, returns a browse_record instance + rather than an ID + """ + if isinstance(binding, models.BaseModel): + binding.ensure_one() + else: + binding = self.model.browse(binding) + + return binding[self._odoo_field] + + def unwrap_model(self): + """ For a binding model, gives the normal model. + + Example: when called on a binder for ``magento.product.product``, + it will return ``product.product``. + """ + try: + column = self.model._fields[self._odoo_field] + except KeyError: + raise ValueError( + 'Cannot unwrap model %s, because it has no %s fields' + % (self.model._name, self._odoo_field)) + return column.comodel_name diff --git a/ext/3rd-party-addons/connector/components/core.py b/ext/3rd-party-addons/connector/components/core.py new file mode 100644 index 00000000..e7c32936 --- /dev/null +++ b/ext/3rd-party-addons/connector/components/core.py @@ -0,0 +1,130 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" + +Base Component +============== + +The connector proposes a 'base' Component, which can be used in +the ``_inherit`` of your own components. This is not a +requirement. It is already inherited by every component +provided by the Connector. + +Components are organized according to different usages. The connector suggests +5 main kinds of Components. Each might have a few different usages. You can be +as creative as you want when it comes to creating new ones though. + +One "usage" is responsible for a specific work, and alongside with the +collection (the backend) and the model, the usage will be used to find the +needed component for a task. + +Some of the Components have an implementation in the ``Connector`` addon, but +some are empty shells that need to be implemented in the different connectors. + +The usual categories are: + +:py:class:`~connector.components.binder.Binder` + The ``binders`` give the external ID or Odoo ID from respectively an + Odoo ID or an external ID. A default implementation is available. + + Most common usages: + + * ``binder`` + +:py:class:`~connector.components.mapper.Mapper` + The ``mappers`` transform a external record into an Odoo record or + conversely. + + Most common usages: + + * ``import.mapper`` + * ``export.mapper`` + +:py:class:`~connector.components.backend_adapter.BackendAdapter` + The ``backend.adapters`` implements the discussion with the ``backend's`` + APIs. They usually adapt their APIs to a common interface (CRUD). + + Most common usages: + + * ``backend.adapter`` + +:py:class:`~connector.components.synchronizer.Synchronizer` + A ``synchronizer`` is the main piece of a synchronization. It + orchestrates the flow of a synchronization and use the other + Components + + Most common usages: + + * ``record.importer`` + * ``record.exporter`` + * ``batch.importer`` + * ``batch.exporter`` + + +""" + +from odoo.addons.component.core import AbstractComponent +from odoo.addons.queue_job.exception import RetryableJobError +from ..database import pg_try_advisory_lock + + +class BaseConnectorComponent(AbstractComponent): + """ Base component for the connector + + Is inherited by every components of the Connector (Binder, Mapper, ...) + and adds a few methods which are of common usage in the connectors. + + """ + + _name = 'base.connector' + + @property + def backend_record(self): + """ Backend record we are working with """ + # backward compatibility + return self.work.collection + + def binder_for(self, model=None): + """ Shortcut to get Binder for a model + + Equivalent to: ``self.component(usage='binder', model_name='xxx')`` + + """ + return self.component(usage='binder', model_name=model) + + def advisory_lock_or_retry(self, lock, retry_seconds=1): + """ Acquire a Postgres transactional advisory lock or retry job + + When the lock cannot be acquired, it raises a + :exc:`odoo.addons.queue_job.exception.RetryableJobError` so the job + is retried after n ``retry_seconds``. + + Usage example: + + .. code-block:: python + + lock_name = 'import_record({}, {}, {}, {})'.format( + self.backend_record._name, + self.backend_record.id, + self.model._name, + self.external_id, + ) + self.advisory_lock_or_retry(lock_name, retry_seconds=2) + + See :func:`odoo.addons.connector.connector.pg_try_advisory_lock` for + details. + + :param lock: The lock name. Can be anything convertible to a + string. It needs to represent what should not be synchronized + concurrently, usually the string will contain at least: the + action, the backend name, the backend id, the model name, the + external id + :param retry_seconds: number of seconds after which a job should + be retried when the lock cannot be acquired. + """ + if not pg_try_advisory_lock(self.env, lock): + raise RetryableJobError('Could not acquire advisory lock', + seconds=retry_seconds, + ignore_retry=True) diff --git a/ext/3rd-party-addons/connector/components/listener.py b/ext/3rd-party-addons/connector/components/listener.py new file mode 100644 index 00000000..bee85528 --- /dev/null +++ b/ext/3rd-party-addons/connector/components/listener.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2013-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" +Listeners +========= + +Listeners are Components notified when events happen. +Documentation in :mod:`odoo.addons.component_event.components.event` + +The base listener for the connectors add a method +:meth:`ConnectorListener.no_connector_export` which can be used with +:func:`odoo.addons.component_event.skip_if`. + + +""" + +from odoo.addons.component.core import AbstractComponent + + +class ConnectorListener(AbstractComponent): + """ Base Backend Adapter for the connectors """ + + _name = 'base.connector.listener' + _inherit = ['base.connector', 'base.event.listener'] + + def no_connector_export(self, record): + """ Return if the 'connector_no_export' has been set in context + + To be used with :func:`odoo.addons.component_event.skip_if` + on Events:: + + from odoo.addons.component.core import Component + from odoo.addons.component_event import skip_if + + + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.connector.event.listener' + _apply_on = ['magento.res.partner'] + + @skip_if(lambda: self, record, *args, **kwargs: + self.no_connector_export(record)) + def on_record_write(self, record, fields=None): + record.with_delay().export_record() + + """ + return (record.env.context.get('no_connector_export') or + record.env.context.get('connector_no_export')) diff --git a/ext/3rd-party-addons/connector/components/mapper.py b/ext/3rd-party-addons/connector/components/mapper.py new file mode 100644 index 00000000..24d8f745 --- /dev/null +++ b/ext/3rd-party-addons/connector/components/mapper.py @@ -0,0 +1,1011 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" + +Mappers +======= + +Mappers are the components responsible to transform +external records into Odoo records and conversely. + +""" + +import logging +from collections import namedtuple +from contextlib import contextmanager + +from odoo import models +from odoo.addons.component.core import AbstractComponent +from odoo.addons.component.exception import NoComponentError +from ..exception import MappingError +import collections + + +_logger = logging.getLogger(__name__) + + +def mapping(func): + """ Decorator, declare that a method is a mapping method. + + It is then used by the :py:class:`Mapper` to convert the records. + + Usage:: + + @mapping + def any(self, record): + return {'output_field': record['input_field']} + + """ + func.is_mapping = True + return func + + +def changed_by(*args): + """ Decorator for the mapping methods (:py:func:`mapping`) + + When fields are modified in Odoo, we want to export only the + modified fields. Using this decorator, we can specify which fields + updates should trigger which mapping method. + + If ``changed_by`` is empty, the mapping is always active. + + As far as possible, this decorator should be used for the exports, + thus, when we do an update on only a small number of fields on a + record, the size of the output record will be limited to only the + fields really having to be exported. + + Usage:: + + @changed_by('input_field') + @mapping + def any(self, record): + return {'output_field': record['input_field']} + + :param ``*args``: field names which trigger the mapping when modified + + """ + def register_mapping(func): + func.changed_by = args + return func + return register_mapping + + +def only_create(func): + """ Decorator for the mapping methods (:py:func:`mapping`) + + A mapping decorated with ``only_create`` means that it has to be + used only for the creation of the records. + + Usage:: + + @only_create + @mapping + def any(self, record): + return {'output_field': record['input_field']} + + """ + func.only_create = True + return func + + +def none(field): + """ A modifier intended to be used on the ``direct`` mappings. + + Replace the False-ish values by None. + It can be used in a pipeline of modifiers when . + + Example:: + + direct = [(none('source'), 'target'), + (none(m2o_to_external('rel_id'), 'rel_id')] + + :param field: name of the source field in the record + :param binding: True if the relation is a binding record + """ + def modifier(self, record, to_attr): + if isinstance(field, collections.Callable): + result = field(self, record, to_attr) + else: + result = record[field] + if not result: + return None + return result + return modifier + + +def convert(field, conv_type): + """ A modifier intended to be used on the ``direct`` mappings. + + Convert a field's value to a given type. + + Example:: + + direct = [(convert('source', str), 'target')] + + :param field: name of the source field in the record + :param binding: True if the relation is a binding record + """ + def modifier(self, record, to_attr): + value = record[field] + if not value: + return False + return conv_type(value) + return modifier + + +def m2o_to_external(field, binding=None): + """ A modifier intended to be used on the ``direct`` mappings. + + For a many2one, get the external ID and returns it. + + When the field's relation is not a binding (i.e. it does not point to + something like ``magento.*``), the binding model needs to be provided + in the ``binding`` keyword argument. + + Example:: + + direct = [(m2o_to_external('country_id', + binding='magento.res.country'), 'country'), + (m2o_to_external('magento_country_id'), 'country')] + + :param field: name of the source field in the record + :param binding: name of the binding model is the relation is not a binding + """ + def modifier(self, record, to_attr): + if not record[field]: + return False + column = self.model._fields[field] + if column.type != 'many2one': + raise ValueError('The column %s should be a Many2one, got %s' % + (field, type(column))) + rel_id = record[field].id + if binding is None: + binding_model = column.comodel_name + else: + binding_model = binding + binder = self.binder_for(binding_model) + # if a relation is not a binding, we wrap the record in the + # binding, we'll return the id of the binding + wrap = bool(binding) + value = binder.to_external(rel_id, wrap=wrap) + if not value: + raise MappingError("Can not find an external id for record " + "%s in model %s %s wrapping" % + (rel_id, binding_model, + 'with' if wrap else 'without')) + return value + return modifier + + +def external_to_m2o(field, binding=None): + """ A modifier intended to be used on the ``direct`` mappings. + + For a field from a backend which is an ID, search the corresponding + binding in Odoo and returns it. + + When the field's relation is not a binding (i.e. it does not point to + something like ``magento.*``), the binding model needs to be provided + in the ``binding`` keyword argument. + + Example:: + + direct = [(external_to_m2o('country', binding='magento.res.country'), + 'country_id'), + (external_to_m2o('country'), 'magento_country_id')] + + :param field: name of the source field in the record + :param binding: name of the binding model is the relation is not a binding + """ + def modifier(self, record, to_attr): + if not record[field]: + return False + column = self.model._fields[to_attr] + if column.type != 'many2one': + raise ValueError('The column %s should be a Many2one, got %s' % + (to_attr, type(column))) + rel_id = record[field] + if binding is None: + binding_model = column.comodel_name + else: + binding_model = binding + binder = self.binder_for(binding_model) + # if we want the normal record, not a binding, + # we ask to the binder to unwrap the binding + unwrap = bool(binding) + record = binder.to_internal(rel_id, unwrap=unwrap) + if not record: + raise MappingError("Can not find an existing %s for external " + "record %s %s unwrapping" % + (binding_model, rel_id, + 'with' if unwrap else 'without')) + if isinstance(record, models.BaseModel): + return record.id + else: + _logger.debug( + 'Binder for %s returned an id, ' + 'returning a record should be preferred.', binding_model + ) + return record + return modifier + + +def follow_m2o_relations(field): + """A modifier intended to be used on ``direct`` mappings. + + 'Follows' Many2one relations and return the final field value. + + Examples: + Assuming model is ``product.product``:: + + direct = [ + (follow_m2o_relations('product_tmpl_id.categ_id.name'), 'cat')] + + :param field: field "path", using dots for relations as usual in Odoo + """ + def modifier(self, record, to_attr): + attrs = field.split('.') + value = record + for attr in attrs: + value = getattr(value, attr) + return value + return modifier + + +MappingDefinition = namedtuple('MappingDefinition', + ['changed_by', + 'only_create']) + + +class MapChild(AbstractComponent): + """ MapChild is responsible to convert items. + + Items are sub-records of a main record. + In this example, the items are the records in ``lines``:: + + sales = {'name': 'SO10', + 'lines': [{'product_id': 1, 'quantity': 2}, + {'product_id': 2, 'quantity': 2}]} + + A MapChild is always called from another :py:class:`Mapper` which + provides a ``children`` configuration. + + Considering the example above, the "main" :py:class:`Mapper` would + returns something as follows:: + + {'name': 'SO10', + 'lines': [(0, 0, {'product_id': 11, 'quantity': 2}), + (0, 0, {'product_id': 12, 'quantity': 2})]} + + A MapChild is responsible to: + + * Find the :py:class:`Mapper` to convert the items + * Possibly filter out some lines (can be done by inheriting + :py:meth:`skip_item`) + * Convert the items' records using the found :py:class:`Mapper` + * Format the output values to the format expected by Odoo or the + backend (as seen above with ``(0, 0, {values})`` + + A MapChild can be extended like any other + :py:class:`~component.core.Component`. + However, it is not mandatory to explicitly create a MapChild for + each children mapping, the default one will be used + (:py:class:`ImportMapChild` or :py:class:`ExportMapChild`). + + The implementation by default does not take care of the updates: if + I import a sales order 2 times, the lines will be duplicated. This + is not a problem as long as an importation should only support the + creation (typical for sales orders). It can be implemented on a + case-by-case basis by inheriting :py:meth:`get_item_values` and + :py:meth:`format_items`. + + """ + + _name = 'base.map.child' + _inherit = 'base.connector' + + def _child_mapper(self): + raise NotImplementedError + + def skip_item(self, map_record): + """ Hook to implement in sub-classes when some child + records should be skipped. + + The parent record is accessible in ``map_record``. + If it returns True, the current child record is skipped. + + :param map_record: record that we are converting + :type map_record: :py:class:`MapRecord` + """ + return False + + def get_items(self, items, parent, to_attr, options): + """ Returns the formatted output values of items from a main record + + :param items: list of item records + :type items: list + :param parent: parent record + :param to_attr: destination field (can be used for introspecting + the relation) + :type to_attr: str + :param options: dict of options, herited from the main mapper + :return: formatted output values for the item + + """ + mapper = self._child_mapper() + mapped = [] + for item in items: + map_record = mapper.map_record(item, parent=parent) + if self.skip_item(map_record): + continue + item_values = self.get_item_values(map_record, to_attr, options) + if item_values: + mapped.append(item_values) + return self.format_items(mapped) + + def get_item_values(self, map_record, to_attr, options): + """ Get the raw values from the child Mappers for the items. + + It can be overridden for instance to: + + * Change options + * Use a :py:class:`~connector.connector.Binder` to know if an + item already exists to modify an existing item, rather than to + add it + + :param map_record: record that we are converting + :type map_record: :py:class:`MapRecord` + :param to_attr: destination field (can be used for introspecting + the relation) + :type to_attr: str + :param options: dict of options, herited from the main mapper + + """ + return map_record.values(**options) + + def format_items(self, items_values): + """ Format the values of the items mapped from the child Mappers. + + It can be overridden for instance to add the Odoo + relationships commands ``(6, 0, [IDs])``, ... + + As instance, it can be modified to handle update of existing + items: check if an 'id' has been defined by + :py:meth:`get_item_values` then use the ``(1, ID, {values}``) + command + + :param items_values: mapped values for the items + :type items_values: list + + """ + return items_values + + +class ImportMapChild(AbstractComponent): + """ :py:class:`MapChild` for the Imports """ + + _name = 'base.map.child.import' + _inherit = 'base.map.child' + _usage = 'import.map.child' + + def _child_mapper(self): + return self.component(usage='import.mapper') + + def format_items(self, items_values): + """ Format the values of the items mapped from the child Mappers. + + It can be overridden for instance to add the Odoo + relationships commands ``(6, 0, [IDs])``, ... + + As instance, it can be modified to handle update of existing + items: check if an 'id' has been defined by + :py:meth:`get_item_values` then use the ``(1, ID, {values}``) + command + + :param items_values: list of values for the items to create + :type items_values: list + + """ + return [(0, 0, values) for values in items_values] + + +class ExportMapChild(AbstractComponent): + """ :py:class:`MapChild` for the Exports """ + + _name = 'base.map.child.export' + _inherit = 'base.map.child' + _usage = 'export.map.child' + + def _child_mapper(self): + return self.component(usage='export.mapper') + + +class Mapper(AbstractComponent): + """ A Mapper translates an external record to an Odoo record and + conversely. The output of a Mapper is a ``dict``. + + 3 types of mappings are supported: + + Direct Mappings + Example:: + + direct = [('source', 'target')] + + Here, the ``source`` field will be copied in the ``target`` field. + + A modifier can be used in the source item. + The modifier will be applied to the source field before being + copied in the target field. + It should be a closure function respecting this idiom:: + + def a_function(field): + ''' ``field`` is the name of the source field. + + Naming the arg: ``field`` is required for the conversion''' + def modifier(self, record, to_attr): + ''' self is the current Mapper, + record is the current record to map, + to_attr is the target field''' + return record[field] + return modifier + + And used like that:: + + direct = [ + (a_function('source'), 'target'), + ] + + A more concrete example of modifier:: + + def convert(field, conv_type): + ''' Convert the source field to a defined ``conv_type`` + (ex. str) before returning it''' + def modifier(self, record, to_attr): + value = record[field] + if not value: + return None + return conv_type(value) + return modifier + + And used like that:: + + direct = [ + (convert('myfield', float), 'target_field'), + ] + + More examples of modifiers: + + * :py:func:`convert` + * :py:func:`m2o_to_external` + * :py:func:`external_to_m2o` + + Method Mappings + A mapping method allows to execute arbitrary code and return one + or many fields:: + + @mapping + def compute_state(self, record): + # compute some state, using the ``record`` or not + state = 'pending' + return {'state': state} + + We can also specify that a mapping methods should be applied + only when an object is created, and never applied on further + updates:: + + @only_create + @mapping + def default_warehouse(self, record): + # get default warehouse + warehouse_id = ... + return {'warehouse_id': warehouse_id} + + Submappings + When a record contains sub-items, like the lines of a sales order, + we can convert the children using another Mapper:: + + children = [('items', 'line_ids', 'model.name')] + + It allows to create the sales order and all its lines with the + same call to :py:meth:`odoo.models.BaseModel.create()`. + + When using ``children`` for items of a record, we need to create + a :py:class:`Mapper` for the model of the items, and optionally a + :py:class:`MapChild`. + + Usage of a Mapper:: + + >>> mapper = self.component(usage='mapper') + >>> map_record = mapper.map_record(record) + >>> values = map_record.values() + >>> values = map_record.values(only_create=True) + >>> values = map_record.values(fields=['name', 'street']) + + """ + + _name = 'base.mapper' + _inherit = 'base.connector' + _usage = 'mapper' + + direct = [] # direct conversion of a field to another (from_attr, to_attr) + children = [] # conversion of sub-records (from_attr, to_attr, model) + + _map_methods = None + + _map_child_usage = None + _map_child_fallback = None + + @classmethod + def _build_mapper_component(cls): + """ Build a Mapper component + + When a Mapper component is built, we will look into every of its bases + and look for methods decorated by ``@mapping`` or ``@changed_by``. We + keep the definitions in a ``_map_methods`` attribute for later use by + the Mapper instances. + + The ``__bases__`` of a newly generated Component are of 2 kinds: + + * other dynamically generated components (below 'base' and + 'second.mapper') + * "real" Python classes applied on top of existing components (here + ThirdMapper) + + :: + + >>> cls.__bases__ + (, + , + ) + + This method traverses these bases, from the bottom to the top, and + merges the mapping definitions. It reuses the computed definitions + for the generated components (for which this code already ran), and + inspect the real classes to find mapping methods. + + """ + + map_methods = {} + for base in reversed(cls.__bases__): + if hasattr(base, '_map_methods'): + # this is already a dynamically generated Component, so we can + # use it's existing mappings + base_map_methods = base._map_methods or {} + for attr_name, definition in base_map_methods.items(): + if attr_name in map_methods: + # Update the existing @changed_by with the content + # of each base (it is mutated in place). + mapping_changed_by = map_methods[attr_name].changed_by + mapping_changed_by.update(definition.changed_by) + # keep the last value for @only_create + if definition.only_create: + new_definition = MappingDefinition( + mapping_changed_by, + definition.only_create, + ) + map_methods[attr_name] = new_definition + else: + map_methods[attr_name] = definition + else: + # this is a real class that needs to be applied upon + # the base Components + for attr_name in dir(base): + attr = getattr(base, attr_name, None) + if not getattr(attr, 'is_mapping', None): + continue + has_only_create = getattr(attr, 'only_create', False) + mapping_changed_by = set(getattr(attr, 'changed_by', ())) + + # if already existing, it has been defined in an previous + # base, extend the @changed_by set + if map_methods.get(attr_name) is not None: + definition = map_methods[attr_name] + mapping_changed_by.update(definition.changed_by) + + # keep the last choice for only_create + definition = MappingDefinition(mapping_changed_by, + has_only_create) + map_methods[attr_name] = definition + + cls._map_methods = map_methods + + @classmethod + def _complete_component_build(cls): + super(Mapper, cls)._complete_component_build() + cls._build_mapper_component() + + def __init__(self, work): + super(Mapper, self).__init__(work) + self._options = None + + def _map_direct(self, record, from_attr, to_attr): + """ Apply the ``direct`` mappings. + + :param record: record to convert from a source to a target + :param from_attr: name of the source attribute or a callable + :type from_attr: callable | str + :param to_attr: name of the target attribute + :type to_attr: str + """ + raise NotImplementedError + + def _map_children(self, record, attr, model): + raise NotImplementedError + + @property + def map_methods(self): + """ Yield all the methods decorated with ``@mapping`` """ + for meth, definition in self._map_methods.items(): + yield getattr(self, meth), definition + + def _get_map_child_component(self, model_name): + try: + mapper_child = self.component(usage=self._map_child_usage, + model_name=model_name) + except NoComponentError: + assert self._map_child_fallback is not None, ( + "_map_child_fallback required") + # does not force developers to use a MapChild -> + # will use the default one if not explicitely defined + mapper_child = self.component_by_name( + self._map_child_fallback, + model_name=model_name + ) + return mapper_child + + def _map_child(self, map_record, from_attr, to_attr, model_name): + """ Convert items of the record as defined by children """ + assert self._map_child_usage is not None, "_map_child_usage required" + child_records = map_record.source[from_attr] + mapper_child = self._get_map_child_component(model_name) + items = mapper_child.get_items(child_records, map_record, + to_attr, options=self.options) + return items + + @contextmanager + def _mapping_options(self, options): + """ Change the mapping options for the Mapper. + + Context Manager to use in order to alter the behavior + of the mapping, when using ``_apply`` or ``finalize``. + + """ + current = self._options + self._options = options + yield + self._options = current + + @property + def options(self): + """ Options can be accessed in the mapping methods with + ``self.options``. """ + return self._options + + def changed_by_fields(self): + """ Build a set of fields used by the mapper + + It takes in account the ``direct`` fields and the fields used by + the decorator: ``changed_by``. + """ + changed_by = set() + if getattr(self, 'direct', None): + for from_attr, __ in self.direct: + fieldname = self._direct_source_field_name(from_attr) + changed_by.add(fieldname) + + for method_name, method_def in self._map_methods.items(): + changed_by |= method_def.changed_by + return changed_by + + def _direct_source_field_name(self, direct_entry): + """ Get the mapping field name. Goes through the function modifiers. + + Ex:: + + [(none(convert(field_name, str)), out_field_name)] + + It assumes that the modifier has ``field`` as first argument like:: + + def modifier(field, args): + + """ + fieldname = direct_entry + if isinstance(direct_entry, collections.Callable): + # Map the closure entries with variable names + cells = dict(list(zip( + direct_entry.__code__.co_freevars, + (c.cell_contents for c in direct_entry.__closure__)))) + assert 'field' in cells, "Modifier without 'field' argument." + if isinstance(cells['field'], collections.Callable): + fieldname = self._direct_source_field_name(cells['field']) + else: + fieldname = cells['field'] + return fieldname + + def map_record(self, record, parent=None): + """ Get a :py:class:`MapRecord` with record, ready to be + converted using the current Mapper. + + :param record: record to transform + :param parent: optional parent record, for items + + """ + return MapRecord(self, record, parent=parent) + + def _apply(self, map_record, options=None): + """ Apply the mappings on a :py:class:`MapRecord` + + :param map_record: source record to convert + :type map_record: :py:class:`MapRecord` + + """ + if options is None: + options = {} + with self._mapping_options(options): + return self._apply_with_options(map_record) + + def _apply_with_options(self, map_record): + """ Apply the mappings on a :py:class:`MapRecord` with + contextual options (the ``options`` given in + :py:meth:`MapRecord.values()` are accessible in + ``self.options``) + + :param map_record: source record to convert + :type map_record: :py:class:`MapRecord` + + """ + assert self.options is not None, ( + "options should be defined with '_mapping_options'") + _logger.debug('converting record %s to model %s', + map_record.source, self.model) + + fields = self.options.fields + for_create = self.options.for_create + result = {} + for from_attr, to_attr in self.direct: + if isinstance(from_attr, collections.Callable): + attr_name = self._direct_source_field_name(from_attr) + else: + attr_name = from_attr + + if (not fields or attr_name in fields): + value = self._map_direct(map_record.source, + from_attr, + to_attr) + result[to_attr] = value + + for meth, definition in self.map_methods: + mapping_changed_by = definition.changed_by + if (not fields or not mapping_changed_by or + mapping_changed_by.intersection(fields)): + if definition.only_create and not for_create: + continue + values = meth(map_record.source) + if not values: + continue + if not isinstance(values, dict): + raise ValueError('%s: invalid return value for the ' + 'mapping method %s' % (values, meth)) + result.update(values) + + for from_attr, to_attr, model_name in self.children: + if (not fields or from_attr in fields): + result[to_attr] = self._map_child(map_record, from_attr, + to_attr, model_name) + + return self.finalize(map_record, result) + + def finalize(self, map_record, values): + """ Called at the end of the mapping. + + Can be used to modify the values generated by all the mappings before + returning them. + + :param map_record: source map_record + :type map_record: :py:class:`MapRecord` + :param values: mapped values + :returns: mapped values + :rtype: dict + """ + return values + + +class ImportMapper(AbstractComponent): + """ :py:class:`Mapper` for imports. + + Transform a record from a backend to an Odoo record + + """ + + _name = 'base.import.mapper' + _inherit = 'base.mapper' + _usage = 'import.mapper' + + _map_child_usage = 'import.map.child' + _map_child_fallback = 'base.map.child.import' + + def _map_direct(self, record, from_attr, to_attr): + """ Apply the ``direct`` mappings. + + :param record: record to convert from a source to a target + :param from_attr: name of the source attribute or a callable + :type from_attr: callable | str + :param to_attr: name of the target attribute + :type to_attr: str + """ + if isinstance(from_attr, collections.Callable): + return from_attr(self, record, to_attr) + + value = record.get(from_attr) + if not value: + return False + + # Backward compatibility: when a field is a relation, and a modifier is + # not used, we assume that the relation model is a binding. + # Use an explicit modifier external_to_m2o in the 'direct' mappings to + # change that. + field = self.model._fields[to_attr] + if field.type == 'many2one': + mapping_func = external_to_m2o(from_attr) + value = mapping_func(self, record, to_attr) + return value + + +class ExportMapper(AbstractComponent): + """ :py:class:`Mapper` for exports. + + Transform a record from Odoo to a backend record + + """ + + _name = 'base.export.mapper' + _inherit = 'base.mapper' + _usage = 'export.mapper' + + _map_child_usage = 'export.map.child' + _map_child_fallback = 'base.map.child.export' + + def _map_direct(self, record, from_attr, to_attr): + """ Apply the ``direct`` mappings. + + :param record: record to convert from a source to a target + :param from_attr: name of the source attribute or a callable + :type from_attr: callable | str + :param to_attr: name of the target attribute + :type to_attr: str + """ + if isinstance(from_attr, collections.Callable): + return from_attr(self, record, to_attr) + + value = record[from_attr] + if not value: + return False + + # Backward compatibility: when a field is a relation, and a modifier is + # not used, we assume that the relation model is a binding. + # Use an explicit modifier m2o_to_external in the 'direct' mappings to + # change that. + field = self.model._fields[from_attr] + if field.type == 'many2one': + mapping_func = m2o_to_external(from_attr) + value = mapping_func(self, record, to_attr) + return value + + +class MapRecord(object): + """ A record prepared to be converted using a :py:class:`Mapper`. + + MapRecord instances are prepared by :py:meth:`Mapper.map_record`. + + Usage:: + + >>> map_record = mapper.map_record(record) + >>> output_values = map_record.values() + + See :py:meth:`values` for more information on the available arguments. + + """ + + def __init__(self, mapper, source, parent=None): + self._source = source + self._mapper = mapper + self._parent = parent + self._forced_values = {} + + @property + def source(self): + """ Source record to be converted """ + return self._source + + @property + def parent(self): + """ Parent record if the current record is an item """ + return self._parent + + def values(self, for_create=None, fields=None, **kwargs): + """ Build and returns the mapped values according to the options. + + Usage:: + + >>> map_record = mapper.map_record(record) + >>> output_values = map_record.values() + + Creation of records + When using the option ``for_create``, only the mappings decorated + with ``@only_create`` will be mapped. + + :: + + >>> output_values = map_record.values(for_create=True) + + Filter on fields + When using the ``fields`` argument, the mappings will be + filtered using either the source key in ``direct`` arguments, + either the ``changed_by`` arguments for the mapping methods. + + :: + + >>> output_values = map_record.values( + fields=['name', 'street'] + ) + + Custom options + Arbitrary key and values can be defined in the ``kwargs`` + arguments. They can later be used in the mapping methods + using ``self.options``. + + :: + + >>> output_values = map_record.values(tax_include=True) + + :param for_create: specify if only the mappings for creation + (``@only_create``) should be mapped. + :type for_create: boolean + :param fields: filter on fields + :type fields: list + :param ``**kwargs``: custom options, they can later be used in the + mapping methods + + """ + options = MapOptions(for_create=for_create, fields=fields, **kwargs) + values = self._mapper._apply(self, options=options) + values.update(self._forced_values) + return values + + def update(self, *args, **kwargs): + """ Force values to be applied after a mapping. + + Usage:: + + >>> map_record = mapper.map_record(record) + >>> map_record.update(a=1) + >>> output_values = map_record.values() + # output_values will at least contain {'a': 1} + + The values assigned with ``update()`` are in any case applied, + they have a greater priority than the mapping values. + + """ + self._forced_values.update(*args, **kwargs) + + +class MapOptions(dict): + """ Container for the options of mappings. + + Options can be accessed using attributes of the instance. When an + option is accessed and does not exist, it returns None. + + """ + + def __getitem__(self, key): + try: + return super(MapOptions, self).__getitem__(key) + except KeyError: + return None + + def __getattr__(self, key): + return self[key] + + def __setattr__(self, key, value): + self[key] = value diff --git a/ext/3rd-party-addons/connector/components/synchronizer.py b/ext/3rd-party-addons/connector/components/synchronizer.py new file mode 100644 index 00000000..7c00fc87 --- /dev/null +++ b/ext/3rd-party-addons/connector/components/synchronizer.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +# Copyright 2013-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" + +Synchronizer +============ + +A synchronizer orchestrates a synchronization with a backend. It can be a +record's import or export, a deletion of something, or anything else. For +instance, it will use the mappings to convert the data between both systems, +the backend adapters to read or write data on the backend and the binders to +create the link between them. + +""" + +from odoo.addons.component.core import AbstractComponent + + +class Synchronizer(AbstractComponent): + """ Base class for synchronizers """ + + _name = 'base.synchronizer' + _inherit = 'base.connector' + + _base_mapper_usage = 'mapper' + _base_backend_adapter_usage = 'backend.adapter' + + def __init__(self, work_context): + super(Synchronizer, self).__init__(work_context) + self._backend_adapter = None + self._binder = None + self._mapper = None + + def run(self): + """ Run the synchronization """ + raise NotImplementedError + + @property + def mapper(self): + """ Return an instance of ``Mapper`` for the synchronization. + + The instanciation is delayed because some synchronisations do + not need such an unit and the unit may not exist. + + It looks for a Component with ``_usage`` being equal to + ``_base_mapper_usage``. + + :rtype: :py:class:`odoo.addons.component.core.Component` + """ + if self._mapper is None: + self._mapper = self.component(usage=self._base_mapper_usage) + return self._mapper + + @property + def binder(self): + """ Return an instance of ``Binder`` for the synchronization. + + The instanciation is delayed because some synchronisations do + not need such an unit and the unit may not exist. + + :rtype: :py:class:`odoo.addons.component.core.Component` + """ + if self._binder is None: + self._binder = self.binder_for() + return self._binder + + @property + def backend_adapter(self): + """ Return an instance of ``BackendAdapter`` for the + synchronization. + + The instanciation is delayed because some synchronisations do + not need such an unit and the unit may not exist. + + It looks for a Component with ``_usage`` being equal to + ``_base_backend_adapter_usage``. + + :rtype: :py:class:`odoo.addons.component.core.Component` + """ + if self._backend_adapter is None: + self._backend_adapter = self.component( + usage=self._base_backend_adapter_usage + ) + return self._backend_adapter + + +class Exporter(AbstractComponent): + """ Synchronizer for exporting data from Odoo to a backend """ + + _name = 'base.exporter' + _inherit = 'base.synchronizer' + _usage = 'exporter' + _base_mapper_usage = 'export.mapper' + + +class Importer(AbstractComponent): + """ Synchronizer for importing data from a backend to Odoo """ + + _name = 'base.importer' + _inherit = 'base.synchronizer' + _usage = 'importer' + _base_mapper_usage = 'import.mapper' + + +class Deleter(AbstractComponent): + """ Synchronizer for deleting a record on the backend """ + + _name = 'base.deleter' + _inherit = 'base.synchronizer' + _usage = 'deleter' diff --git a/ext/3rd-party-addons/connector/database.py b/ext/3rd-party-addons/connector/database.py new file mode 100644 index 00000000..a3297326 --- /dev/null +++ b/ext/3rd-party-addons/connector/database.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +# Copyright 2013-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +import hashlib +import logging +import struct + +_logger = logging.getLogger(__name__) + + +def pg_try_advisory_lock(env, lock): + """ Try to acquire a Postgres transactional advisory lock. + + The function tries to acquire a lock, returns a boolean indicating + if it could be obtained or not. An acquired lock is released at the + end of the transaction. + + A typical use is to acquire a lock at the beginning of an importer + to prevent 2 jobs to do the same import at the same time. Since the + record doesn't exist yet, we can't put a lock on a record, so we put + an advisory lock. + + Example: + - Job 1 imports Partner A + - Job 2 imports Partner B + - Partner A has a category X which happens not to exist yet + - Partner B has a category X which happens not to exist yet + - Job 1 import category X as a dependency + - Job 2 import category X as a dependency + + Since both jobs are executed concurrently, they both create a record + for category X so we have duplicated records. With this lock: + + - Job 1 imports Partner A, it acquires a lock for this partner + - Job 2 imports Partner B, it acquires a lock for this partner + - Partner A has a category X which happens not to exist yet + - Partner B has a category X which happens not to exist yet + - Job 1 import category X as a dependency, it acquires a lock for + this category + - Job 2 import category X as a dependency, try to acquire a lock + but can't, Job 2 is retried later, and when it is retried, it + sees the category X created by Job 1. + + The lock is acquired until the end of the transaction. + + Usage example: + + :: + + lock_name = 'import_record({}, {}, {}, {})'.format( + self.backend_record._name, + self.backend_record.id, + self.model._name, + self.external_id, + ) + if pg_try_advisory_lock(lock_name): + # do sync + else: + raise RetryableJobError('Could not acquire advisory lock', + seconds=2, + ignore_retry=True) + + :param env: the Odoo Environment + :param lock: The lock name. Can be anything convertible to a + string. It needs to represents what should not be synchronized + concurrently so usually the string will contain at least: the + action, the backend type, the backend id, the model name, the + external id + :return True/False whether lock was acquired. + """ + hasher = hashlib.sha1(str(lock).encode()) + # pg_lock accepts an int8 so we build an hash composed with + # contextual information and we throw away some bits + int_lock = struct.unpack('q', hasher.digest()[:8]) + + env.cr.execute('SELECT pg_try_advisory_xact_lock(%s);', (int_lock,)) + acquired = env.cr.fetchone()[0] + return acquired diff --git a/ext/3rd-party-addons/connector/doc/Makefile b/ext/3rd-party-addons/connector/doc/Makefile new file mode 100644 index 00000000..58156b0c --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/Makefile @@ -0,0 +1,153 @@ +# 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) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.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/Connectors.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Connectors.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/Connectors" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Connectors" + @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." diff --git a/ext/3rd-party-addons/connector/doc/_static/09_datamodel.png b/ext/3rd-party-addons/connector/doc/_static/09_datamodel.png new file mode 100644 index 0000000000000000000000000000000000000000..4bf0bee34b4c9d847ae8c4d1807f182eadba974f GIT binary patch literal 383631 zcmeFZbyQXB+b)dT07U^MB~=up1qsO|ARre%fONNXEV`R> zFWq~eU%lr$%U(fWCk`TFeh4=~@8rn6{r%$BO(5_~o zp<%ql_yay+|JeN#ew{ZL5S7Kiz!;g7ggy_x0#Fa2StmJ&4-6$@hck0^AJR zPFhJxNxWbh^(EK%ctO-BzqYatuUh*}y@dyVeenCYpW&U;+>DG2&1ux%tMi|ND^tUyh67^w@>n*-#BE5_b9r5ArOL z{nd6m5gexDZIK)#v|)UXhel%+#eU(((-db56SdB*Aq?VFJ(;;R2GK948-35CW5NF| z_4M?}T2Vd|H^--9Sft<6cz=3jMNLlbbwEl*h27kb@b~ZEJ2^SwQavwoI^|uM{6%!G&|`S*+F;HztdP=A14M)Sm9-Y1Vxd zPHa$eKHZA7UK>B@Q_zU!wcnj;@TomJSwk|vLfr^zyG2xgrgV01&vAKmtTLL*l9*Ym z{_{PtnI=O+!)uoWMMax`gg?Y4ebfn;ix>1@R4z)h-I{Z`_2kKukHl;SXQw9$IjZ{o zSxN>51~xWjjT^{;+>Y>v^J~s$_HuG^Mn=m8uUn6gk1z0-S*;8sb8Bm~oBRw1a!xiw zYe(TOkJf6>LTis3nwnDKyj@*g`uh6B%y;kJU7o0|&B|In*_-h9^9ynD_wrgC$esB1 z0n=FC8QGs*sMA(qvG`er1Roxv#7jljz|fF{>yw?<1ELH4#4fkW4wMDo&b9>mk#U<$ z)Hwe9@}2;3~vvNw}%mvJxf57s)LIiKx06A}=V81%K=%lCF+ zeD1lX=A^097KzXF)LNRbKlvC8L!oX5IhVyky%#R*h1^&kEr0m%;nx1f^ySN!AL{(* z)I`n6sl*c#7N#gA^#*RFprD|rh}G0|?R9I&hYugBk5(&f zZEfMXhnZi!e*IcUCx*{a`BWvmrKKge_Ov1;B}Jvw>WYqREuCeU$a!W9s%dHFO z=qhLTIXLz@;|0Y+8FzMfu`n>g5YDIW*GN{!tLaWz;f9Y@cBx|>HV5;yyOsKzwzjsc zS4R)V?bi+t4s7l0zz*~Va?}tf+dUsJ3Hi>BxB4;_&@W!JwXt#Y@PM5m{JJF3KnF)h z28n~k)L1xerSV9~$B!Sk<~u~5Jh@87wLRAsDWT7Zx;L&dXTxjdFev(U;i^JHA8ujr z@$pR|s;jGcd3fqwQHP+mI49Od@t0Ey$$0qqN@r<#d7Z7TtrHU($GRR^WVCd2x$4!l zh!;2)BqcjWN=+3M6f((}?%#hvbk*@_mo2hQr?4Dc0nRKWBy{oOMez30)7KwQiSRmh zHaBlv(A=D9#zq|Hg@z8qo*mD_c$(H6H2MjjgDXqv?oB8QZZ;5V;NjujrJ_v_6F2&^Rqoxp2jOFLnw

+&7iXb)T1o0ET>{ zRpV6pFhGkKH5@rsXW49b)6>(z-*c12_1}VxoSvRiOUB?CIv($DP>DylefTh>@^|L@ znb){4`jVWSyfu_b17hCs!4{KhnUtK|&Y1Otcr4!u*n>_XCkxBl-Q^(;lhONhbdemU z>RMU}$E8$Umdk@?opJmfh%*OKQLkGVv$L~cA6^y?EkQJJyT!%Dy6sWdaW7oBFf%vj zJneoYWwpN5D|rig%J@G4_Dh;yMFx?5MTy@gHf$wd$EW5&K<4h&-eWB^EK<- z+I~DZt~ZC{hG~mTouQygYSr*j!x`(U`WW^^z=issrrHf777ZA6;peZ zE&Y6VWSV_DWH3jq^8I=A7VMS*V)MBlH(B+hUcH(T#O8g)5-y*kx~SOq>(SuHJMGgQ zM+%4gc&INM2q(V4aT^{UcE?JJ@zh}Yu8ax>zqT*%w{nd$P z{osRNe2*v2P9_?CNh&RoC6M2~x}tMDy}G!#2mpcGYB}r{2H1RV^{(9dl{v&sJAWt2TsHRaKunsaMc& zyq7BmJCO0GrluSm9JI8wyuH20osL#MeZmQB4*LB0&OH@K+X0j!S1>UlHkKHV)Vrec z=0zqw$~$-F+M`J*C?-lxC%}^*>b5J!(uKTMtDJ2Ojcl8P zFPE53ICUim^;6TzpXEBAASwNM?ofqsnx}+@D*VbLH*ekq1L#@6z=V+JH04D-4Bsl$ zm9!Q~c;~F*Qg!7prpc>fFu}JS*dMp3%CW}wK#p^0= zd^NMUHs-CdA1TZVFI*ZTdZj^M1`1InCns}tyqyXhnQ0Cj$km9Ajy7h8jALHwbV5L{ z7`LTboJzyLr75aDu)48A+sRaz@E+qsNvA(wYbDvH#V4G>0|*);TPhe#bARiP1SqB zp4cLwgz)fiTQC?mw+puJ-c8ic!=#jz?e^Cv&F9+>_V@2nQ)l8=7!4KV<>gsVIC4Nh zXJ8QLcF)Sng0#?+Dk&l&q9RMp%j*c}4d4-jN(m{%M#$L`5)#6~jZvKDjH+cXyFLS8 zl1X_^bN@cLLvwSp?OOHT@`~TeNU5%lj?=+xD127uel0U2L;AVSi%LjB2V3)N!^N2Z zDtpsqyeX>V6dgBCW;ZwA^5g8Tj*Zkf9s#uX%+=P`X5;$ivQNIz;6qqgP{6nU^So`O zqCX=t=LLzIL6KlVyN1-wQiHl?0mxsly?F7$!J(>`#+y0Q(yiUa2#dX#IjjGay|wS* zTdhnqx4sTTe!hR2+q?U*Z3q@_Z1A+m=Jwdy5pR4M1 zV;$vr?rSLN(LdhKWr;d^lPNFbt78O!LS20v!cDQyC)${hkd%9jTDkwthbc0t5}}N0E$!{#$4py0jpof$`c-`*OfEU%E=vS#Ca$OD&;z7sAQ9c?U0t#X=|IWKojBar=c20mJgr zEq)xQqmc>kVseC&gSdFx>B-SfR38A=h=>UIqO7d!{{H^<@=(v6_sTmE3hL_W_Ets| zq@_1IoKMXGC_)UpenGP%hS$u@Y^vOV>~6;~%%y4djy%k&fS{mmTg1JSr)CyPJ>k!_ z9^N(VpO!a%q!i0-yEy}P4>_^sa49o5I9Mz7eq+|)^+U{VawCK2wEk1OmSWCdRs)5~ zH^_QTz9iHb-^$FU`*YM(R8){}Oe}5R7V2!N`lc$OlZPY)f7tz_K1a^IFyd)qik%+e zZFyC0-)jGj-5f@?&D_$yWCwkH^JBd%*CdB+Y$qg_0k(kQZqBIr+qZrch?+N(0*PHj zczD}WK1|*;5HK3hmdXz0=?3xxIx+(PN{^!gf$mswU!O-kdSRE@UN@}~ISH8_3SxSwd?yVTUsurgFQ-yY4KpPvu22zC1YqzA<_F|ovig!+2al#UJzlma_2h2XYa zy8Cal39(Eu3ZjPnM#Fh*9vos~S}SiYRI;eOwemHk-^*YnHx;}K9S!ZV|MvDa78%zQ zVc{z-4*;AFKq2qLRO9L8Wkz3G!BehOXq(g6lXV_jth+_P{+!ktZJmp@c+v|Q-Xb3y zx}507@g|!}`Ox8mfsQ5V{f^}1wvEJmtk0WWi2ZD28ZXAqfSB>D`Y*6WvM5t0C@8p7 zzg*E*s$34h9P6WleDoig5-2PIP|vlo^74<7k&#y{&Hh0_K_5vtOpbO}n3`)L_LDQ2e1jy&PjS|%#90^;kq%lbK$x(%~jRa z$zw04at^tnO8JJVBB zDUz}3YHDPJgoNbe>hkg-0RbBT_n|0V%Cda(W*w#*=s&o_TNsd)r_74GUSF>gX7NyB z^}AC%`Dz6+<&+QjIaI#kRFvbhDE`GaQ5D-Ral5h{>VY4WaQ-Ji_m~vce&KlD}Tk_cSzRp zT-Pip>VnGc_j2|JiY6x~f%hycdqhbo_Zv6Q1V-u4co18+e&XSj3 zT>zr>_Vz;kE*ZhPxH;SE-E6nB6dWDRfGWynVfbed&&0(~Rx8)QKDOo}P1z0mpHE}I znk{Z^ZXPN%)quJ!H8nLhHg<>NzM(7-E2ogR0nF&Dsz!Z%30AIDViexiG4&Y4UsG6~1@`wG=N~z;3py+hjBf)P-a8cVs%cb7^eH)q$mSKHfti?b-slySZZ!lu1m_BJ=YKYqLlwEyMH*Du^= zXWu>CLGC(PcK}bbw>*S<^X9?+w0~1$qc=L6a43(B?<=gp`P_i#kk_6*Lv2^CULDQX z_86ow_zi@L^eqy!eoxu&lDPFf#yPad(?KC2yW2gIaL%6XLWl+_fa4)E2gLM5AI;1S zmK#XQuu~MWJu*8tRZk_InJ!`HomZM#WH{fSDYmka=u9@V{!Fa;?>p*QU>}Lb-DtMvIio zLQfDKs;r-^Q!(%UDyeHf>Smvd%O8Rw2CNmEf^W3*{qGZ?m31^b@AcXs{_G2Uq45K{ z?ey4|9|sa4A(J|fL2sJ7AI9&aA5V8D#s68GzcB@e&~E%#4n#1p$s)eQY>tQ9|8VHH z0e)1qx8s)U`ZrDdu5jJ*)1O!V{p(Ha%m3%X-SA`NmygfBefxHS-_z6cdrQk(dX-{x z$Z23SNr>1$YRMAds`Jfv3QJSqCWb03GwJT+w*vZwT7CrRO|UO0wxG^_RP70d?2{i5 z7)Xg&MIuK4x!4|yrDrs-^5q&{{sUdW zAkCz&C-_jiCs2j#NbE}EI6+`)spnTEU(*0%*NJ8NiaMG;9-zCSUJ(=!0CQXl!$<24 z7~V=!TVhcdK+N-PEtDJj^wc!JdiL}w@Q@y55#|@E#|81nFgrS=ukKVWnEx!V1|$*_ zy48+PLV_G5?)Q~9-&ub;_vL(HP~#+HXB_)yGP+hJbC*K*q8Q~z){`l*GC7#&EM_~7 z@%*EdriY8V=1-b&dmZ=74}DYID?EP<^jJnrMv4yF8a)j8SWv4KvZxAA^qqeR4Q# zn9E65BK+Mqh6C?Ln}z7=l$q<-PN)uG6o7?Ufrt+*LA8bVej-HjS~x3^ zrFo}$9)PFT*WYMpXcP{?vuG`rfn`hN8-VizhXSR!Rs?_=$*>1s6VQtzXMH)w!6UXMRfg2FAyKJV?LI%G^Goyna1nLF%9wLAJvBo{tI*^D zYbnZ13<=&no*T7KQx*~1mK?AeqcUorobpx7FSudf;r`Fi%I zif`@YKjhf#x%S;e`ORZNaGMkcHa5$}?&OAshJb(oXaeD2ON2d$FDlvw7z^2UYhy!H zLPDOKgN>~iSY!F6NQWk1&a7E`SR( z+}!p+D@srOE0qD`-hVS&OFWc8g@Axy7jW9#>?}ZEuQe~A6);`$pz8r9OY!KtReEoQ zoH!PR)}fu{yJ?6MTJnLjFLUb;{i_(Qc+Y=NJ*leV@fq<}X3H)t;H>4`BhTpXx)I$| ztX6vY#Jp_R+*7%3xN=oyS&w>LFY44yrpZ3-L#T#RIkW_cUyK!Iaw2~it49L9%4&bK zqFiW*EgLBpX#Kt&m&~aEzg3!KoL#W*>~6Ze+th3vGlH%rF`-|}QmHIG`Gx)5K)Hi? z%Ux6R_o~=?7p=?vp>3znkt=*Ova=h#J0^4HMnFPhKdD=L*p~}TZaua^G1C2Y+gwKH z;+j()*Dq|dAl-K#dbhRf-!L~RA*o4-ieA@n-fH6jUrNoLKI&%U7%%VR73<7~vV7RpPgZ>Bb&sI#-R z^~y~)$Cm`q5ai*}1evsc8igAzruHVB*A^Gc^?RrmQ|%J^()6KrV>cSS6+I60wl4_> z0Uq9kOP3gx3SL3pf@`e|7mt*irwaS%&*UodmqWFC*+oiG@jk+4y73x64zzXd&*fPx zN-v6h{rYv7O`49Gi)*;2r)N(Wz8UCeZ);m@JksCVnknQ%5bJzeE*o+z5+5JG=`PI* zErjMkYB4g+flr_Guv-Z=95&)T$PIuDfuf&*JYX-*s_<#(J7KzXIT60$*_ok?U`D3` zWhbYa<9Z0r@;Dc0Hh}$uWM=$Vx+n{6U!X@QWZ$wa%RCj6?c_GioYHGHfvjd+2OuyY(o4I;1GRns-g#dkn~tsGvGI4g#Y(@7)4~Y`Dz4&J z21ze_m7izx&nz-%z1e4c`Sp%U==d^eSbvms8|VxqDpHYEqceE9TG0phceC1ejUe^L z@Y>f8XgD1tE3!4bv}hOV$4$Se|3D=)ff<2}71IpdUsfB@V{I>X2lN(otR-9Z7JuG= zvoa<+qc`>%p8v?s7x~%FhyFr?yL>2{hiner#21NN21<@6I|J8P8)&(!>BYe1*Be+3F}T_RH*q+@(hA1`|P=-(QW#GBtse9D6FiZKJqZK zoQOs*ET+MGcJ8H?X;!}X8}8sSp|2ba9g^V}ze5(hkr7MW3fC|`mFbKoZ<^pAfE%00}I8cu^IA6MO;VA+twjw3U;v2w0KQip6-w=Uz^J!6) z7cO-TgnxhwfCC}WjD2~3p26wvDmHEq2o!*M0ANCL)g6)t&=QLxe%CIqXmUb)hYbp` z?S-zoadRkrXT0!LL}8AT0Mr1-Z#-UAF0=?(NL^iBn$UWoGrpi;6VUJGRkn!MxeswK zu1B70&Bf$Zh*DOoryOn|<9z$1gI<&WD5BuzXJQ||0;;wI_$oBHyM^vLT4pJi8>po_ z-zZ6oR!&?b{etz;T!@|I2{i=m!^F1@5VX0Y3p3KU-UiB4c^7YWttvG&W(z;CW1+u) zKQHF##o(_-YR`;~v$d{kYHG5lK0+hFi>1bA5-z4wkc!BhEq&X7TTIPZta~0gZN;0X z^ycLatJR0^wAkL7~mWc_Wd&-z|>%ZtfK zODF99$W2v=W@+Xwc}x&xr|~B7sH`nrh4TGr>6+0cqcyo&U?zb$Ujdm6ia(!w*J~SY zn2WMl4_woTUnYBWBl3$8=HDFMfzJqF3vVVM=Aa18=B)%kd%33}ce#sxrP1Bb6uD2Jc+bk!<7m5TAO^*Q_Buz@@Jr6k)uE+!7l zeuaGP0newp_ICF6Vk27(WH|<37n<`RP(vtfd|7gT_UBhu1EE2OG_;pr4{fDaP%(5z ziYK2DH#ABO+sK6%o5;J+!#wufa>ffq#V~-zS@vmde*FkF;6X<$BRdfuBRixCFU*Q9 zV?8`PhPU1!O;{~$znQi0_Kv5mw)I5`&Dkl-LBv#@GdSNjnNhCwl~I?sN=!_wSgfd2 zDa%Ldc?vH=r8ZH^6tnmBOB)-T`+R?*;{jW2%SFep)vMF&sV2o24kv14Fcn{|HQ0j> zr^}>5YbF(n!CsU5z9b=Ps@s2u%u7e(GsaO|R?Cl|f}D?au1QLIg5w4%B}u-6C(N_x z6b_#P17+0Is$VtVNbE}6V#)_ntQ-1@(BH*$0bNS5R>PI(_m)6A+V8D`NFp5!m66eD zKH55oVs>U`d88DSo-L4=J31sc{9k7$LhAobZd#Z?4;SJtN}vQm%JnM_E^eXG5X<7) zO7CXZ#OHo;h|SjHw)3Db(jCr3U#Dx3owNPclew9$YLFLhd9P<1a;S^JWfFQ1Yr?a1EA4Xw(Z>Ag!`cRD+RGP zBBBB~RcMH*)i@~acaUd^i9C`biw^K08A4+nmu53i~XK>N93jy4E%u zyPl$0U63(8O1y`s_`GD8b@dOdSIF*2HMPdPQ-f!uL?hk`W@^uCjregu zhLf!G;;OKuyEkt7@XHcLp=^v|8pekY&7pm6r+i+|Ei0C~k5RaRPC@cI7J_@RLv{Xq zq|`k6)p@@23%LO?LV<;=@$B5nXBNf-#sZRLD;Zfa-kGT69XhVJwCN_ZXPuGUvQ6Rz5Ma8KLjW(dlvyH|*%>UrQSt`NQ%ikwM2XSE#8(_>ARv zt?HlgZ?5lY+}R5EN@c1Vp(#KASI_H|fa(S%-(^n!StfND zDRv~#sc}8BEm{6k)sSVsQ1+uHoy&%PA7)gEXEWq_@~>xxMGDupl88_afe3YGjhH*M zAvr^Qn(?P%31jsTCy)D%f{c@QwYJIzZO$}XLMks*05-r-1HQRN&ZBrJ9yuJ8KrM*$ zk~Mxn7m}dprpyDrr33}w>7{eT_{e!tUv8hB;LJiikJ#w#&a*F6kEYMnm3N?V87Ap= z&D7hcS&1NHbD*HynV{P4?HX@cN-rBWYw)w$@ok)>j;fdtT=8vTkT)mZ;QrM3m-!`J ztbA%#v_SL1xp1NONAbLFgSG6k@i`B4_u+@N?X!_uCA$)vTx%MP)l6kwj-xtT26yw2 zE8M;)16)JNBf(gJ=qs)3sCP8A8p~Ur^|nUfk%T1wrUo{1XG^!`p1jdeDKS!l*aqwm zXjI*Se$I#PF0{niEpDN$n#12``%MVensX)bte-0%Q>Ig`YEPM#|0!v`b6VnG44SUJ z0{ay*{Fs9^?Y-fbzpAgFe7DZVaAPmbjsF)+^s4y;h;OP3&u0aUUL+P}10C2qVIN(m zUk>uF!mzvZT$}_*ahg8fL^(P*lOKqBK}vLu?D{+5cxa%WUdu~>7+(Vgo-h07OI=S_ z|L{#h!Ha7-0SL8;*43k&$#9Ba=Zjn2=XwfzaWVf$T)!cx!MgG5|9|~h#WnilZ_(PX z4>=mC{#nKUM*Gi0<{!{r#>B+Ea2wQRbaa{V=X+sK0!-LmQ~&`eK1L5|8GR`z3tRoz;M3FyBt5J3CjwgQPZB2>VSu6LWc=VNmk& zRs$jj6b<~Z8R$VYKmzXWo9(w6K+rE~bOy@K*3w8%Jmi#>_P8Z5zjI48*RN%2GR*_z zOG-@@J5vRA7*vM6QeX8Rfk+P85y0i#!T3gTy6yo%FyCGS$F8l9v3(_XTe7`2D z_u+4$;5+l8{UPXjgDPBR!xCawLo6uS{#kC;;EEDLu^THxnuPW-=%aI0%eA77fet1y zt-21d<@)sv(50tGzXb>i_|bZ)w;2SUEG#S>911vYfcc=?>F(wR;tkElk2e7ZO8?jb zE!LzT8a1Ov?4?jtLbn*?9R(Ql01|n4pnX4J#LlE%H8}o`!2x=M zptOe#c(9*9ebu`fYm;0%`!Yz*=>%=QEbyP=j!kM5(@(*#;i#E-P=yNE=-865GC zk~E_9J61apc#Z#A^ktTSQpNo*#Bd2?RR(RzsdU9nA7$Bmg-hBe|5aWmeAioBT6ayQ z)V=Bial9_LQt`d1%5u)GqE3icOPqnDp})|?p%`-_;=D|PGUk0hy6CNWUYpws`hrN( z-l?F%J>i#**Ou1IctZ>8xm4n@N`?4wVgRp!vUv_h(&ZLF49ATILcsI|L*D>?lY*iG zHMV=J)jDm&i{tU~Y3)?q3lTuRBX)XarVM`*;s2BN#zF9k&6D+L@hq%S702rhTuiev z3{;TX7_Hc=Y+TN84A%c~+;1!w>V<_epm+9HelN3$<4a0O0h25Oa0Yr~nBJ+cmvO0p zC?w}|*oPt(s`rpp6pf`Xz3IEq~m zFr)NTy!ItpF;h$?F!y1>!8>2kDLgL&?40X}t%V{4Iz|vEAnOd?p#^R-IvS-kgQhYN zN+u&EZ8`6lVcFcqbQA848%b93S#jqNp0X0_LQ)378*n49-@Yx7 zy1?KYQHyTy|uXsr9JDN7o>q)_7fFsGb?Ayg&hV1LVR=hxP!}B z4Mg?RSbLs#fWuemsMug*bf~;9;pNQ`$DU&$e@0$~V^k8ag=IGsa~wgiZz#? zgE@!5V1p)C^f9tukj)f2*6gru0do#rp7uI@L6{! ziPqHA5T~kwFbag_pkKF?lKSM~Ap(_(l$6weDKQ(k(*ZqVN)f-Roqmcr`aLPRHHQX}C_ph*JgpEI z6*Zb6M+Z*juqm343Kyn)Z;5@kMkY?>dCWir30Hu&SZU_Kc74iLJ&jBX&+&R4gK`lO zsDr^A#%-prF)`(W?%V=aSHOxAgSO0mRlADrxv>19?{;rHJ?rhBFD*MZU5boio$J%H z_7J{mxp=)HB7@Dd5uYLTVYqnzZ_mGS(pQVlbRp7MFWNQc_R<&M$My+5H?vQ(=zC{N z?qhs|a}Q*zSi^XOAp*_UuJZ%TugRZ6qwGz5m)_MYSL`4TG}I4&7|se6#ykUM9jK*z zKYqlM$x+O|!^&C&oiEh70gxI)fM}RzUkkIN5^kUcitg+WydIT_;TilQ!z;z56SIX# z=;8?o2oz;f4OXlnZ+5pwEc}}LG+oeH|Ju{T1Dc_M5JsZR@yH4^*8KeMzrI|6f-a~L zmI9@veQ#=Nno`yG@gJrEKZi1?bnvq5e^!t^^#V@;*#zW8hEthCqt76<%7V(eFGCJO z$nUjXF%2T55J~=pyE-|iGLR2RW6B4e+~yWMBS^-;EQmKUH~wPlRhv9QL*3j&MnsQcGAVIJSTL&L_#UW^6bHmDQKF5k9DZe!N| zS`n}_6L;NfC#-kq$RIoZdesLmtN)#e6ciWtZ99-M)9I|at|w{1m59IC+#;Z6;^T75 zVr_hEU|>(u`7jV%0GOFs?jk&GXek@?r1)-^djT6QU8#>}P^eDK5CtJ{CQ$O3pb3a{ znQD&IlE0(b;+rp|U)nf)D znBFeEAU+AfmWQB*8ZI^j7XH^thVE`@8V{7zi-PYMYAZVVEFv}oSu?YI3ph_R=pI35 zO^%BTx_3ytun3M5=B(0YBVj)wC1nmm6jh)or4tZFitqDA!l* z+H4%CSw}uiB+L@|pxrm1k%nZv5N)g%PzQ{@rnx6=`&F!u#)La%JSuFvR!Ee_6!aYs zu$r+m8c0b=kD)M-mzDKA`T|LAMlqhivP*9gl4$LAx0v)ZGm->L6T8*0e#&RM9E-7m z#U9=}+2ZQ_zUIjBHG^}8vf|ov3Wk|>k-y#M4b7hrnphaH6#6yd?c=SE(4Zg;7b$i1 z(`M?}M^@f8|FjH;hK7bYvJG010Aye>i?EW?5U3D9yPNGyHUb42$Q9@{YGADjDCO|! zvdcqe|#UqUkV zS`xa%H1}|!^9mL*a{R%`%e#tZTVk-h(hr$=Z7`pbhDOv$iUEv;8`_?Z(BuP41AM(! zwdJS%LAh5b`va&LC8N1s4^Tf%7fN`Pux$~jW?rx>m0wfbOqXVsLw7i))5oggR9w={ zxg5x+*)4rC^9T(Bqu)_lSE11Q*(oPH45226vm7itTK zR0-=T$dF+ul068Ih^Pz}WPKXiH13A!`*?oA7xPo-%Xz(kYMc8#MDB zEf;2G(GwQG8%}$Zb;yN@uWEIBA)F`Me0_br^WhWZTgp!hi)QGGstpFqOY#s7fffct z(E=V}^neIp&*#WUke#u-`u+)kz4umO_3!yOJKd`V;u!QEKXh6LvudV1yL-f~+M0(2 z8-4+b#`2s6YhF2-N~gZzXY+a1EvlfY1uTg?HngR8^#8TmiSWAffFjglo$q^bH%iU2 z*gDft0}fyTILd2e7-)|HP^o|d9Tp;J63)hc`m_!bG=B=jxX{4>b%V;ti7fxG#55Xl zY%S?<h5=A;<5lk2YfKEU<3fisNih{%4m7{uG$uh>XOV$$#IKRGW-TSxR ztBeAVfS|FyUXe74%W?^msj5?t^4u!fe-MFL37+78qzh1vJkY6LVcaS3}su!Fv=s?-wm|z|I#(A2`9N;i$Ev#heGMD@2{S zti$po8Q!*_hjz?(2~G9unDbse_5VA|2>vnw?OLdA`$;0qENLiD=@^l@D#)uyA~v|=91Rh>?wy;;+PCt0P2#marwtE^AwC`^a< zr3ThrCuVC(PZPOxl4ZJk7su>&bF``8Hqcak;jVvS4!dPPEN&vhEG%(b}~mNrac< zOn_PL>Bf>ILNwJA!Bx33-Bcm;@t}?l(c*OXpqAU3eP!@wS9(vy%8-QrO*CRv)Qc(v zO;#7ax*l2>Aa=c)wrUV`0tua-0 zR?l#;$J5fn5ccv$9qTokbA;6QPPUpd4PMiv(9_T^k?5TA*jI+lS$j>Z$FMARI3L%Q zk47PC4?Q$?R!>`sCiH_?k|q*cC+y6RJ8ugf@*cJYJ&fz%>~VRaw!4V1)!spyXN_%nYJ)4Xd)!t_DwOZ~_(m7D)B0(o^wf^wgs;ET zdOmr!R)UK{?Vj$&PhXOOv+d!aGNi=#R@8J22Ofu+5RR8PsFK;N{Z^q z1?oRPDf|R)%`skk7+wA_oWB11{K*p1cB;L6-l3zsd9R(*T;~#+w~&=Y`v@I^yr;Ay zh~Je*O-(I2N_cPaq2>3VO0hW-9p7;TSV?hMbjJ=EajA-lnKMoX&E}ajLL{C$9zR;H zn=Q8A$r&z3<_($8M5|mwcXP;F+=3(7E|ZPE-T!XB5jtD)Oi3v?zc~0zCSA7MEcn^$ z*ZPZ6CCg=THH+cl&Z^b4v3Gc96mv$C&YdSuO+B++sc<6Pr8v3A!C~F^aS`2_(~A0_ z#^HEwtdh4bMfS?_;9ZM#uZfNsTOMXk+x5ydIb?UXe8;#9Lix7k#8ZEHXR^tWRE^{> zetcv0j3;l+-!q* z(CweLTMYKk+}MbvSK4l9HEF}nTN4^obmT#ah~biHA9tEd;<#3v ztk_-GW4@8WwkB>%H`%zuG>~2HusAjPnr>XJD5*lS%^IP&={i^1kl9aUI(y`Lgcu`r zS}&_GD@40pAFy_Iv>2*V>&rEsui|g}Fh%q=p8cyUD=qliig{XcspQp%AFxjOw^U-^ z-==ERPYQE7K1_^nvl+OmhI&)OPoYMhhDUQWXfG=~bNiW84;z@r4e&>CVM#%7$RCFm}pU?djlwIgPAGLf=Jn00iIDqWS+BmTTH!YS%-B9zk z!xv$8VeGSbdE zL+$r=^#@A$SBCqlt4hco-J+o2K~{U49YRT>_6#EPsoZ`mwxuPG}jot!#rPz-Gk zEh0{%%9ms)c`GcY8(n;39gjA=BPYnbhiVwscLv1QsL*D_n#V4%zg&1@8XF;>{LJ@S zWJGYd?dBl!?I)?^ymZylO3BiFyO|?}XYX)D{4s9RXVaS(6n4aNZareij;eNyuGn$I z;mFnC-aK)hXFU4eTwdkt+g7wUFXZU_i0z(G?QP0?DkX*!Os_h_&hcl4IOS>8QB|_M zevVMUxX$w`EHSW9we0L?{46P{8;&uT6_@p4kcCvfNXjQVj^tFZuBtGtV_~ATh$%T# z$4&js51EhJF@KLyiQTdIZ=XS6PE-$BRO)OoD`j%d_YD=se%kGwf*?P(){`K^eY;v z2{sk+C9hHjm~KAO6WAfHv9fwyxr<@@2BEJt=%7-`lFMeIRIJ>FIltN7(KuFRb`Y8- zXijKsVZI0a+j{!q{M;%HFCL4HRyNluJA28AU}H2lZlLaf%cYMrx@-5{^mks$FEzM6St_064Wvd{X^bXOja0Is31~s=z zkKUS_f50Kk)fiAM%X{-Jl08{W;jMKnDT@@X>CAp}p>C*zQ)X6lw7u>8p0NM0)6bU@ z5`OXIN=nLeGc(7#^9@C{rv*$ZDeB^}E*j_29<*eXoxjhHe>Q|?q_4mDB7Z7+r1S$0 zf^_t(p@Qx5KyIdNMp03(4ui_&+f}p*O2>;8E3wY(=G`_EcBiJ*ClZM|ZMY_?3hA;Z zTt&fj^oFL+92-`g_V&^4A45qWIn0D2`-@B{6i0G%oIW*nSZ=L%GA?g-82@N&q=Gg7 zM~gCIbaV~m;Q~3MK`{|TsT*3}8zf$xHUoIM5nhg{dfXdx3vW6s746+351m|qQ(jR~ zmef~dd-R3d_1GSi9Hxi&C+FmXp9P16Y}##E33xtJ@8eS}d41I1xAvT3>BykYOLL2a zP2ZAkGUHkD(nMi^s^-vJEbFzqL3HzRJ)fo)-G@JitJgjm4}NW^(Adyd_wAd&>HKt4 z`b7$=+ip0QIdX>whnvNZGu8ZS5jHZa9p7&ZdoT>CS4i6-?UOOFw^p7F-~mE}Jd< z@w5L(D2+K%{j=i`ivUJBt%@OX`^S&ep&`(y3wYihtE^^QUlWH85ADHdJa2`^2e-T9 zl^nK11?wm1%Itb^TT)8gBP=B)-W#R|RvP${9l|v=0-mR2Tt8H5nQ3=rGu^M;BAmTL9)t;VOxPMZZk*X^!FTa^6((T83LN2$lt$H?INn*W1Uis$5 zNd(&j85>Jnjq`ZjHM9d%VuaNkf`_-cxw)Bdf2|hyki>0GeZp_=V1OzEjbZ(z&4+e24d0PTi%V~Jom?e79SDfdS?>j3-)2Q{78`Pd^ zb}Rg9_BVLidYk=_LHlA+dLu^^@k&=0SnIm6YOU_Ek+X1|qEjDNadl_GWa;evH*>|A zgvl&qTsteB>88TMhy6_Q62t?@GOBWyc{fOhu6s#5-2;X@5kYtzaKx$lMelyzZDRDSQ;2Zfu)nI5Zv1w0N& zlgW-q%|!YMP8^7*F;a|fj5(9FgcvWYh#bxbyQy?zOBNQI-lejGH@cNqX1aNfA14FVj|(FHtaQYfr0>4^>xf&6|%q8^2u0BOlYqRZ%#)Er`$8){Zsd{L|^#v*32M zS=Y$DRpY+A_o+)yY%i4x^fNla_ud`P$u;sPKOqC)O62+8OO?O zx0>|z1u$Z{YG{L(OthwI)VPyB!!bM?VnENP`1<-5`iRkFN(*=@WXKwiSG3umg$G&8 z`{7JEZC0< z^vR{mTCa@`*IHM~Za#Au&Fw-!e|LCrkc+cYSqa9&rh00OKCW&#oHB5AoIqf-Hg;lBH(}+KV(mMh%%;9p=LL#AyM{_7AFQ39uL#30GBT2U{tZB6jP zH8M6zVgV#j{${o%FjX?tX(Kti*z&RKp&XsOL!#OAWgkLnDr(HztGo_G2R$9OCBe~w zfdRqy&ZwP-60!^$yj?4-l=3DY;<_R%mTkIS(Ggi1*2}F-NoRbv_J^e+39AUZ8JY68 zY80`3+%*IOulQ^W*r(2tWUi9suFm#-AF!UI&IG_bQSA&bWAi=FZC&tSJ%#^vee6IE zSy#OdpRJam@ygVKY|BE^kMoZ;gGR+)o(Q0KL_Nw8Z8Jce?Nt^}Y6LSHt2K-qwWar< zTdlC>88&hDoc2^%lBB=V5kB<3xD_$5p)XxHeD=Zgz~+Cj_vX=9_HEnn*(^~KnNlJ1 zEJ}zvm5`apJXFRcL#BjE3aOBYkPMNKkeO1Hc}gNf88T#^LWXxcx}N)fpXYwR@4s)Y z@1M8Ux>i@=Jcj+Z58J-&+ujnahz3L z7-Z4Av|Q|B^UE~`#E}-a>d26G^|*UaCcoqrxgMHNUHWo|ZPE5*T>RdF2wu@hMl0{4 zgoDhVxH76d+J+rQhJ)s9FyGeN~3q3 z{E`H!_OCw$r4%_2inZu@NoJqq$ZKPfoCsXFI4}~^e01Rb{W2%#8LHv7mm#JF>q??4 zE0>>r{TmvZEiG1(w?&sOlrL%@m0qOYVV|~;8^BRnT;kC1CV4J~tE^pbFn(a)#N{h# zjb&B|TyuN6A4`4sq^AnBm;O!@qqaTHro;p1j>RI!g{DBEf!xVGj?(3UR)^4jMS0I&`NzH^dv4eWYIRxd!794vXQZscZmTCQECmf zQQ4P_bA`H0hQE5ubUWk;J#kQeOVS|u_^h3@w6vV63=#hF=2l?42^`RTtG za_~QyWg`D#mi_%_;y?fQONgiNf1eBS6#lO<{Cx`le;R}3na*|J+h2^08+EdMPrCA> zex-N&Iv&gUIzu`)3g6?rAMfpUqaf9iW;VSQ5LvvTKRKsMkH1iU;yhJQ!Ah2Wz`ah! z=Vv(gI(c`&%_7^11?Fyi4}1Ifw*K{>w|A$M%s9!HgrrwAAL{UR=Wbr!ab&kJ^J{V6 z^EGUPzqm7wzm2qO$2Kl?v(!^j!ByHb*p`9(!L_R2_t13-Zm^Y(D%)?7P1 zwhs_1L(PK${ug?g-eVmSY<`fXQchA&72blbSm<%SJWeV|euU?5D2t%D0 zvpc7E@Fq*fBxCd{-ML2Op&C8M=hU$y)cZ(ppR8a4i5Q-|awT0SwHdSJN!&AFk0Zu| z{76R@0N1snLkdJSyd$u08OS;>&o*^*EP)LXIH){v;U&Hc5+8hLUd&=l+yF#lPft)J zvbFFM`StGIx$_|EQtOLwP>P@%kfxJ5{l(DXu~=qP2FlnAfm6_01BGZ8`3|@iMDJW< z-<;h+EfqQMm?lEq8SQb9r2B4Mp(bhQ)LtsNSHKi*paD~6nOLId*~QBJ3A-YVhZ?$R;q1VhTuv|Ma9V^Eew)Tuz^ZRXuyH7 z8UX_YIh8z-d-qu>GYsIQr{@x6q-BmCO$vX)bkI`q#wraQK=g<{%COACLDh>VoH)G29`0RmG57+Fpzg~4fuk=5Y{s0Qd4Syn7C zV05U!=>ppaSOv_?BIUkRE?fX3Z}PsfdTU83DcddjuQJvh3;A?V-5V3v5Q@S*bU`Z< zn%WbP1WLjD=y_@BB0_uza*7~A5JFoD+D|%XAM$F`g(Z4RNrWa1bi{U@T}Lw64sPH0 zm-KI-Vu4mJ4QUt{8a1nw4#iG7I&mo5KxRNKO5A33c@gq82CvUoVRr98SK_WmRFePV z0uWQn7)!**RycEl24>X|dkwOTprLd5DMG$cRrMNZ*qE`!klqO!lNJmX5EmyV_8Q*> zrYR1746mqN+e^kZP=HN62I$#7;H85mc%HcXf}$dpf9`&$){gRv1nC&t<33N;uv4Ul zy3=6?t{4E%AR9e9^Y}l{e!!+M ztGkb$UIJpi;6mv@5`!ZCAjKwDchcLSOOW`(KjS;yFd9@eQOaL7d(O+_<3gZzY&hO% zXs9@I9nK*n3z7zsVKq=uKm9u&!-o*Lo&}?-yIP=YH<*_ZAt9np{hzEP_V_+txO&_B ze`e?73~u`^pS~%|rXkn+HoU{=4#b-iwNew?$*!(%l9C2+-qO?44~mIJ9kO4-T>KF! zDMBT@L-!0$E;!8~ycgu>GfEvkdbA6q$Li`45L7{HzPd0O9~Ksto^G$K92g!>d^MDI zaM^oUSz(q1ctaQ!!o^sgKM(m;(3Q^cO^lC2tUP5``s@Rv?2v_Ma3ArB#>MVgm|^>i zDSIyq2?=#1#Iw#r{$}P|u9dQ<^A4Yz4NJc-xquO4Us8w>X2jVI@`7@NOy0un}A|709C~2DV%>kXEXuA9>z_ z)1)j{j?)TeW3C@b8#{#d1Y&>MR3ms>5tx=X-(1W1D_1zTet)NdR29GH#fJu*RK%@9{!XVA0J1E z1VIUH>HI?oEQJRlOfd=dz6aGs1qEICj`G|F!)yhX98*w+ zUWN<~4%zSd`9q>=eHF8PZjO#kd#T4>VfrMhCnG+Qlar%X)Kn>A!pKXhVB(Kw+6g7k z*mEYej)b$k8}^g=XZX3QFyWUG97NxInz#I$SFFhHfo&`hYo<>chRZZKI6BD^lekKW!;px&{utL;{Cs!t>xAvi)v6}U1=J>D(6-?=vI z7TdttnJ8g8g(@$>6u7hCN@W`4DpRnru7UrE=Z2qE^N<%T>6comkl=uS zc%NB4^E;H2)4BFYN9IxFVeVXD0;}WsVCo2-5`!|zJxAkk-9t?r!?)o|QWICLHu1*- zYLvAj2?2}s_)D)rdA&n3r_>BAB&q+0K5D3>j< zt|Ps@^YrQdT!VDoG|0kY`$C&nogG~RJy}v(+OFp=JoEEw95waz-54pJ-Tns;*kh`< zqP(AbO-h0#AfDvN%m;7XYpqDx32zl5k~t^Eb)OV_&{;h+P>|W;+&PY0Y`0&mc&#Fj z0%x;hV6Lb(@7VfdN|Sh}`;L0LAhXfc)kP{m4W8tuPa=*U+zn@VE2@)jf&wp+uV z6FPZ&jyNU4jUo@iE{j)Y@7AZDA|v~_FLt5YsL;g*{ zw26IOmIfqWeQ78(`>g%xffJ-=7XQ@MW$Zc3-7vtqD&}wYvcA;d$W5n`^6;O4F(M@RDoIH%5XrUIw4sjbIGQ%ekX8_wF5TG#kPD4gM z?1fW?frLnC65?bFnU>06OoQzM4aqCE&>L@2lSLO}zvN14ig*S(pLVL`7-J(G<)`@%r`4==fOD!q_ z@fV72Ntlv2lcHe`fgU1xa>)pQAR*%UAcTA7z=3|NzN#AV?t|pEM%J+=p6QHrB+9pY z+I~gKtara;a_>N@X)+!$#J5un^Tw}ElweG3Cm7XCO!|1YP_pc-thB`Z3_jP@**T2T zP+vb?KfAJ`;sRviF`N>vH;;!kkGX9^jep6h3YrJXA608}NTh6l&4lhcY!p&A`i6!+ zm|TZ^gNM*WWd6g%vjy>r5G95C{{`oV=m-k&W{lu=7HF@YRff6&>;veJ~o z9g(SJYa+E%e*}a(3rst&M_vcK)*Cmmx-l@&MSZ|wQa^0fyG~TDOx$$w3HPvcd{q_~ z=%++HMr8p-9mkK;p<%CGlon2l|DL!Yyfv{$!MRw0bI{}75!oJ+^25+a5ATY6^x{Ng za*A`HbmCV!E$6Vu_E=V~`y#i*+e9+=oQ^#avR|qE#Lr0XZSvJwKP60g?uITJs8kh{ zigY1J!2ja?BC*lz%z9`otgj{Z@kzo;2dbvOtl57R#3akRs%AX;I%|iJqVz(+(8NHB z7vp%T1qB7gN;^ru<=Lxw@UXkxPM~?e2ML$RjRRXr?nh*T1_WR>wY4g;o2eR!(w)>m zANPiu)IiP4K=QTvP%Ik^we&u`Ti=}rlt^!Dt`7)&U;IA{^8ehmREu>?Pe-BagV=0< z%)_f6v1R-A?U-4a-ci9AE5OZdg-o=8ClVzWlA+xm10AAr30x$)Oej0fA`3Ifwe9Zi z2BDge8Va>-wI%eq_*dRz9Sb-2sdQb4DTBJc0_is!i1R>SsK0!gSeapjPgAsb0C@qV z*s`9pic?MHoxGHBUxPpDz6uQm`8w59>iF*ck6FsnoSu_3EGj;H(8(~;r+`diwsjM` z_UpJ|PE`!D{Tv@Rc}0nY-^kcFPP4hbs>;#X`JmG`F_Z7Omy@)H*M;j)Fk(0&0*t_gvL zOH7j z`8~TM5=pVfEAG5_ZPgI@{R$ZY!!7hbY6-tt8=m=ux_2z7q#}>hCYOU1U7x3=9l@*nP1U#{^l?;(Zj4 zEok>9H08jr<1!E@(lp}Bp%d3%j>!%Tur|;AYP0*C!nRMC4+X#sRQN7m*6_*^aieV6 zb@iPE|5+uaRIMaTtJs>G$L~77F0^2(h|i6Z#HkC6;pS#)KN^?`k{A)rKaWkCXBms_OJ_wzMJ!#wFL*2T zWeg5vKCP&%bRBLUs3r!|t<24LvaozZ0K;iOfUA1{z7NwI54M#}Rk9FwdjCEu?Lsf3 zxT)4RgRk-rY?>S$`FMKx)@f1qonCXTda!|LP}fnQ_20D3E!0d<=#cvaeJ(^DOgNY# z$UrzjdCNpkncVqLG+3R2v2kL&fkG4j4%V7rx7JJ4kBCvHm6SwXG$}J7KAWCyT8hpqL z?dSCfR98Y1hi@h@Mq3p5D=VYqv$eMuTmh%;7l0-THmp@L#2q8=+9A8JUrbDkThaWx zcl@>BS%*Ce<1bFaL6HbS;?&L5%*%^|aY(XJmfJv#8<1G;wmkr=5b{-{#HZ%wjLW=B z)T+LI{Yt#qVa*Ow%)^KMLqj}0Tc8dwgPdlhEuqT~>xm{Op~ZJQGt&VIpNSvROtURG z;Z9H?XVS0(XF%8oKmbMDZB$gBhm$SrF@v-hI{Yb`2^gHi<#P6X_usLv`|0tUNbjJT zQa0aVCv}E*x1y>l7Q{Fqv%oMP)<*2_;!4yjqdFS(vcljI)5O7XOs zlY;KwS4VyrzmUrkgW=?mfM^Rhl{jNt?I(3rbb|{X8GB+S9m!W`>CS1~)g62>FqlW{ ze*M9L)9#_4nG9R>_G48X@%m~Q6btjEGMR==uaVsAr;XaQj8Zj>STtpbWdV?rm>+4a zX=upAE7h`Iqw1;sJ@A+0C=MoO}6dgWjnJ&^30*|ffhI&f{NX(=%pYmqB87NRrKC583Gh@s8 zN(6yI>`_>*m!3e;&* zX8@=ebsSC(vU6yk%tOHQYkT_&2HeOL6*skF;6#o>)fzHq0BU|u^knuZ!>Mf8umMuE ztC$0Zk2NeinYxPV7lT!&PM$1T{26WPvvTDhZ8X#oE>e5&UNLJ_w0J2KXS^ty-^N5IvK`s9BT4P6tK{dT??h=Yaz)ZnGL0DpeO?Nj%CO=y9 zn0wDQojSAXI8aR=pSyJwu?%0sdgx;0=MyIQK%3@M3&V%lqJi7cexbuV9KLxaik?5DXNrlLIVv`GFX~C?AHi^kU9_{_eEoX% z^ywO)M1Wn~fXHCO3i*!r$`VoV96EFeB_p25QjlyQaa}#`eZhDgc!z|f0Zz)pr3?K{ zfWJ=95t#(Ove{L1Me@pKqb$CF)suGv0t#RUD7b(H>+pqtKF%TW>F@x`KMJ-)O#=i| zI4T$qWCnn>c>T__E(z&>N+T|KRW2;-IiG$A?(n=M1^nyTt}=s9b_>K?g<@b_rv4Bw6Q zrt*K*T57v#g?dvUlhSKHZl#zkiEEp*(sgUH**p}lm>g^_TOv(987Rm|%GZj|KV)HT zKZxW8vXm9*b)fRwpDxLy-zS#i{;cf3y9!ADwYRq)KYqO9cy;DerjZzLxQ9Ez!N!23 zgTe6jJR`+pzaDM8PWcmO&w(&j}xRb&j0X~^lir?2`A>^p#Tpag&g(i%ZQ!CN#?{3GAN^uCPu zG6B4k??8Y+7kN8Q9QJlJH8p8vAtgs~#^%@i4qpdH18P|&jtND`lP6xw3yv$gi7nWO zL7h7^F_GD1O)QdOVPRqOL(>PEBsXu~#O|)2LqjPojw`2HZRZeklXkdcgI2gjP+(w3 zzGFg;_5w_sz*)$j(uYn7ZF;GC4@rf#ZR3tJa(uxG&iD|RD-wCcVM5xryqq1xyMqTI zIQIIldw_s%(#+NwykBG}P*E?XVdvtqM0MXBXO9dQ1tIl{=*VCtl79d56Y>qfDY@3GmlvIhv%P|NA!xc31Vm$`nTd1;lOn$$f z)A@5`WaQ^hu9DAe+5$Al4x6m8T{THhf4rwmxRnXQZ_t;kI0gTWG-Q9*KJ1jlX%v=7 zWPC33-Jdyh*yuxKWF*3WwVOCvaWZz7ot&`ng4oc23ZwEKYcw>3;W7|aB>4D75ZNG? z@()1v?VB`E9z--eCycN^vh>jk0{%PkEpGxz@T}Zp(;|+*+~KvQb-ujVda-x+ZWKH5 zn3vtOZ8rj9xS-)7(_eZXvOgM}Wkao~lf}8!&(K+kcZe$P;*>YmHd<;))=fi-&)?-i z2>n3oknu59bue>OK5wku(x?{qp^DO)*}(;WwWht7W9|)oG~+RdQ6?Qc8A`_~tu%5s zJ%IlK9u{GB+RyLJKj14BOLCrD_uWJ6g7Imer1C~`aPN%(g@pE!t9cI%kdY>SwzUqf zX>_{1y8hvURjVT7S%olqr_@0_d4OJxCeM&u*F#Y^QC+-oA|}3Lw&(%2eW4NuKp&&m zh|=RX(f~rP3|IXPTOfg6xKSmbZ@k@K2pEH_xMEC-KkUCUhSpm z4^TB*hyYN7Jw4S;O^*0p@*P0hs3{L4RlrY$HKG^@_j#ax1la%@iSggu~{-O zC0fE#D$=XaB3kmI812Rkcr?DJne&UQjYMMY8Z6Va{G%lBGzTG54dG{i`AcQMWy zBA$*TZx9p^AbO6hdTFhMVj$c-%yu4*3is^6j=_Fnr#Z+Hi8TxLjt3a zk&!`T5%M)yNW?UzJIm1)&pHF#Xg2z6k!$)C^Q`<)r~W%?I_OGkr0PJCVi)}&WwApf7yry%xjO!Pz?Y(=et>rqYP`zwihqYJAOmNg5J z4VQY%B$t(~0RxyN3J%8VBj^=1J9{p+I*uK%S^5su3|+ZH70fWzjI&zN+1WENb|8lc zgi#?OSvbLjs-UE#VtXn17G=kA$_-UU8LCs2=KUFbfkSHRNI!?Ldlrpyt>p0Mo29T} z${U^pVnddALa56@s(5tT8!;WP`rh5UE^cme(C$GyT^~=6?F6J7(PV>46Eb&U`$(pjD>>!37zB=xR>+i6ITzeC)2ku4Qv1`W{zh?8_AWXYfzf|-3>4YFCM%a<1*Dw%Zh z4BH7^-7k>o`Y|{d@!$b2S2Imlu%H6O38J}|oIEl?YT2%ybx58K-T^Inae!~=HrVV% zwH@r0ZpvhuBYHvB!mHX$*?C&$q@zLt>rENWz&m#uC!$bX=sP(%VKwXQxEI?A7nfOR zA=1e=59h}RME4dzsO7MuYpU_Ftci~IDRLhhoCh?XbNE~4FEx$mtdEokJs+SNDs|3o zi82u-%FGPjF)bO$mnL&Fa>!rBmWc-`{#({i_}XbedF3X$X0YQ2dLnqSdueIesWKgT zh1__Aj#Z^8l)n{=N}N1>bSd*`I>-)${7Rah-e^qkcOKUtFbZs)Mdg6v2V8}D8e55$EXrg)zsc!oDYtPWbV1bA>d`9$n(;6)l1DCH z4u6Y-I5s-ke}Al1md7szqzI^0a9{gn4>AGvQD=Ou#!~=Do}@i%_)sn67p^S()hlb1 z&1i6AQ)1HAn<{IXxdwu9SK<1wL879*UM*c0zN+^9dyGr;!2lw(Ub*rwh5Wkv%C$C7 zwO{|HMT(TB&F#b{>;BWwRp(!MV#QCQOa>Z{QX)(?Q-Yu04k=}i*G%wid@f)(s6(Q_ zrX?dh5-Xiha%wN1)2R)fZj-gevMtoup_bc_iv|S*gp5SoW1$plpo@>x#Izq#E5JEI z1{%i~SlPEPUvx#iSEO%QWFfmE_V|J<5Ai}JtYpI?s0FuB@oSgq&S}4Vr=etz(>qc6 zXB%V&G$d9$>r^qyxV!^q-G~C>8(mtPZA<$N{r0~C-5SJvOi=#IxqFhXpeY92?_;4OjVFd)}ciswhw6SgPLMtWi{B_i%rG)!*3*zb^z}k z?tDYH4W=-KhWxaBFE}N=ahWVMWFFZOd?gxlIC|KQOb9_?F*__U(9w1WPz0QAo-ObU${t5kD)N*En$_z>IN7skecbKsj9Z6@K1J4l@Ay1Ofjq2 zs9mjpCYR83?|6n_Lxzp;O4VoED_C<04cerpB4~UgOQiqzxlV2nx?<5XQKaH{FK)0p zKEA2t9$SMoPA`flsMYe3oaI9Wekf^KT~sx_UW^4|vl978<8dRUIsvP83LQ6(z1TRp z{O@YunY)IvXLIx#Y}TQ>xE*K-hn(lm-e|>>Z(&VbYpS*tjC)CN!9mN|14N@|jnQxE4%$M%3>E`y2!|9hXh}=- zeR{>(Lv&YBQ6O9rqDVj|hf5f=`a6`GXWwbwRn0P%=gd7KE&Z*%Jr@e{6y{b|Z2&1L z>G`Y=KW9x`_^lvxaZY{@Q;6P0lNV(gY`vcp~w&W2IwgcY&hn39M6~Jk|B<^7Gxms{C}2~01-m8S=*=Q zmBn>r6!6Z;kfOz&ns3WTn*8QdIWsM<$r)lRww38Gp@@D2IZFg0Uzu!7}ODWrC`u?hX}t|ysdxbKYbvu9eV8$kn#{Xb|x zkx$M6vco~^1gK=Shi=mCzp;2iXF64u?8QIY={Us>M)u7FFB`xaz)K`{RcbtpjTI_+ zJ_#@lHw!ts+39J%@u!n{|1Z5!<$Q}LePD(V%|X0Rk5$z&jl=?fkAbt(2bAwwm{M?_ zp`7_YxG$zBQS3byw;?p4585Z?KWd6qpO_piKCe`@$NAp8ow}|EJsPGbk0msT6D!{n zpir@K5$Ge(1EgB}cJ4%fwYU*>K&+%hF3Z9ajr1pb0~N_vhQ4o)56*W*vk)mV<0}JM zDIAjwm2zb-CIj7=#`J%0=h6I%cI?}k%WyK_I+J`uu~CH^ldt&+A{&5p<5vaiCKBnV z-w|07GbNO8^jG&f&cKt7ex90we7P=Yj1CUvy~W8v5t#pv_n)C5zo&$@D+ZjvwU zY3Z$uN)%4j*qMp~Ol->G%>$;N`u*lHDQHfhbzm*TJG80lD{0aRvSIqz-Q^{H+1Z&t zbfaNTtEZ=@vK%NG04EsoUpyNj#$ThOzu{2L?hBPaL$_-e=A zfjhb>XmauDaj`?B;yu`MO|x?+8)qw$pO%SB4LJt#?b5IcB*2^Qy-JaC|EDFnWy|gL z8__=9Ks>8yUCM@slPbboKkiYz6?h`;R{#FJJoj(eU#VfdOj@EM9FzyQ3ZA#Glo#xH zdmu2|GRD8wu6|qbr%z$GGJ|Edl1^4ER4bw4fd~I_(6Cfjj?#H4=#`U}PLQTliO|_Q+-FHQzd;}PtUKs|)+ zH?esZf7cLwSbgf{|LFG-#9{#Jpp+16;E-+;4fiAHumSfY(u8yaVjTdPBG;fRMU$iA zYYsm^=pi~g_k(uwBefK%m=(~y*f}_6=zXx;8FeP2 zKlIeFW+hEKUQGws&nh|&146_FQG~?C%0iP1d>5n-SoEX&d^5mB{SFD!GH>Iu?2g$# z&m@`2cMzSoLqisd#ZY`l_i@wmnGI%QD{|^%2WV(%pM}xntj(iIA(SMLYcTfXM-$pd z*bnpe?XlqoebFnCp+BxPN9}o`w)abw1Iqk;V(0H5)FG>XB%sfp#{$kRo|dn#FZ?vJ zOaX{fB1+=2oA+*vN%?G>3lT@KhSScZC0{etysMiWcKQ}gARBM8Y{kvMx`D@8!FO+p z6WvqIJtm~LAf_R?gD@Q$0pEm;@WC zxF%5xKUhMH)D;i}bR%t%l1O8_ANFm6?0wXI^4O(kfB~9!Fb7w@e@}!%Pzc~iLmbWm z4nv3yAK$-iw*UP4H!mat;snYKz9UyPk6);sl;ohE7cQ5Fj%WK&(J{#>@z&SblDz8Lme1C)XXMT`9e@EZ|X_sIVMND63$tXd%U7a#BoJ6*|Z7|3kc;L&d+^DQKCVjCAtfR!|7FT2~8~meCOGW z^(%lDVAW?(-JtBmJMKXP378&o?OT3+R5(Qcw2>IdSeS+5aTR=j@*Uv0Lvesrp=kif z#Qxklw9ilJ>9v8pUEAFJ8pS?A???7>iw5%}iy*RS19&1)D3ie|__KriE4R&Ce4-c-Fnvvp@)d0|D<=QdWMUo8CcW zuqi!9NFGgVGjJ-&uC$DD-o>uu#>H=-ql0#xuFK8IiG|=W7BRH4dyrETBzf)IY6F4o z^4#fF@erUM={Fx+CK4)uyBJ_NA}E-S;|YsKE{sFa-tK|N&KLdyl?T8ed^()v6=!EO z7#=ONo{`c-tCJgD4R-eO?rz!r`;V2T^K@7APr5jz(mX>`B#>?R`M-`YwFKXNVyklR zxtIphv^8tte*D>qK&l9o~7^c*e)~0{mdKb-@%oi;#)uhHL{k%~v>_G37)C zOLW;mM?%x2gy>?US~6=z$L{CPp9&{VD7r~KR!9i(#*$_{Dex=w9*bS@{5`&cZnJu< zj6Q`XTIq0)%7=f$Y>3_}dMq#TUR_*rK+^&M$N<33wp;|8oDQBN5yJG@ntI|GJy_q=$9UL@ew5vrm?6}og=JWv_{H2Ij& zQs`YaUF_B2GU5YPrmJYhi=52VUTYR6ArjBs^};nnqdpQBM$UV6AMn#iYb6Z1%%?0N z;hcs>BY_dtMI{}z(tOg%yIJ?u1tI;|T?!SYL!Xo7-k>3;yGMQ{)I%2xuk+S71gL6P zbFAtD^;DVjWQ2{b`?Lc+#}QtYyXv;L?L+SG9m@w!JoEMCxgkJ*LQ_+JW9pSmoz&bb z@|WKwwe|Wpr@b+7u$i)*dx4ufliDFGl>abjXwEV9+a~#SzYbgvG^5Gm+pW=_bxirw z#QmAh#X40kwm_QoaldQySo|M5mpWT6a5?|%rI>!Pv{sJ>^3&0YIApMu#9H5 zbVtB2nYsrmLTd&9fx)%zq}X`r(j^@FKiG1Q_z@Iz8r?mVR_+{4L;9i0Ngda27OyC7 zo-fOC-$rbD#_RXM{#I9su~NzI2jcSsXP&%jTr#IQ8|^$df3|8fl?~#m7$5MX zK_Y@4*>)zeevDdN+#FIffN_@Q>~IyX)5^-v^5pxSfO$(9n?M@X!9jgnh~fbh!f7vF zu=~L}qoSh^QoY|E+xk{eLp{mmq4)%)|HHQ|d_~zgluL?q@B7>?U%qqq?h{mtpoCi4 z*`*opXE_5MZg{} zUUYDn`2PLrFPHVcdMDfBxT81bXIA-G(H~+Hp>js67nKh!8LS+XN-jy;EspuOso8aQ z*zDyp@c4r?8Dy#herNUd=KyFved@d28<{V5WukQpoo|9&ufd~}ssnL3aJD-`3yP{l zYVk;hatdv8qkh`16sSo@j8H1Iv0SetcaJdFe)a6QZqI+T4w6WKy)b3;G&4zS7@yOg zcavzL9iV-zlB|_FKi+kk0u-sHg--qu#aKBXS)Wxe@*Py&n9~BC4aBG#dj5zSVQhF1 zU4Qp9UpN;RSMzUEBrw=USGbHe#wuKLoScsu1+Sps1;(H7#vt3}oW%|X*BMj*@U7VU zpvFTtLdk*KVGn6+!%s&j2jRmOax)n0+R6sE3%{K-Q4bm>x^SpUkgGXN3MRjKb4Xe` z+FR!Pn;ob11UrKF?AzDCQn2ct^SkE3`;SSQvThQ_C$m20ymQ`4`rhg}e2Hmn>+qbZ z6jSr51L4YW)2auv^YSn$A-XtW!ZjAeEcH8E!A!WVt|DpehNk-9-aPT(H>#?tt*!nY zr;ht*&Wa2d-e_^2`)DFDvsYrnjwi0p>vArA3L}1#%$(e>s<~W|R7`4ybDCMzWec+hT9v*AOEN2)xzp67$sPg$+gFfiE-dT--CX+6rR$#L@T&7Zf4=p&>xm?8?A9odKD{lz zK}A%?+ut0>HwNXhfHI+f5>#OkyuLjJ#PiKmjQeQ=DA+taJaRISrGc7v_mAr*YNa;f zgh())zG^BUDCl8$4msLvh`8T_8#mUwK3Y$*W-s=M?L6=_geKqT&&6si-VzcJ7zN?a znEU9_6|f1vtFnIZrBcsnj=FVg(;xmrJM8-NzyzMp&WB(Q4;`?w#l^+-*PkLW^m_pA zId%pFsI4Sv@WA3;rl+@C6lg*yoj1H1*jjeY@VCHKBR8=2f{m(KXdOmc!gu7ReZySE z>fQ7-)_nV<=N_0wl?+#|Fi}O}bs|*jT!&2@v@(T!W)Pj(J*F@}HTC1DkZ13Yu1stTKfd;(MSB(f)cmxm z*sY!Cs=sxRNUDjVU1FoTn_Isp?V7knrH7;$&g*J>Cn z&ccHHkfAcO{*uj~c~pz+F-7U|P2*}ELj5n{>gMLqq0$?D_B`bUwqNLHYFH(GzfgP7 z62D0*I~^LT(D!)W^W?!nk2Ouu`+x~^{QOL}x} zu7pGMKL=>qRSDomnZ_E6Ls&D%90nqatre-~Z>*oBWtJvcUxJZ=p8B+fR##6CIoM4a zEhwDNe{=8wZ3^9QBY^7$>0Ex0+Qzzy>pum$)5R@sn44NzSz%hYg__Bq33U|G09946 z#O%;D{UCC;^5#{2X4BR0=?`f_Lqd*cKcD|6wzydp@G~-&k>hD7Z$Z30;NCr)dHR48 zg_H;UU}1@<+yVD1=VB4c5h}?}+dxc5vXWZ9h3Y3m#{x0 za+DPm7Ft?aLB|UtT*NRg%i()mhcD$^q#Q8ewmwxMLREyUz1}XfB$?abk*kos$bmz1 zQ$qde8Sn0PnI(198A9gq!Got-sZ>(uNF;+?5T*~MDko{Z>FI~Df|-RZ0)`17&?3wk z&1?l?1P+}I@g2wvm%uV{b#n47u<$5L`p6kph08^qEl;7OqJpuQD$Gt>(<2jcy?i+( zHB~?Fk}-PlNVQ=ArPmr;fh8jspr@?BCv9b;_6HZf@8?fTb8}R^5hyF0cZ?xq5F=j5 z4bXDZ;K9NPaQ||(Qu|A9g1y7d#bsOE_KMT_+wGvd-Q5b?!5zJ4q%Ko9pZ1Q3A**O{ zE*|Mr?RPrz#}d-}?@Fs| zPd#hO{_ySar*F){9cz__6m0$20^G_tVy~z;RB$8W=Hs^=Pf&Pbr64w*z6*%N13cVu5R!YhaKrR^c2iF)Rl;KR|?O~yz_-w%Fg|1_sQ@tlIZ3TOApewMb ztXR5+TI;H*3u`{c02dbA(X%7COCzm8*Isjz#CLYfsb8X9!1Q{-*5e#2uN!U{VF-&5 zDUiK}39kkmwSW`s-Jjz%B^`*I>tar)%*&7~*b4({e-hG_wAK-H2(S$=nz2!@qE`Vu z#fsHO=8PMhV_bzK4jdR;XFvK+PF2Wv;WxR+gOj!@l=C!tA4{QwG^Atvy+cFbe@*oD z?b@^FBEFf+O3EYXV<4J*{31jf zfR?$eWi2CyWsvAi`oA0Ne#VBKUlMF=@qm@kvlzWS58enDH+M^3B(jHb>3ki&6>MQa zL0TRhS29;_ABRctP~+>w@wn8M5#!qL*~@0o^wTuOMg#`_@TBQ#0=uJ%x6vRzTh6gkoNAlSuv4X zL2_cO^mw;-BEy(ZpI|>;IB1^C4qn*)70d4qb*3_~YWpgu$R8|3+4^;N?)B_=Rl42P zk47q+;cXf_4F$#O=IFgEe54s1+UeM+Thg#(*rjABx}Pu zcaK?v_c=}i(}`P;$NK5MrJFf_u5pi@LEEYMz}QvAllLXR{T{#l-w1sNqS5Bc7js4K$p@0y_osW`8Dw|f+=>PeFzDn-%qmQ%X@k5#*fI@ou zSPZBa|!R#U{HM`|UvZhQ=2O48z)Ygtr{f}=<-hT5f{(>3hU$SI)WK@XF=rNKBZM`}1 zRXPn#Q0UlCQaW*5hxmWum#?mh^(cvS_vy1|<&~AmrKR0puakVM7HU3hW&O~bx4G;R z@dH9*oxgexP5!*Uh4eP(b6eY5-@dh{dNczA1E@bF!qc{1>d$;bfCi5uA`V+6;j$@G zGc(tEgM_2lKY}jnjCqHn2nDTa5gZ4$|Ih4%l!hOIE;FKa;B^nG)JFCx&ag=HzHISB) za_Whvau7AqO8pGHBh~E`UwE^^In!5V&3DQ?de@2AdGR7d!K(V5fc$z@7t98wLe`4GMEBHs-aq22@xSu7U)O!7fD# z><|gSv?4YUonU7=bnz?t<$!L2bJR(VFU9?Dtjl4R%v(pIazn}pTo`pTeBs5fua5JD z7Zw(RFJA({kbsO*Qug~ngHQ;d7*I^~QVa`SQeA&*gRH8eQj4I5GKFT(9u=a{T?AO~ zb?qAJdQ8WV^+0ezAG03O0!UMPxd+4amlVw)h5q7jyb)J0AAq$HkIu%%Mp?NUY_dfR zPyhbaHUYVYzHu^AShROGZ{M@?!oW}D{i))QJaLP6 zv-S(G`J*13s=jrs2RMnN>Iq zC?6UhWQvfg^T6>YXJ(w;+^}jZJvPQdl&WuNND}mCyrb{m&5mCEC;^rqiihi^fI;K0 zK4+D2ID&YHi((QndyCEq_=Do$4ZJxkZ*cc?k%GTDCJ=`^}t^ND6wjKtW*AekiMG$;8&o-9koRL72qX zuK`?gDlm%IV7$^mdRk>u8|?Q(%&a+oFuQV6SY^XzQsaKyDu{gqJBa98-@ErnISI>f zp~4V@Y@K2wZGaz*7???D20Twr##Ap5+X>hQ^R3z_iL}B(DVQif|1apEaQpe)x%{Jc+CJ7Z}cEo;%31i zlffs!gu!JN1}6*g3`S*bJp`Ktq~+zcjJx`J+zgi>=d-$umc)RQ2U=(-Ocj!t`2jv0 zn%cR6WW60^*366y+zI8aUYsJo2k0X1U=lk3syGM7IbgPc1N>+ntH7JSK^y@Y5%et3 zAAcF7bSWhnpGJ2W_KyZwIJS*qn8Gksg$wYRl>6k<6YRs#RLK*zgE1BVAwUF>kdb-l z{m}#F2Vs|bXa`hR1Kwq*`%yfV&FIf7AOJ>vJ{cPuGrDjCE@Ls3x}(zD^7_;`+`FAX zx7)+Wh~0@-ko%+mIR2d^Z=llm%J%ao5fv<6#$=Sw?{Q;Pdv3Z#G%H5~sSl-Qyrb@z znyE}^5-2{!^mLI;ogKf|lOmUT5xH?V|xQ{6r8TW#M!fFQo0*<&X7*rWZ z_dwh#yCe`pT{>$|-;E4_9z|~Mg)-WBbIh;cAw<$|h`K(1R^cuQV#*rW%Y0Q{kuMxz zTCA+x$#h+};pUUF*H7`8H>ZK&%aJgJaEav z>d))^fEfOR2U~i2Ob_%9^E~=DB>QAfeUY|+zd0N@*u$sDifEZ)jd_NUr0%~l*P;74 zeQMG$7T`{Bli01KOabmOfZFfdw~HiJ;7Z!VbEAXIBhd`Xn)owoHnscN^HW*xxGpgI zyE4BLcJFJWzps!zx%YyvrN2x7es3k2ji}^EZ*!YmCqhAGa0HGRSu|#$<2590nh%f_ zy}e5{ct%kL;pG1dYYT{pF*Y!W(n{SU<9-=+Kj0he9vqU`@LmM7jvzDsgB1r74TLERT6H^9jX+Pj|Q`-oVM_THbmFWE>+*0)rbFP!pL z`L}O>@Oa=xP*wOnfH#cV>%l-!_KL!6QA#rBrs%wYleCBI-VnGh0KvPSoOc zVAunc>)c!4buKO^O-%NV<+p5)&3l3d>Pfd_WJqojTliAMuaml@l-u{#0} zxBVHs0wAl8hIeB3o?KBiK$qUwcx-&UzO<3v2bSk5Q_Q`?w~25nwhT82LotA%1j({f zJr#W4w?967W^OKAISJSsA(CTUt`G&zF4$8wsTi=4&ovGy8ZHAV(IgDMU8~ zeBC#LVAl_^tWc z8FcCp22*ut$%K@Xo*w9|PzX!VO2x$y(gc9LTCRL82ek$tEg&G^P9#3Yuq5&w*Cb#_ z7k~IY06PV7l#VV3Kz)){Rm{j!95$@7f0>r1%@_V}%w>c91GLtqB_%(9{)~|aA@m*- zw8rSIYcY~ke7G64#EtCiY!xop5!$*ij;M1ef{#F>tZ@5P1{v5Vgd||1Zfp)jqJvl2 zxhKsSgSc#ll1(Euv;ik@dqB3BncT7T6p0vO4wqj_>j);A(4pByX8fPP+>o^y%;*`T zKZaAPYHB!$UEElnr}|jzq#nbbUxz_g4fTyBiWMqVQU|{$dQ;l7}sd(Dx()Ix5!(;qvD2$96;V2qe_s4xc z7lCnObWSsMo-${c7@P>U>LigOAD|e;)4_scxM>J3;3Cki#46iaG-GROPV>-VIz4*% zwOH0j&5-S&oB(Ze5FOOGUc@|-)R7}LGJP-K?e5E{{bn?3xc9w?xQOwsp%KmgUVANn z^RJrQm-+^SpTGOLNrbXrDR@EuzuQe-2+82tTG2UsgBE6#OPC9MMtg3H#rh?wuRF;( zajKge8C_m&117=z7n6ATOEW+)Z1tlwvzWhsUDl|iNbpORojc9#?20bb>|Q#D=!AHV z-po)!9f%@gh$6@%%SQK-te-t+Kbki8onP7*3yb^n zb_dx|X^(E%Y_0tt0ENj}B1oQMTB`3bGc~~(XZui96|ky!`^Gu|dCuYGGJgyFe@c4% zH{Ji!*LBC7zh6^iB9VqZN}o_z6LFO$@9%l|)kVqW@wHv>1F^V0e_WhAF_~_R!v){u@!9{PpcxeN?>+25ukPmALvx<_X8RF06TjxMoEFLK;h_`#Lf+j3g>i1 ze#O6c)TAb%4ypvHbKyr&{Xf_9zxa9&xSap}|NoLzS(mmFN>+o6%9cyW%4ix*At{jx zQ5j`NMkG>JSxG}FAtSSh6ot$dnJq>2zrXYOobNfGbAJEpoZIJnKECO?uJ`-(e!ZU0 z$9m=rpBH+6&$ZW!+!u5)m|tI3*UsK+MU{PvB%8tp>-=$>15zvE)B=8X-+i#))!>+5 zIm<&qV;w}_T(_7U`(U4VFv((mTd8l_2A<2NQssU90n7?$XcXlIb7 z&%)yQ%8v?Zo_UXhn^sv_Ev#53idsyU(a)?`^g?IV5g~?ccM-8|-P5h+C0lBz?&>Gv z)8kq`>UpKboY7gs+Pk+H^=P0%Gv<>~#-ViW=ezBY6V`LxRyh~Q^&3%C+da;Sd3V(|l0LY4bzM96A5ZSIJ1rNbn3$OC zZ)H{UDDLW7Vr(<>^Pj&J8RypjI|@|TwY^l!b=Ehho*0(sVBhvKU|-6%$vfnz0c0{1 zRDKOv+*!YC+Mw@5mcen4Hne*4jmCtiAU9q4UY9U@%#qQkOJ5$tV^)l8m zyzx5V*{<)QcsuI{`a7??7JswFy69em2Ity10R=7W<d@IXM@!N z*)p0O#~g9oL58~ViZkcV38-rT83?pL6ljzmbNedvpObX=$rDfNvTI}!%=Nf(k?MksqOO?&VU|=3LUo?COZRJXO$9~;XZ-5xxEP$q)6&I!snccW*xsy zXwt#V2wfOpmma2N=}8y2bazVOsr zm$;An@#E;M_bxSL|ahmOM9{YGwx8_L+gbu|~anZ!$6~I+NPgiMJ3K z1@~YGB_J38qbDBSIq-o?_?o$Gp7l=!G(>WSkx)E{V;G?|+>E`TRY6eZfq;)@)_Se0 zR8o7>J+~+Cd0A4A^g-~yc1E{RfD9~b_ij>&D+!~_X(PZ&Twr*XiPBU;owu5Bjj3cX z`*7m80eWG91Oymz1Es%$$DwZ}_pUX3_Haw=X(^R7`je)zo=r;8ig(UUSN&>Z>kju% z>NfoFFTDjm>$cqX6zMNk`IUEAe_uC|U5gqk&4`96YlaC6R^>5=MNMShocDo8|-Vh*_aQ!q=h z@J_C&BJb#av1gD39IyS-cp8*$gPcui6YwN~;$VLB4$XSDimfmoZr z60datA2~?!_QQuHI_RS4H_47OXFlfl7O=Vs-mJG_X!QB~Wy_bt0p4W&$!LJ4P-V{M zgn#j-u-A5zW2}~E`T5Z?G4cZNCaobP8(mtavB|(#XOq_Ab6WS@&kN>>jDNxtg+1Ee zWHNh>Q>sjCTG|}#P;G^61iQFwjy*eVRpp5Z_e?`Yu{-u&X*lTNqcHF4s**$MuhP8U z+Qw)a1T{R%dfOsH=T@W4lB~v{F`pN%JD9OfEP*Z&as=H9Zv1)yQU|mLRCx8^ajD#6 zqkbtb9mvxyO6rJ(jergC#lc@agub2j9BDx^KgPX%OKV3TWvOlH=BBH0;?kw(Sy?;8 z-~bmOwa87xEL28J-ASDX#Xoq9@`A~|_u~D3eCQ?UWOL|de_adeJou|CnY0zku;d5`k*z|Hg*TnHG;mNpXlYPu> z=FIVY5i&RKeDC7eaQfx^D0%@bfE>^~eU$Le+u*A1`_-(Vpn&U*zJ?F-?CDdMTVE}$ zz@0TBm(UQc;83m9>`b-iFupi*%5M;N^85E%;(j(c{+nRPO`?X_`1akw!ClXCBR)*3 znW4$n*KdH4o|u|!&LG>H*YrEsREl$&7B9NDe}})CXm9&28+JZ)oapy>(b*LTgz9Mc z@U%;pR)J=`j7tY1Mr*x#&_P{VP+cV=a~*o?J3N*zx0<=N^X7nyLG6tXJyWPmTzn-c zx0B`o<-xD4);Q~}TmD%0Raj!7MdP-`Nzq|_UYHd{3H5K!-1-xbf9`Uw71#U}B^s2>4h*GT$Ioj00f%y^rMuU~h0%#s??+I;HdX}7%McCj*eMSaf+Xr1E} zZ?whUwd+zs70MB6~n36dk`7s)2oLK>z-Y*ys9_wXWM@ z!`ADq97L+EnjB%S7_isot3wb=59vVArcJK8k%JfQM5qs9ih*eW;YhkIgpEUZ86Voz zsIyL~-J<|Ejc-Hm8d8y{4IQE}W(=b#{U@24k_S(-m%{e`@@f3~eow~8+vNILs&9N0 zwcy=ow*!9Y@85LpIYGaDC9=@EpFf48n_VI>1cmEToXR{>5Q!WoMabnj=zu;3<5*VO z{u%)#X9@7|0ka&NnKR?DzBM(xZbH(DdH{ar`VKy0)aT;Se#^(q&dbkN{i#$*dCQ@Q znhGdlE!P>-Zv7OC4x*e1&hVy#*VR;tLz0KQ@0TQo-TD`Cy1rz>h_q=scQmIdC-EO3xwtl9<0;9|HG`T-ykZM+KL*^tU$a@lt~DbEc+^eEDw73gMdR(3yThOO+>S}MQE8Q5 zqVi)}PjE7c>Egxx8sbl!I34Y^A%EztpD=Kuw(tJLudmk!6E_Wf?9gNa6^(K_P@o#aMb67DW@2TWnGsP5^4I75dkmbCx?) ze2b$a2-9j`*l}F+9IZeLOUvNyV~C7CPQjui-HL-y2nX|4e12ukN{Q)&2@}8+>=vBk z?KgE9=wt$O2f#n0FSf3#s;ZG|YIHR|5Xr}JzHQg8uTM@sz=!Hsq5pR`6&2ikyT{*I zAHQPV>`v-CcRNn&urZ@Bt*Xkas2H6K)$GzDo2cp>6g#n6g{ zD|BP{(X^n^J>)@Bu8o1o70^o+pWtq4s)0D+?asvi z;53rfsH(f7-M0E~EkIRZ$eAl~p|NOazioLsgte|5M<@Vfr zkGw!3!nyc>{gdvThk%JY)Ixf@w2uhzAU+*>%rAWUk0Wb=6MoC$eSzB$a?JqZKV&pevs zxqHro>W^Q$Hb&z_Lc$V}55$NFb%T=ZM3 z{OA#Vcbf{^pF`6BXjd+74<}R-02T5YT$vbmgEmGGeepKw9_k8ZJmO)6aI6kZlc0Da08Tt@&C|Soov=e_12sC7eI7 ze~2t(G@zoVPMgLPiW_>z_U*a;KU8n(^Vb=P=#8+O^w`j{?66@y0^`KXT++-0v?#v7!to-~7vGS8C@gsv3cgVMIU) zf{J;mKj;jRuc}U=rAosl%k#l=Gg)g7vvuH5OG-=I1>Ku2b)H zS*8f!j(g_o>&V71h6<2x_U-m@^%`pVi%SleYM~MrZ#4-FNlzbnbjI`8xkjJ;9$$Rm zJ9%Ni+4zlZCNLR!QfZ+^AXFf=_2Iezgo6{$Y~vA1=qb-W&dN1y$Tkm)1a?)bQeUW6AsXJ>|Ai z$zcDTF>@wl;`#Gem%neLajT$UcJICYIEC+`B>434<0@_Ne->oB9}5IC=s@nB9OVp1n^+#n9t3 zIEtVo&_MZ4sQRV}$JB>;D84+EG^NDdU9x5UV_LF*YLw64)Vu$0;%AOp?o|r=PkJ@V zrJ9*bJyQ=~{l{e(C2TZYi6Lz`N#?@D`W*!^QWUgR}+Pcrngh<+=16xoF6 zjv7pG$7soQ5iSv>12ytNeMbok_Nl8uu*nF|BJJm=RteYWrrPQ!Cnjlu_fLRSj&^ z5s5}MdYFbRK4}_W;Gr0*GD0k$^X&T0-;3@ZFz(@S$3H%f-e9EDE$K~;SSpQRsi*@U z$D|6gYS<_+M8lXIrZ}N_Az!DGIUuL=T;pwiv&|r+T|*Vf7tsiWYCXrSlYpk$0H6wl zEtq|uue5gwEpw5~Z|LwOF-^}|lok^m7O6AKe24m70^5ckPIt@lnmg*IE0sB?BC;?2 zDy4Aw>?gs)&Q2?i3;V-Td}!rs82)bHpxEiE!F67@8qzhCwij&7yh^I*Ph?6bW|a%> ztt(gfs8i#Vc}AN^I34L*b(a7|b_IBCikrEt;wyHzHGkt(AYthok`Z|cC-Z3RIRbuX zafX_TKYZ`oBEvX3Y+v}6a=Y&Tspg!?EyvzSZD-`u!(F-K^|O*VgQ-Ga65i_fZdG;u zzzJGqpvz8!*iS*X^)uHD48H!k?F6ChdKz}(sg%c*gY{SXjO-|9>gxKDT$d9w`f~Yh z`d?7mo{3_Us+X#nJ3MCD8<7UlUd+tCnU!@89WS~g${c#Dzz~jNWQlzty^V~lkIo>_ zRqO%4Y>l$Nq_s149$f3WU>!3N+Ae2hbAnyG0N-OYCz20;)=S=&cTi)Ma{ zc$T^O3V=i3D=b$QX<4<9h|X4|b>IO__Q6AkejyR>vLb+|sPF`h8{8b>a{<(%w|AZl zzM%m`^=+c7*U(m?92KAyQ52$!yHqN-oZ?ecSCfUov0Qe8qLqm^GqmK0Y9L2a10#$0 z-Ip%{=8LNx;**_yz3~hHeHJ&{wJ_lVywK3lP{-9pREJ}Ob!WX??vO4x*-EW} zF@I7Su!Tu$(2v-W(SvBO0Gyli8K5F3wEM_a`mRq;;l{g4R+A7%MKo~!hY>A-)H|!H zPL5L+^6+N#ExWljCR3xWe0GGKd(tI)U~e zebskNgQw4CuzSf%Fp+&Lh6ZYx4Q6ol&BJ8V#=!)3i zQ48&sQc|s?#`^mUqj9Rw{a@<@^9KioQiTaE$pw<6;zHQ5i zLQ4WG!HKGX)@%A={=$ccPcO<*QLoM{vDC6* zCgLzZ^@_4<*0aK|Txnn_Hvs>WmG8swJyZbEjnzP-OXd^gqT=G=(OpStQ_5ffi3NXT z%%47evUiXFSLgOJ2*4Qe(4Z6Nxn2UqA3AZtobXefg`akF3qR$qqpcl&ewk?g*duQ7 zh{mIaDbffRZ4U5Ol^^*w?!mTgQ&v5TXRmKuveujJVO_G!u8nS=`0lr_?hFoIU=MIC zxHD9BriTyNDwb1Lo)~cM%$Z{Y@b)$Lb=Mk_7te1k(jN=b>J)FIxtrjqJ^ddaasLkL zop&)6ZiSxPh{1PcMQ~Qpi34a2u|^@D;|qhU5tx3f#|0$UH3qdUoA96_nm8B#16E&J zgYhs?WA^X+ZNKse>D+7-ls4awUF6<|wK{F_@$1*=*QA_#)OXNqI7A#U%4z7lWdP~OcUBOZj7yKYQ*Dk#ed%9xB%-!{W*vK5XjGV z2mGG@zSEd<1@daY3StUBS)7O#OYFSFD#Gfu`58i!of8Od#U!OejC7zuBQL;Y0}T*zwP^*mIAm7AKwB&}C6EF{Nzd(i-h=UP3z^G5jJAB-Pw$K|4)@ z%EkFvSH~_4#jt;=8YAaeU|c=4NgSy9|Iw^Y*h`Z|OfcP`10rLf6N0KkCVc+SelslJ za`x=gGcDN48H~kxAVE!0UcRT&_VN;fBEm_x)W90phewKfvGBzYB~xi^azuca*f;(- z06gSllv-BA;p@ShpwXNHNR48L+lnS?n)MrZ`Oi*Rd>Fd%os0cMarDnOEraJSPk&2{ zMcMIPqcsD6({2I%Q!>3Xydh|&Q{HvkefO?uk^0k)ha6Qtk2~(?R2KIbu^-KUgzCsa zg9I&TU)2>M9XkJY93Q^TLHFbk+cEp~MLOPRhZ^lw2!s9%iPqx<)F zsCNXj{nL&oxwOAYl!P!P4>peT_)$^o<_An)lVF1X(+LA>1&TL0^7bZ?6aSE2G8%GQ zoe|)(Uj~Lec`^$qQ?jKwwZIh|9l0RtfypPg1qb&Eq-&)mq(2Vbw=YMn4#fv%`1Flx z|EZJh>@hP?4DCROP#U0=Es|M40X8}Xg2HTV)s>a|9C)xgCC}Ue1&5z4UEa#QQ+n@( zta&_pF2>8zgsB{zaf&&pOP0i*JLh###v}e8UH|cGC%uA7|C>ro491pPv!$$H?B@$z zHgRrjZ#bXy2Nj?~XFSnglHwFkZ|}Us_o{ug1ev8=bFcbl{v!7V zY;2MCes#ZcV{E_GN{e!aP$j|-j9-J<61R#F=mgxy(^5;S-}BCY@S-H!_BXY9^@s9DvA!jOIiR+4?=EtM`qxVQ&UL{JtWrhg=x0khCn+=03DXWStyqh#tq1q@MzIjW$KHz$xU)n-HVBVvvwgWt+lM9^;D(zI#R1&&!RnUUVE4nf zZkcfC^HDxec=Kx88WXSa$JBjTO5WZVu_R9rsrH$$(Lhen>-`5ur^sIC!y5u-ET8CI zR=7OamsB9>b@6}e=Hr-Da@l`J(}#vs{!jNVZ#)*XMVvJ4^l-0P#P&{FjAY{#(QulyV9_5gW>d+Ej8R|A*?<*6~~a4{ahr zY`=Utzg#}z@`kCs+eu4D#o@H{d*yIw*>?4TPPc#y2^p&)SktAeRM9so7a=`p*XVi| z8bfwbf;?4&bKaPhZ!;O;hGy?d?h2ZQqy{cB=nGB|7{&D)ID9X|Pezs-D`~uH2#l>fJQptLvFc zK``r*sT%W$&h=+U;OuvC5MRo4WRB*~LE}hvrLyk|6YaClAg%@zi8$ZGGQg zOXseB{k2r1hkN;ojzdnf5ZFaYOi&vkc1bO}xM^{*&4)>=f*ili((%Ff0~ z?%(VBkR#_`EglBw|BJ%T@M_y^6GUvC(ATxl>BtO%dghFhNSBzd9}2VXX}B zVN3i0c{D&}0_q~U8RO};EaBe2R6<9@7!QIt@Cjd_17LH$-L{h`CqHMHr|QNRez*M^ z@Z6tAO_Y@61-HwukBPj^wf!&jOLO-Yu_ukD(7Ztv(mZfZMo(9B3_WlFUTitfKhs7P zHBKBm_AYn&7;K3e`eAkbvbnEpX@{+L{kfVTiUS4+@d);XomM~o z2AhYa&7}VUu-VQMP)9Opu@Q3pg_G9WWCitDUUK9@L~KTCYat4 z+GIj;u{y+Qw|P@7yX(i4s1J_z}TBzQ8cs@STJxWhMv+MSeGI6p$v{Y^g=53YQ zy#bZSSL7v)tukJ+qvg0J#rn9MfCW9O>@WICaH;7%=5ahS<|D;LxI&4@$MjEatr2%#? zN6JgL6lJs z2(u{|({Cv21=g32X_|DcjR1{6srYCO@lZ_jnXFtC!qIZZ>MUDk6R;eG22fcSxl$|( zW60M)N7#tFl5#q2!{du1>U%!xJMYo`^v%0!U*?#bA~rVBeEd^&0p>2~#_X)d?rT=6 zK6`qxro*ZrjrN*7T1m?dG(Br^c`Caq-DnrIOfghqa?7j-Rok-?*`pMe8*u^!U2D`fx*u%%rf=rs~R@4Y{dy_6ty=U|$WGx?s0wI3rDt(vuTHnLF`lU<*Sc+6W(k>Lu9-V`4fz&HCRX0w)hI~;kQs%f zjElnWmruCdA?3*wjIvYo<%;u^LP-d__wXT^PmJLa62QyezfWYC=Yo@6L&u*AA;CpP zhRI?{DJg`m9$PLaaoLOl(r@BJZ0*K1Zx)XqVV4(P??|m&6%hafPMZNtIA0QWtlz7@ zwE)tU@{>kKel0IwUHVX6a+g#0vdiOREHcI)H^0Kn(7=F_l~+_`W!35p7%&DuI!#2` z*Jpy!=Pm%pnzkAJr5qZ!*TX@&FA^r&e? zK3bGmfIa&{e0&#L7ouv`r zln`^+PUP&}bVX9u6!dGCrJ~c<=`Im6c|oPbT5Zd8qK*F~1eNFHFu?G1h3}KOE6&9l zEXm$vYyY{?#Mbux{p^^8Pcpz7UI$86&zkM?vAfI8&(mw$S_J#&ySxro_@!A8z6i1Q zjGwJr-Hw~n>AiKU_ts6yx8v%&OqEhI#-L{&8J)Ritf7Gc=y>jCyroqS=V58U2$cPT zn0LRLf<=;}Gqghi#eqgs3=9{{JyBI%UA`eYx`bZsMd2`!@pPgV9x=++(^GDHCVd_K zv@rY}m!V$NQ1&dre`ReA0LqTA-dLYM;ctR=kZChDOnqz-%D`S8l69QO7|9rJ9?QwHI~b#4Rjn{e=VRD zw4K*U;~pq&5U+U#TbewdM=}xcDa)e0*qBNmJ+2)Xa{Km# zlHB{CT;)=gjgkJt9Yznh+wsvwyMHY*=A#lN@{HxJKQI|wzJRia!ER4kh08>&6x?{&1u!C}VS zxnuy&S+R{ayG`#79fBcmDOF-)S}tzs?HydTG3jGhYPJ|qQu9s5K zMwhIN**t>kGtS1wMqqEe)>s_}ofdC%4ydrcbHEpDebv>wUMrf|JI;%-rEaSBbAYV5^|NI@W>%rIV8(W*h^ z&kfS9zw=Y^`cKQ(F(0jF=o_>B6D~`OJ9x=+w`71}g0<)@0wr&$P*HA7mzL?!VcOKG zBRQXuv`m_G4=i%3H0=@^GR{$5rL(6_ZBg3gNQMA7$@WaAyn%gRXo`&O$G-NMnf1YX z;ngvIuhAA1<>VMkPnt62&}hH3&``z5M`M^*WunP(q7j(0^@7R5G{3Q9TWH(@FnLs3 zS@#<)8A)*qkH_lnJC#=G)b{kw8698sPdt?69t7)Sgbfdc|8m689A$BFXsM~Q<+kGD z-$cH ziobOFbUBi2Y9ULdjX^<~K+?!JCrhtpOa^*`5k4o(htHf=Z3dj-vUo8Q3dj2d-w5H? zPYm!MOb~`UJ( z&Erq=ei`%di3}c@d6u_}`g-H1<9yR7ZM_tY)MR9!3b%=e91(tvN9VxJ2UBl1_rN~)3$l@W&&9lSOvV~ zRtnSFqD2dK;gQ`2kU1kB1ot;OG5|IYM2`DKS91C}_r1Gj!+<<@mll~ItDX0a^BX5-OWLMSoD9Qu)n?vB{@~OG=bwsx&I+OVwY{ z@xKAK6!8#Q933<73;^+qpeh*+o&|Uq3iX|oyo7IjC1Q9kNSZoRMERk4{ht*S9Q3yf zS>Wa-Ob(?Ae0gQf0r4J&V?j2*dE>xW#%SuhQ}6=>G}bNZ(}zu=Z?to?EEEz&%||r! zaM9oJ;d6IW)FYDS%WL~g=8~d-Ww;|M* zXu9Qg{*rdv_7Jyf+g84~G%dEz7BPJ* z;-R8&)57I>0_g=};4-b03a@4GON$GmTde3Oit04>{s#Xx@2%YnIeisw{8Z%N-Q3jh z>HN3z-LEKJsm|LN^RwjAg1CcSI`>++zLks7@WvN69M~MfCUgcg5i#$8{Lri4t z!g{k@(>3#><1F{j2c3oPT@F)`YA$sG`{rl6JJuv=wwDi98IPidymBqK;wu`E&tBcDe zD#(Sw3DPneB>He4*rQf@d!JkqJ@p{D0XG1Puoujo`vUN8%a?`b=6g*vhd~VsQ~Bh! zqP&}7o&3sW|ChU#udExDb6tKp9qBssYj#=QbLB@fU;D;9-o0|7-}eU8THI+CnM&-K zR~yOZj01r=868chnV35QF`+7oVfy5-ZL!(aU@GH>?};mOtZ1A!F=b8DcjLOt)32HE zdsm2}rrev>-PJThn?ASVRigHM(MCThYcN?PJRh8g{cqtS4^|aQU5?m zN!~a^SzIRu@WqWHVS3MKXeWwV;rLtDSHnW;Q|S!GHcM%*_uh5Y=HT%GjrAu! z@h`Xd0;So9lsk8RTt4ci@w&+lSGs7gulD!*o_O2%e5;yA0gZ`u_t_4sIUPSXIz;7C zHpScMwrsiaNXHXrNxM<)(&hAd|3c-xvy{j7x=<9iI!H}vd){yNNAytl7bY$U5Nqn_ z>xVol&2_yl($DC3sCvBolmX{jO$b+f=9n`Sh%jozz2ZrEGH1FQ_qxy+J78za2W+EF zo4)I8;M1(DSUFvFlsXKANG!PvI=7Sy%-}o$mbv2V4YM>#9bc%iM=dM3)=N4ki2JZ+ zc;NZWV$U_hTdnJFa&6_lh}R)uVVBSwqJ{#pcwn}a2vDr{FtnVV2nyGZzBW;+O<9Nf zdGTkvJx-i>+E39-;i{~#L^glCb@E+-|KKt0qwdhy1>F3pSY^n@&P~#R@rP?i`LTTH zVGzNRP;0yLk9yR=@pboMY1_1FM_-O^_qX{%K%-=h;W78L#C>8n3Y|A>N~vo zmo@*R%(_f>zfx%ecT`TYsiXSj?mt$gpYPaSR6qQ*MPX^ly;lLc?xVA%nlH%>1%U%? zP;CBu{4e7NoS>vE@-l#3V4F=tYzEfX?I)ptDU`JdWw$U2-iC92u1A?tRQ`Ort0#Z_eN;8y^(QNhs{f zZ=ymwA1ouPmkzQ_@U5#F5EQh+;?Wi3BdyjgJ+7;Mv`o2bjLJ2Z(um}|t@{40M|Iqr z(MBmhpxUcP^Eb}9L*f^yzXIXSy#UKO_5cMFxk>Qg$HM3A@=If%BJRXm$rwlk83O-m zVPq~uy1^)AWJJy1og6#2x97s(Kgo?yN3?|&uVn}ty5Dg=h8^ZgY%M=CW%|LF$#c3p zZ-;#*%^KP5(e>+Z!4d*PFuo!!s`4@s<)~HvD7TmOwklT#EiE%SCEKQDi`#Mf z{&}h@*EaaK=hKUow)binu&`U$@#F6y9?CqymN<8(AINkfiN|R3&4Gr7K7i=4vAqH< ztgWdW&^sGCI%3J^s`sZ72~8y)K5Eb@FMYt8>bXKcKrC_N7{xoTG@oL)9-pswk8q;7~|$! z6B84C9fmL;RESmGb?3cjs`kQeZQHZ~1U=GUnA!g0z7E?Rl7qh(s+-T?}9|EERLn!_c%fO6)qp8|(gys2uJe$-;|>0XpenG|uCRK0WYF%x17JBmf^1wN8jJc(r{eG? zEwMCk{Plg?S0UzRLJY_agsCv4wkBdw(4+HwXF@}SoV7h*r?m0++^4)f`(Xnk=WmjL z$|zTXhwiPiASNNyx}T`Zj6XGD3U_)g<14XWM{vEkFJ=)dIH@C|~*wFeAn zq9`~RDz!f2&Yc*80RyzPsn=%dr1aWty0h!BS@Y(lbEjGVC?S%1ID=xxXPgKh0Yt5H(H{4G2X)g=e7Pui{hFS(fx-{7_WCBRAjb>u|K5I(c%u^zvoPxKAxKw7^G4 zb3Wm5LZXp9(mAmJB$g^pNlA(3`OKNgM9~%X6&Vj0dsgp$fBM#QWI$?%G7dqQf6C^1S)R&p1$08cXW8+3HmAm&8A zLc(JdZ^75h8^2W0cO)hv)w2)suHS z*~_Y|d$niSJxEMIKoe?VicmQTK>^s{CZ>&KwE)vx*eh@*0By*ykE#DyHS)*nci#d- zgg+E0eZKrO>C@-VaTkW9qdLBCcpSXAlqrWq34n5ys0jh(obrqHrczCqo0}JOHyE_} z9TWs;*{st7{lOF*OLOxj^p+$v6VBM*{_1b8YVMd@blTio*eZ7G?8}xum%{EYNHM+B zLeYnywV!Y)tZ)eE2SMQx5mx}9eIf@fctkxy&;>%gZbO$j&|i4Im{p^l+JiD?TBn|Z z#(R_hVGAGaL-rw54>?U$sj2pX;;AP@>qg6#x2xCLVSlfitN{JXwowq^SLd%%1@GFH z)AQ0}<5$34#?_)mLm?)XgvEUTh%Y|#YKO|eW2?tdM0$-C+%}b^fgva(nX@#tufpV$ zPwwBJ91svtxUToK4$ZH6wyvX>F47bbhK-J$=5$$}BW6cYNepr$iO6 z%9Ny}dH5o>-4$-K^jptVnxADpKG8a@rPdqwknYeSbjdl*8zl@^0a_7^M@(5G$F$_y zWWlA&*>J&e+=DyHB9X7e%1Wtn;x_RtD=XOB2|K$^l3wiQmUZu57o(-~c-$EIDk!8D zM37rj&5kvKiSRJM!g<;JIv6<&<%eYtF$z0_ug>g_G*=1lN8m-JW&k#3gTncM(P`k| z!Iv4Au}x8jhnKJsD|>rDu7eA!EHQ3KckDQtAp=Z-VumLl*Hr@#xk-}CJ+7#{4(vwa;Q8JPh$D6dyih@t#ea+L+7#h5WMes3`wJ zem}3ba(s!|k>y0yWMQFja+@cGQNt&rJgWkO-kUPhkMNbR>9C2~inV$Rp zYG&~F{N2n

    pkv=;ybTrd^G(naHu-$dvzeWuG*jX+|Tx3B&QDo<%w&csI>8z!2^ zr=^99C4FQc)Q~zxSgav%KEH9Ri6r1IYRhh8{HIE@68dRt|ER9Ee14Dl1n9K1@1h+<>^z#Tn+~7rgo3Q(V?Q8iIa}LE-zmq8+EO`yeT)Q&bK~XN~Dqliou5T-dbPeDEHiW(fs*)nTH`H zE~hSgE0x$tU0LPvoUKz@gD(oE&pbcw+8+Rx6~bY^^b;uMMjx~{H_Bw0?2D9;bc}1(tie|g+c++HGZmRIr}Fysu|33HNBQo{UiccZ z6mBv!Sx}+mCpAKmQ=2IIylb9)7)TY(7B&nuF}Jbbo&jQML94-N7`(;op{jX;D@MG- zO|OCJjM352oO|?3bVD%X2CqYqbP?l@JSiommhXG$z)fUC;2V}I(Tb&V-EzHzAe8tycF{N#yd;K)^T9_OyF zY9XMHp$j%g;_{%VBv^IHk|mTQ+*_){z2YA@t%aaaT_wx}Tu2Z4AMq?(+bigMX&Wd; z=<5aZvcs3&hU5crjtPyI51CIwoS+cjjcbJnpCZZt$_lFV5vVT-7#V)229FO9nlNFR z3Y9PgAnsMGE*&{y=kGuIzyr(pnPvTwhOVC8(EWsUweek%*Ysab{^uWFdXl?7Y5mpQ zAy10J%9n%|+blSUo|%@Cyo;+SbdY|dUApmljY03u^tz~-Ci z=cB%cE$EjO9~i>7@MDw=rQ*~nTTN(Lg&{rl-2~8tEq^GG$@USXw$r*Fd@*(whwG+I zn}jm0lcfn+=s&-`MPo;0;8N6ATU*u8%?52keEdKSXM&gEtE#5A*Z4sB)&NY#II+dU zn^X#eyM5j{FVC+yU|?|afRcObD>pj$8q{R2c$!kQ*z3cqnFCf|8%P`k=B1T1qNCK> z7!P)t81lEsMWijWyWb{zUCCk?s1c0k@lu=SST+^J|4}HX`r- z0x29*vU<-#jmh5KKAE2X)Ne>hx9+dY4E?@e4%=DQ>wSjGHK`fVJtv)3_Segs;%Rp1 zu7B;*9}T~v0@#R=!#S2$ntSpbnsbfDKC>fXuBd>ka)=xoKFfeb_E zB`*p4IDo@JZ>fSPYJjVq{9`}_lunNyFQ>J&_pd7!xOv;lCGXxzoMkn?&;{KM(LmY@ zaWl*BtO;s zh^q#t+eImJK8mVjE~#sQR;3L3FJ@(gZ6rN0Sv~XTzbAw@`^c!d(>@0@O+X2hk(09w z*%ptjpkMxOw(}np%=sO=c6qqC2va%c5pr=GXf*~A><|yj8!gI;VJ~T}~1hr=||WJ|>>&cyYY8(7S7l_33cnK?6wYi?nv0@(PYu!P%MQ)gI4aUH-ln14?vB33*55KVAQ?&DFaY{DtWbE7(4D5`GazOpY z7FU$8pxqUN-`FikE~V*cs*G$BO9bvuTA*>+uxXnkAN2_&jc#XS$*up@Z7p811kJ*K zwPtfIp4S1;gnpjFec>Uw<@6onPWIEmO8@Agx{221FY!B~wJkwu^Uc-&Y|rLc*v{JKwTv$3?h+Fc%{{zrQDT5LfKV{#b*v6YXA@ zhb0wk#%*#eW}KiYYP~muOXVAc(t_Ysgclt*12Mf$2Sc;Hk_jeZXb%Z;m&56N(U9hg zS~cHm;W%MD>*cj|37aF&TgZI|3kS^IGUSpV33F1BR&1F_{Q61 zCYm$R2NGsMbvv(=afP((x=Ifa2=(i?nB-P|9#Hz)np&)NY3LsCSpo|ltnrLEE1=v` zE#wsy#bO5!j{rfxR8>WLO9EKR_Z}@W*5yZ!oOEwNEI>F4FXR`D3?O!f@k9$A?B8v; zFoyMk9t9le3K^VWAk+zgAzZVwrpdCxxC>rYa(_YaSs>#i!oEr!AJlxEhLc*5D|{Fy zCzs{?Xj$!vS*LH*bwJ8{thfu{PVMIx6Z;qe{XSkqwStt5D)?ZH037UXGqkJOb~RfP z=sv#$pM`k`Ef_-puASYH-Mc$$Xi@+0wE4){92$P$e?afaHGuZ>4*k&Tb?Bm&+$6Mq z2$P`4C=LK>!Vlx3E=WjT7!w%SinG1EoVMvZvah&AAMt9rr~{XpE{&=^e9|DJu(t4s zWd4`AmKW=tUL`bkcyBGr8Pfy4U3eKQvqz34?_fd>k`RURfP3eM7#c>m0}7#8@nS}; zJJA~SHfu*WfhaLLVeuHJTU+uyX4>0F_D6&cNJVwAPWB;6GW71h zxy=~P@A?b!G1EjD8IS9^PYYu~vT!&9ZPp7dkKxiKK8VdOBqx8#S=v`fTM_wn6!w__ zW2KE(we?vmsEaxJC3DI zp~)lcUtb;*7{ZxLFaMg}AV1#+M+x#M{@DmwtSp*5 zum1t@tl6_Cb+@vxNV<%7c6N59);Pl@|5DK8Y-V8&8F2cp8Sjzxs|K#)acgWS_;~d9 zSoNN}0Lq0#RLXBrn?V2qHa1Opx$A|CA~JrBp%aE#;K)$~5d4q>HHg%yDCH9X2k2q& zmMtMm2LA()+v$S~n{|kWm)RTeD6@qD9shr@V5hIxMZJ#TT|pAU;AGDA?8q^Zf)S?A zZd2Ow*}7H;bErw@R@}OA;~2mKP}ox7z=}_w)EMrowEa+cIJ#mKYUK|LI!IQHJc169 zOC}>6?O;#k=Z>^+ShwUzA4R9c0y1#`RGF10FB^pZ^+d3xb036ZJ9e}e#w*-IpjCFC zwwdorJI9*czi;1frm#=_^?#SE`tDD~!Nb%)d4b3*U2>o^GZ&C+ zgB~~QRRZ$V{~{^qrHhJ+x^}!nua%j3lFU#;t4pMZ{s1)C+o1`EAZnGBl^m~V zeRl;1pR9~NO)Y=x_H9rjm_S}7A3lgBC~r`0k6!i7f#u71p7UeOSm+b}9J~{Kmw9=O z4KW&JG(h7iDV1aD^xup7M;6vNhPKR(7(i;jR{P}bPdO~C#xBO4gDwSa^uGb z@%J>efa^Fycxou$|KMRKi)#-~@5{N{DeI8YBQ6&xH*#NQ$B^m#^r;s|0%beyPP#n) zspsRgXpu6zG+5aC?>JE`lSVFkv+n58w{*B1*El8ztek%_{}6gEghF6v=yxeY~jAb44=sD%t&zg|=S*{!mDaTZjtyEUh8?j8qzi zO)|DRv>=BA6cs$B><|M3P+bl^OdZ$>4iFrWL@uA{v}qSpQWlL~2Aj(XX3yy`YLp)U zA=J;Sl`cdrY&dx8>2BA$hDYGzD?b+&fBK|zc~%ecg@TIw^mOzrMn<(4pV=*$Hh%^sdg39EtloGYP({N{&#PnD1 z_5HH;n#|09=b0)94jcPAB z6^#!(H?Nc3=kky+a%JPjaexO?r|#f~aDih4p>JETarOm=77-4IsBiy z3Go!_>gty(?_vVBJ9I`*Zv4egXV0F+T8#7V(!8b4&RV%Pju$h*P)A4Nu15+uzZs;U zVxPY6>2iyFnd-8~J=d)HMX()-i;$zap|WQU&pcNTVtmEVwf=u{9(f|#c3+FCZtBzz zm34e0&)U^9lYhzf(~&DD92dF>pgs>O-}o15NT9uGk)ua}fNAdLwuvRQt^1E0;obO(A0>L<^VZS$IA+SFje^5|RkVQP;pO*j$ zNUdwpF*Ku%xL~zRf~D(@;NbEN)Gp>KV+dwXd^DQ98QLx(;R%_*;so-+wwk>A{FyGG z1n_;)qi%EVjDPD(mLCu_=KeEGzNMpKA%0jkl!K0AI4iCW%By(tcYHIF8Vx@mlC-Kc zcHQ|@K?rWnMFp$5CqB4#XOLgcBRTFT5?ip>t(a*ipV6c8oTDWNTg(~op`>JxpZ2-; zr_RZLB-wE|b~j|lV;aBj0y>4q6ifD5x?9AL$bP)o?w``%A=&y{) zm0SW~EKHBQ!{jmTkhd~Uq=9OiP1pSSrU%7^1qB2K`qOd4TUJ(AgCw6J?TRCdH>K9U zy;FVrSgPl;LXuD#cH(3Sl<#xFS`Vb4Pg^qpnfZgPpeT`rE7m?EIV`Q*H4 z+P(bIy0D;-K%7z}gh^}A*3s_)0G3x@AJGeQRU$LO^~o1d%z zffysc1abotwRy5@&xlshPAi8?GQSv2+-`yk>$s_w$k+%##J(~VZXZG&L^3+TkQ)ml zEni6i@BT-i72@9WP$kS`mM)CRmG_QhpA1-zIPXZuv5G-^)zD7K3%i3c8X791p)Whi z37RPaAR&t1zkA0~GyR`x*3|jWs0W)7+b%;~#2SIADQpYu0DwB|>n}*Z!zw_1XGS6o z+W+!$K{&wCNOeSsoHl;Jf7dH%@7W$ZClzYuIb9q-Il0F1Z?S99i-Eej=U{n8GygZ7 zdKKJ*s9@zQ|+N~ zyG=#w?A}o+A?ccIW@a_?(qA4C-afH;Ep=dLJZR)`1WSUYWoTU7S1cE%|EKx91D41U z%vrSf0iHcnoCF>F`8A-L#HN$?31=sRVkm)LJ%4_Q$JloOV_1J;$6rJ;1BVEmC7b=3 zn|S3AL_ukc-iQj)f?ozr2CUO^VmRuBX@rqJ6myrWD7fS#e~qj9M!7YB5CL;ck?u0WM|beF^$&_0$q16|2?}K& z9=EnQ)Edt7=?(I4s;mhAumRcMzn|ys@U?5#5*Gdot40H$N?tjT5Xme|?wcY_qnQP0 zM<_}08GSjySHdF8bQ&1ZF)w{*&%rv@w|vW-U*W)biSP?b|#1`{!DH9%=<>%61bWH}&5N;n>%$jvH*g(z9($?7q)t zag1bQd~oK@+T8G#FSa%fu$U+3xjP;7E;}HpeYVE*S2P}w>e#88qbT?PAk8`{cC-J+t=6wTbz$f6ZDt_%&G6;G2lvky zYQIodbdFikSqSw2#!7e<1EtQCRL_#537Wg<6l6W_3-2cqz1o%OR2^Geij1A$_qZ!H zbEda_qTWhs>>@=ocE(D60e=1$DO-zto`-%m`?@7+mD=W1t_9rzk6H0`-RChZ2M5NYAn2$+dqLT#>jx9r5y_=!5CV zsdne~ZD@U+{#hm2o@@;R5%zFK(fjxBDd2-PmLWg905?rR0mML1sP0)2rn!81zo4|* zj~^#6A>y5r>9z0|M9$)B(r=E6d&SjLu#M^JueGjHQd{c4;$bA1P`lalB)tL#EgJFO zez3UO)5^HgNJg-mIfzu~ImjTH<3w>-IdmV{1w630TV}vucgEt(TKVo>f!}OcjRp%A zjDn!pH92F2sa0y(Ti0GsV+wBFQw^LE*fV^iw#f?9Mg1+-&oi8)$H8K7VRescg@FT2 z>EysK<0J=kRUS3UB+@#*G}5ZPjb#^iAGbYo9$}G@F#ZR7aWIoJuap6WGWh(*RY461U`K9h_oB{KCEmuCD7twdc+MUr#c#xxYN+< z6%&(!_P2N#4fYzrd$ZsbIRE$W-)Wv;B`)Bj?a}|+wBW3Otelc!w}k_ zOJ@;GSl>*2bojpX&?IU9poQ6nf-Zwh_L=nS(DK7M2bfz5LpCc*4l-&;!R5(yK~?BKnBXJWti#yM9K z*S%J=wN><|E8%&Dpa7S;=1ABzkiuf5_{;(T>9lIpbV|NsiI`W|625>xKsz z_k=govoWf)j~jAyjFCg!D5H^H8YG=Ey?VJ|Ag8*EH)PfrvvcQ&=|kv1dqW-DMiwd> z$$+L&zqeE7K^*`}Y$JOvKtfgUo@87rq9C~~*k*C-5nOzL9d5gRy>WtV*#7-O5k^c%<54Jf^W_E7V`7utxmtUT)lao zuA?no96}kV)B{lqCcm4V2Y-bLLngrb*454C+6-N@<7-+vEZOS=p!7N?cIk5m0bQNi z$6bAyNP3&2wo7dvr)Y@^>n6B1^!hto7K4|Bza)D{ktxNavwse(p=evAu+yfIG6OBI2a z63;1*?ut+P(ZZ@F6=Huq+f@wt0o9%7{-L(^`T12H{Znn$mD`>QnR|`nFvMfX;bEnb!XpZrzo@#uS+i5H&jI!dcE1Gh_L$swn0D@F7Fs8U2K22dV4md}~}F$wY6tNZ?nxI*(18 z5ZEV^4!yk-8LiXu@erM$%WroY=}-E>fx%d2)4`x1bV{%q?k`c0zZ+sM!{%H9=A zF1+72dw}IxyA$7p`$j))&#T4aP~T5R#Y7JZe{GQThR_=qAKyCbp{TIv6qkKmIn?>2 z9|u!FU!f^+Rb;37vKH;CMdMxZ@L z^3%#Dj>uX1>+p-=%-5PkINhLO>05^D0FDMS-ej@plcW*c5-3(WXIHwm(Ohg z5gSdCYh_gqTGGkaZ&VgcaiKnAgY0kl_`~f_`#m|8q7!BmJsM&Zv3xI_mgtBG=Ea2_ zZlPoTST{GP%M1o&U%Pp8fTE(dgP^{<2Zw$cz(_?&LRC|Y9=Gw_T%Yjkc6%nNi>?fG z+bTZgZfg;9mH5C8B8f;=4>fcTXz%UoD`=LFWJ9(acHoYcrDebWAj7ARVZbXUQ8k}F z0k83bZzk(TjkRXYnhrZx0D-@HrEO?9M`nt@yJ%n7R;m)f*rL_~V6$1{EU^czUrq@|>2V+B2XQ$ltK z5u^^Wq%i3bB|B|`R_(f_AD5pv@iN^DoTqvp=-#JK?1{r;{zD%4?mY33&M7AYz(+p3 zld>2Na|VqHv$LRkV=}Mh@R~xA9t^B04lc%;jAKg7zbN6mE$FV4(Vp?>F@At+$WQV+=UF6e-AmrlR)}=OGi|4&GStK`^9&14fS1v8fSZ-)SGfAeDrp)M z0Z?z%??;?R_nkk%A)?PzA&u+%+Y+%1Y)J>T+xIm_gU$BL51Lx6@?vax^t9rG>4{5$ z7md<}K`Iw~dDGGkNMK&n8Oj&f>@kT~#l-?^kSsgANwq$H;zUy3&Z?vy>lz!rqXU5x zQD@_SnY{NSFLHAT2a_oyUV7w;q}&!j?Z)a zW{PIkA0wY9DHb$kD!s%$P57j;w!UFx+*`qL5);=FFqFLR#;a(JAl2X~HGO->{sdDS zCIk(`vw*ELE`{1Of2bbh7G=J!_PCT-I(7L+&gBfkw zHu=3(#Fd7^E;g;lr?+Xj4W9a=GzR}&nT!)YC6k*c`H#?#7&#I+ewRdNVD4VM<__B0 zNwwRs#k7m(3$_gQ9zPLbNXL;;Q|Amg1P2_~N$wja-f-}g#*g=%*Sx>mFo>nb0rWT^ zN|u}p*zxGY3k&x>ipz{@mETbJ1Qr{`cM%>Q^Pq%$-OKg93Q$L!rMoDwFyQ$8Dw zI={7v3WYW@>gZEKesck;5)of{wB?vB3XWR`D5i{UD<<|NX`>wtYe>2~8L?n;y`}1} zeBc6v)g#g0l&Gr`0&`F6_dhrrd#?xg?*s6Wy5BH6-}N?*$vIhBE5Yge`1$)k@P24o zIX@OEY(Z#er_mF-%z3GECime!(d(0j|8=<~caTjy*;GX8by>yp!h&w=r%s)E@lNvq zbW;_8-zvtZru6L_Tt4Cy^N--Ij410l0V~W;W183(3ZAsku4X3X5VL9!xx;Z2lHoQj znzQ|7Bp;R?v`t*i#{{>c>uCeC8&d$oBCsNW;lK%plw{~pnbZk$=vcIlT zVeO|c-EoFuU*m=MO12rNo_)HSoRfwFT06M%IH5piPFYwh>hy5?sjjwR zDGI}dT;(40U^L+_^x5=&>z>}!U5idH#;hDJ z6reCAb7>vC9Qu>Q1L$(_Wziu8OmSsWcmplO9#DN^Vr&>XOZDbc*~@-(LgcbbLxeTM z>+00CjReq*TejX~_vO`3Inh7X{aMFV-I~6dC{2CH)WMBdD->t|=rytCE-$kAJ~HK7 zX3|c?47}c!!==jEH1G!*$3GSi*$L-+cJH3M{7Jh1OVNW(Z}r=M3PlCzDModT#O_~@ z=GT{v+QN(owt7kV^N&~4SN`#DFpU&6o45Gazn0u+;`03C--A2e_)C)b`xmxMMy(dy z8X%v1=Rag&^fwHvZK+&}Z1snEpA#k963lEKfTSYW$|WWXEA7V5ef#UJONJo@6|o;` zcHyv&e8tn*6CV5@x7>cc*N?y0H`9Tvzj&DUr<9V_cn==|oQJ6}&rfLxLb;na-G&5v zd3q{Pdb28s4m5WmKCAAUJ-~?z6ALyT#SXNlEhpCk@G8tnb#gjk{{1KfpXxm4{AfCxt3~@#45T&wo8a`|`mVub^+)nX7_;G+&i6KU*R4=LEpXm9%&G! zPiVc(-RO(K8T#q%aurk!CKkeWLpel5kPPHRi zLdIIu&9JGA{F_nz&i+BC`^WQ5*B`#~+Cfk1U)N&POpwHyRr-{T`A_qgfdR*L4eA=7 zT&}(}7+PRsu6Y0cd$+vv-@RPEa;R^h#y$6}*UjDAQ5YGN-n$;E>;SzQ!A!1eLNsUc}OY{o1MBnyEO z-Pv9e66sny7uvZ2%xHuu_UorwA3|dX)W%H$CKIHKyg)B6FKAkPb5~WQ)|N_sJN7{C z{QDI?de7BmZdj$$7T(dZPi1lOSX|`LNk)7}?+4SIl}L&3v9{JHC%v;OL%87N#qfS0 zl&CdolMb(Ve#M0(yCB|b5it|(Z6!@`Oe7Z35QgxSGdBLfwXPcJ1n^{rWe526#6#9k`-9`KK zm>XnY{_u99XxJhLySpNp2lae{!Ze>`ox3Qh`_lI=9PJ6KMO9=qhnu~)HY$3k>YfV` zrq}({H-4P9X^fR$Xqx!RFFk#826?=#E)|<8Qe}mhd{tP_$N6=`mn(?IBi{qJk6XE1Cou|Di&=da8>tOTStXRAD48jfT_2luh z8LRiErDU_mKHhslKD3mENM~j6j1Yq+Lu)RG2lwS&dGZ zea;lE(_h!ZwW&fV$^fbRLu1i-3}-l#m@woF9Doc#I5{rbIdqct^7E7L^%jd2kj@C} zMrL{lGtd|&1{>f4mMqAYB5D#^|9n)!pS>mbT=lz*`W{sh2?YlXIg%^7NGc&!u`ulf zR~$RHZG&r$eBV{DXxl~4mu?N^k1!ntzdw)lo@`)aj6k?KP=%0v;wG2369`6N1`C6e zPzUYY=~$XMkj@W$$^86@O-&$c5OnP{vTMc*K+5G=et;7KP~ez)P(bU34^O>!uXIY| z*ZJsquqX-@L)V2)G&nb5hgkc$fs+zo_|YPxd)7f zom={y5g0}5IVUNEk@kOn|K9W7N|*?$yXXmB!Q7;+`w6}QLrLIYtObR=hJyWwMi_iz zw6P;R)}r#J1_v{~#(U)Ce1=EW4#CO(DO6u!+7^Hc<>mgKo?1py(jIT4Vz0Dq-#(tf z5}!W@@{~Y;Wy++i_G`^&mNjV+Qb@a(N?9FMrz#~Fy+`1L z+i|+KmCd_gJ=AU2?%ft_vEes79~3zq6wI-UJ~E)q;ywRi*VIoUN9}oh$%yU~y4q$Y z0R<9bRCi(LS@;NA^e(0xA-EJ~yvifQ`ui0;nZs%y&}5Fe5^&<-dn;jyv#02yZ`dHr zp^nmm6^u|qy&e2U56fCjcn~)$7@KHd0CrhK^ zr!B_BV5O{=Sv`-#ebkQFw`*5=LrHo0Wtd8`Gq{h~VqGYv?V=-}jp~f|VPJOHz{h`I zCHT+nnVqEeAx#zhdhp!%{_PuVlPcyf#iQ=%OPYV}nhBN)SafAd8>sGLNy3S!!EgY5 zc;CJ+0v&DNP`~# zo;(CsbCv!aTm^s!I3Q4q6WBvts zFk4}?Ju@nC{7RA1*-;PDwB=S?J~iAE`Cjvliu0IWW3~rMoa{FG{fnbHU1ewHXDOPb zhEDq0ce20o+{{&?3pef8EI+JP{nfr@@c5{&wIP1WIcw%;Ci!UlJ*b~7qP}R2Z+Ln9 z(jb=)Yv1>5X5K+_RId6c|5wk0%c>{tkNDQLyNG3a%M@?LnySFXZNzJ3<>kwGl4|BmoFz)&Lm0mDJdZNhDLo{()A&2eWohdE?8JwvU8`4L^;l6$b-{Sqiu$$8t z{;@CQw)Rsf*ogpw*Us@F8T}Ogepmix0NLn|f6$crN7!92{YzXnuMB*L=E1hNxER>-&GGQZP)SyAd%%h_v zh;K**>wt31YI4tz|6QEjxkm6!7TR|4miP;K5(zEyTa$_s1vowYTKusZEO+-)5LTIx zngg_eANO(jbg*(dmx{d)eoIUdfMN@$F^L{OgAbZC?ypEd!fX&SV+C>l;lrfO-|J|J zTA7*2xs`ymfi^E*eDvZ)NB%-+gj(t@p%G>a7EC|`wjcq?eO8uH()SQB&PNbC$niuq z)R8{Yc#<;P7Lb}~dxz?7HPv(Nq@L3`D`{83%MhC2hrPWonA{MRow0W9T7Cg;L!Txr za{Qw9ub6Au;g3%%)C+wv8VS{rr(cHqnk{2G3U>xNS0?ZgXhrwx5r}p&wDR zAM^C=>y~b=Bp70tn`5yNMq3DEAED@`v>Oozcs6>DUv|JjK-YlO!jc$WRW*eYYe(BZ zE<8O%SpV-!p0zrM`9^-_ix+*Z;a5ZDE3YJNbFNtLI76?3c)?D>Pl>NNcj)I8+(s4#2V+$Gx!uL$hPf(sc8Bu{ z3ku>6=B^!Av*5-{nL}?K936c&6LwdJ|9NJpoNk$ur1O2|MJxjr<_XDphcwXAvN&xq0)IPb**(Pyb8!^VfDS zIW8u?oWg@%A#}?E$kCv}4uyya5jU|CgZ%x00e}~a_)QueF*%YSIFJm))O4U5M#dSH zMK50-F_hUjykqg^ z?6qH1#lX85BHgLe@$V#lg1e>aE+A6M0BeTy+$Xh#lG|36NUSV9_s_&?%UfY{a*R*@ z`sOf~h6djS9L=gE!76tIEiPCb*vrDSH(zss*4H?C;1JLLat#+U{>n^r;DAQ(?6WbX zBnq>YnddG&dDA7bMtU}c_c#?Rshi2~HHQQA!c;^DYI0=0#6;J9@VWtQU%#X!4@XU>$s3hmX8Hq+m)xPO!rOoZv0A(7WdAEbR? z|3utL^{BzatJ_x?EOL{yUiiRG`S8b;?SoPq%>J*Jzkh!Y{&rMh=8D!Llh$%@Dy)XP z^qMTFkJGT423-l{q{yJ79N?c4j<|FNsCZogg8_xCD+ zYW8gBC(oB$uSvSy;m z*0#4MV_HBj0kR#0DfJtIy-tJGKYU>3 zM0cV78|-zTj!y3Q*&&_AZ1C(@k{}}8?#~Y*HSF`y_=mj&4;2zcU+`$cu}1BGmh zL`(o>fPIQ_u`th#36OY2za4e9q$*lmQ=n3CQ-^k$RD258Ngt@sceFn@uUN`FQPQK= zA5XiCcCIBXc17QJ3B`f=wDJYihCX3iuz{I;W?)%23B)d3De%lAgjD_9#%=y~$sihg zj8!vd-m*(msm00|pc$-1v({!e6ZqDg5EK=^Hfz?5)ZLPO8ZEUd#?Lfn+eOSg zt~L8cTUjBDFJ2s;|NKnl{WG^_Y;URAY3Lt^-_az3H|Wr(%EEe3VTIA7ohiWD*W*$} z(0fG}f|!k*ftXwQ_*9zUOGq3Cp_x?ua5T9#W(tZQR2?^N9JWplKme|~CQo~T(!*_k|4NXCf9TD%_FMiBO$5Lbv7vf%PaDzcsdS-~}_LyY*GCrqyFeeBq<_>l&2cQKk|#ehgf+3`q@ z+*`>7+dS!8zQKFz$+E_rOF~IgFs^d1c7&wrfF)^G@1}|fbqE$n> zjER3Ye5UROxpQY*By{}G@>`z<+>@=724o(}J6Y4y_r%Gs5h5af`)}Vr{AN|~#z^7p z3so5YD4Vqwwd*OqJtXPe!O0PW^lHTx~IM&AUIgl8A`ItWJy1Yqe4u z<>4|{qcE&K(ffw6u{bDn|MG`3(nLzx5wKK4IGO^hlEa_3N+TrI#^lO<`iun>RX~ z4;K%D%o<&EvFc)2=%fK&9`-u3-A6bfEbH2?=RZsKP+64tI@e@vu-TuvK^6u8mT&GJ zgc?h2$BVVpL&eFSZsGS?dQsV2X5H(NEJKPb%XlXYP$-FM{IE(nqcYZiuCAT~V?bTK zH2wJY3(3bZo@BGoZr1B=i9y(#kBLY8@Vme;BG>wP-c7xWfrp?defwjqGW0d_;iYxDeQ86-#4ZwMDM8gzyfQ3aVF3_e7Bkt1W zb$NNz*cB9q>~}W_Mc>mvHhH?jNGZ5Pveu3z=`Shq6P=@%Bq$CUaxX8h4jC#?J|~?S zRkY5C3(mDRvNK>66N~WVQI<~SC?Qh0Nl;A-9p}}n={;4fIG_SGcZ#fA#up~lb5=X7 zQp&5qf`s#N2{XAUn^IC5u@ukZdaqucN_8ke#oJqtTzn?jd(a*8)oR6{-%5E4wfS8% z8R&z7%eI#>Td~59=O{DQMqFB{1f9ati#7pGqfip3jnF?ggLP%`*o+jNGmVF*Jv(ny zwq*?$YxDeyk(QRi4`bK1vT>*GzFz{QqVKqgp5TpZ9)W4~o8nJ=eHAZ|K7YQnq6IG{ z9UVL;O2=Rgj2ckZO(Tr@NC4iEH2M4IL)dqhz*G$1_KA#m0F?moz**H@!ZJSZ;X}b~ zRT%q0mCh`@EI7-zXEh%3_LfuDn7NF2L!q((U#l?nY)c2~F?R{rW&E4el+8&tvn}J9 zeT}7K4GJ^C8IqO{IY&$oj{A5t-MfFkvnrR?UP=Kh^fMNtLOW(n%6B=p4V4MSb+uKo zdV*%w@!bv)S%qg?H?141kyY*(~3j)WH`sYGF z|9A?~F{fr6*NWpum@Z08P!%iP%@D(Ka1;V&gkBVr(L=h2+9$C+c}Vj$H923kXB*Iy zQ2~(PL}r-OMeF>NE~92IlnES~{K2Dx&8LSV@&Bk2vQcPMJU(@x(od7}ECqaredQ*B zu7!Fw{`~nas`gdSRN(6&(ws1X+PojrI>ZiQ;s?;& z@z9|7uA<$bDux#f!U2ASCJ$f*@76{ZKm#;@V%E^;o4i*U_bzwdBBQa$aQU)IP1Zs| z<~H6oG;6$^oEge2<#(nVZ1G&`e&fl${SrNTSj3$gVKMLwo$_ddcuU|syeYtHlGeW5 z_NDyMzQk!7;Nz^OuzU^jIVARF9lp@2T0_*OY1m2iO>r?$N_k+vWVkrm_N5z#$uh_jzXlEm^0}GFU<=zS$lk=VfX&HBsv_I3oDbCXBZjN4=Nr&0R7A_xFqq)} z%5yl8wUOnU7%NJW=OzIy1F{RWz!XLlkD2G8cKFDVEI3r?jerT}c#z1EHbDKQGj-YI z8{#M+Do~WXZXr8|xDmuv$jA@`&>qXuUa+83pFSg_P4wyy)6h1P^3Ui5<<6YDiRc?J z)Jn=$-9_33cn<5P?6abi?Y`S)_HJcPWtJRFL<=MXcsStC%YqSz z2Bq_&WkR2QkQ*?7u8mr~=cke_&026Qa%w)`Slp{(c;7H1@iebzU({NUbu!zMN6|hv zi*Z8Wt{a!mTqYDrYd1Yc9a3+z=-~-}9^HCoH+bj7r&?lrH5jUZg`i;V5Us z`<&M@O($!r&65gZ0eub^&U46!nBeQnx=AKPMOks-!d2atS(DZ9M#>|#Bq_Tl%M`x4 zg#}so{I;^RZ|iHTMh>?O4wyG~cIk%rVl9T?y2OFRKo6Qi)MC~QkaNT-a-81|(LskB z{++yPZaJ_wSwdAl+S(rC${g=uUkM#T0*#pv6fv>};R-=~q?IkRh#KGVFdI%U07Wal zAcxxe3bsu=jZp;`0c1Iv$gW77h)PGn;=mkx_3SCg1L)+@1{Y@h5^q&^AquB`jRh(@ zm-TJKVMBqLSxKjxt?hIiQYN`VFjiq^J$1R6`3 z^!d0oUGAOj=$CPG@V$S)|UF>}tyio(l_ zG>)?C)K+EW(`qg6Sbti%^N>3^#k$t=i_ZQ61V`VKc@?`T#6o4($#9F!@*-PKhMfI4 z0GK1N%&y|_Sjz(i9Yi{INT_@n-bjD%>(H3e#MqQ62Y7&(Q{xM_;p((zt{26BYuk0i zzIjhdiYrDJfWtJ2NNcgj#vd$mF=?x7xBhC{W+?0HDH1s=B$m3&Z58 z@Jp^RIQ|$u=P1}owq}bR1fO2K_zMGC5e%jIkDc#yoGU0}L)5e1c8d2P>-5IyDfF$m zK%#&R0YBq23NTC+5^R!H=gr%%5#~n+k?c=tv#qVrY@uOXi=kpIEvD}X&hL203`!-S zS+OxnPX+OSG;!RRJo(w$80vd0{c$0;BMWAUkprEo3`v}|=*Emp)!-eLR3KSu4!h63 zZE0xqF?Zqg&0Qw=rqdtB0ExpG!()9jvy)>?awhFvU)y?}!Os9Wb@Za@vLzz#(+AVS zRO-$KV9@3j)M4PIVcw)&$4{TuBniX&jfYG2O)dhFfkdPaQwh=1vw9(f3VhLx)n*~} z8u@MAU(u%{oRg7Ds6x^CR{y+FZ?GhUdKX$-aF1jIsc!tmj9g&qO*l)SIz z7$)^_MZ#cKc65e+IhYh9DGBs-kSq+0jW^SlA$h6@$qVVC3i%)*ad)Wc81Za55s~or zA-kCcT7aG3(NWVcFKT~pspI>y&KBe*?(^h?HaJKK?JZ-Nz7X{Q4`w^IkFn`yVL0~S zudG>VShDG4k>ImuI!pDAgnfqgS9smJ6_H&=NhBr<8J%=wpfxTc8Y=Ch{PtB2b)$2Z z{@wC9mKVph#AHKV;rIZaSL2M~1Sl}xPAzexKIud1I$@*~kAcEccd#Ut*~WKg?+Cns zody?etW8X0-4w=-^|>8ua%|6@wh`0YN43(J6{%vJTtB_ESAcA(0t2euBnU8MFGe zo|7|~bplDrU4mA^{5f+Bk=jzG)fU*LF>ROTF((!Tf-`3nAOT5#j&5%eAVm_%p=nU* zfSYq;Lv0E_QkEP09FmKmbsye*^rwfT(^xb;$E^+KV^V{17$ep6@_vZmDgfgQo+Whv zIo6ofPZVwxlC{TZ4Hj&+`6V>7@N6x}odJ;w#VUZ$GYU`ahz0M)%X6%oi)_hL@RO?Y zU1sHbHEK?%_USKfc8LpI^Q)X^j(Qm+fR4NA6>`cx=G~aVy@Jsz zf^#UIFCArXa;!1q_``Mj*7)tyMw~Zyu2*IMZqm|am6d`WFTa1$#WlkPl|5+?TTB{z za1t)d^Ltf~)26veqJZ1@5se~H3-as8@&aVclwO$lycWuyjvYaUggYJPl}x%#Com_* zh)JLqxkKDG>B?s`rbs38^79!_e4B8?B#`4;QbuvNOJ*Pye!?^h#Imzz?}99Ad@LR& zvgHl)iyMVmH{l|5MY@xzCwur8s>aCLrOUPXX0OV9tk2ChEOZgfeuG`P5D;SWkA zkjbt#@7JB}F6t3;{O%O72R!zktEM)H{sQ_~v#mGZWr`Zb%PQPuUX^Fp{=v+^OXk%zy zv>Nd)0ED=J5fLOpM%}>d6$EydFJl-sEf2}%d#G)=8~7eMGT`t%SX!4I$}#<6AYLs# z)6lS3d$9H(4-q);-o9)-khHU#H@lbAI=`LIKGqOBZYR8pn4m#Pj8~& z^XI2*HIIRM1_tcg2KL?CqM{x=7XxSm1NrtgaTz7{PUndo`eQ$W-Ae`N z)ao0aS$2)P-G2Va_YztyMa4cyRNbFp(oIC{knGQUZr&SC8v)G1&aRrzNv;gv;sN#o z3{lxYZM4*>bfD}_7-4bws$%g5M!LFPd-ujP_5t@7Q_*&^RKh$@X2UEuHN~Oy3`hvT zmTs7~!127COP%g6;k2F9=qr$>us(eZ-nMlI$ z?AdpDccMz)iYSj6VxyQMfZ*;OWf4*yIQJQjxBOg;KvM7s6 zOR>_yl0(kpboXq+B1AAya`P1{MniPLEe_k$cCyeqmPZR~ssEQl&L4BvVZsu^qmWPwgK14Sv8&GG|z5)IEz2X4^9duJ= z45PENGw}1ATl1j|lHzc8U@c*m;=N=0mwL-9`K zOZ_X1?NBYTX(!8Z180L}7M~9U0D%USsVXl%Dyx`$;)kHPA}88k^|*v8Pi2luji^pk zHZ@WmCCaB06DZ%H2MH!1o}xv7c*7V zC&al)z#YMMIx}CH)53EKA+qqq{sq67 z#9?yvaBU(Rpe*%7ZA)Fp-u7v_?N4>zkp8B&a$8CS)JwcYPa9p<%eTd8pFvwpAgNI6 zzvC3g=T{iNlY^IWj>B5beX+g#_O~r3&D%m{1)LH7^;3pijePUo=Wrx}iO1sLiQ*F1 zPgeH$v>hIM_9)_n_-zgtA=M^_7r^q)4!wFqMH>{j;S~a(yhnMT!CT&e2DR_JJ!ks^ zk(&AS%69}D9M6c-OP{u#o*o(dRpp{@k}w~y>Gi($q;`a;xD>q)Z3BZk$_hc>A$Bkz zK*;2>MN4hkZFj#ET7hs2ESm{)vNzdMkghmq9ADpV&n3#vAS0bvl@wAq$MG-J#5l3P z33nQ7R)W#E>LYxF`CH&0(jIE^{T~anX-K%jy6={_{`m1|NOYV;40use%3=r;4bqW$ zY!Hon(BnMo8{s;@BC*_)G1hrm64BmD0cs(gROxMoBqeo+FIskMK<0gDhMOJMmN}g{b)*L>D7ymKcAl2(qyM>`d~Dk^B#c#G7@y&{Q0gJ z?8jHMFS=&BCGXVt#9M#$EkMBT7uhEFE%z+5+MH%BS4E5W$Lm`%6Y7PDhV-zBJ2aEE zEsp#FaFp2WZLE#ipIE!?7}h8>#kt)MG=T{`82KVw#YnML%a#nX4~9H;*{5;~5<>hG zKGf7yqTAq~g`gCh&)(Dq5{j6m?^q63I22hA|Kxk?L4a8~ z^s3Ws%eT5&j^Ucp$%zCoH04x*@dg!TW%9Qe6`0JAaN>5C zl%(Kxfr93A{vAClAdAF<<(tRGc0bRN`BHMnotWB+D<t&J?0x0rZlebv^5kng-nW;9!&m+LZgYn_&soqlaQEtWQ!BTp1`nEHw8HyycIsIwxQeWZ$KdyJ z@X)R8QRowigt>!Qx|75asmnQu2rryi92kmD5z?v0_?FGA_pk#;4frboUBDjPC90CD z=P{~?f+KW2;TV&ocCtURJ$rZ;6~+#izPU@Njoy;+rTz0+`_}u@>!#|b=7DjU#!qdA ztZ-n`$6YpUjV`S<89skr#rcIMCdV@Z4`B<%aanp_deVk7^u&Ht_X65DaKHdm2nNTs zu+E=0_AaPN50|kS`z=0MhwZ2>s7pC8d;EpTv6c%H_Jo=H8_1pZJu;~M6#wr=>al8% zo%U-kc>GOAL}c!)6-DYFN2gE9F3uaYCaZTsFOl9oZ3}NKXhc@^anX{;rh8mn)$HE? z*+EBLBM_kc4jr;(kWGXN#|MZ_qKpAMb=Z(03nFxAlY-y)X2FE`0=S1_ zatKbh@QU#S_1M3E3<*4Ei|dz{twDzAN$HE3#4V7nCJ7fzlYb2Vq5!fOH;1B1ZJ!jD z@M{FyXsWEy#}-JZgom5c@gijqh`0E=khJhagJ8ruzThIVoRx5Gr!`N|=9GhRu_qPH zo6!BBfr+`+prB2M$bH7`HGY$LzU0iDlh3L?^OBdKVB-k^QeJmYHKe5g~);&OwBdff=>Y0()!DGjS5vsJ-W*=sD-<+r# zNH`8az#Mdmve_>``bf7ImXpVo15)b^u~+0hvn*=>!*Zhy$5PWLOB&Q4UReK5$7ud; z)#K(+7xeW7#M?~*RhH^5p|$|RW51iC72|ztwn=6u`J4A}F^qVra&g+TSwBx}5fP=K zdz>AwJ%7Yjfv^qbWsvL)8j`LYTs+aXvP8eh(1{A$tJCwLZ%Kd+8`u^~QGd5D!i1TE zglf9bZDlECAtEsaGE6TDHSr*!gtWJ{?W`(g{f+O_k=G>KG)RZ*jv5^~vI$ta* zE}qkFndPcc`wG?;saZc%I~ATPw&S?88rBmo_^1P=5I0E=NCFLiwe1WIbImw%f*r4; z@;>V0Q;QT#OlZ~7g$TXgD#VThXN#Gt!81L_xhKhM5#3c-Cga%cIid_u4P;8sF+$qx z(U0z7;iYxcf3y-w_I{YIydebq@i#He^FxDbrS>dFSksHTmDArxjE_9B0rmiqygSFx>T~GKR3zuFZ3SA|)Do>;g ze44cJJXgf?beF*K4ZECPk7&TlE4_Z(coGxmQ^vI9jvjr& zNlyAob3%3o>kYePHYuJ4W={sYX+`MJ2oOm5>xHS+GLPuPtwXA2F-qn}4-#404YEED zVC;l`=85v*N?Fx_35iUzAP`oXI~{m-#lCzGpZ?;-09JEH_>83K&H0ttZ{@mm>*!^2 zFsW@neWU0(4;BBJ0)-ar%UcSYZ-{Fdsoke%>GUZab`lb(tP}pKR<5=eYzhq?yo&>S z2~lx)nxBuIhF(YpDwSY*l`IYp33zRp&RapjZ9Gr->BRO*Ey>qtUzKoT>z_Njpu@SR z8*8!`QOE>wO`Dh5^V@ZPy|mc4!4-+Aj2u?(^+A~v)J=ICK% zR|0MA-lIo3-P%L#il9lt`(y^3|0L}$K_v=zfpq-11p2o(G-bw4m;+iw11E0p%YB(6 z@;-24(*-8>dJofQ4B$zvZ&Q@_?>L|~bEZYD$AJT`s8wigQ8S2k=*fIEBp56PTMKuo zLVfZ6xf5?Bj*@z3xc)LQg0q@$-ERqP;IvjenprOJUMW@KIb~fw1XVj!gb^ z=)i#kLdP<}e(6kU53^f)y0T@uO&zU(zYiTi4tz0LCFxXRo6v&5U|8U5WST31qvDr0 z>j13(3OInHn=*pD{K;i|_U|V?q{O{{0!f5?U+GGgv5_Z1AHg^$hWM|*59%XuR@gN3 z0Z)S0YFv!SnR`5b%6PREqbI03G(Anh-v*dXY=ORh0>>TSRVH*p!{xHAW{qa!-f)gF z-&OldJf$TAmF&sqpc~dfJ&IJE_Pq=-o!X`PeQc+r-KZJ@I6CQR&Z!SMa9}>X8i{`L z@*4H2amJ-r;Une(#bUJk2~zsFaf{_+1WZ+c$Ji`kbGp;5G=0!5IkI`_4t+J5uu;NZ z{E;kI?;aF5d(NEE6ZX>1p*eopzVsvQ8<|JpW8XrsVJK|@?+gmEi6&v@_X~02eX_ro zksfGBucGAOaL4lgBh3Wns}6ApA8(sH`n1gXj3Go+AulXEzvFe_`2st(U~fsuH%xaW zwsH(zzI@qg>7X5UrC0V4hr9IdZG)^~i`muu{CY4N&WMj3e;+;wZo`0qVGb7vO#(NC z1A^2V{$o9TU(9OUGv>r6+SlQSv$3Iw(BmzQCbVzO>g>pD&Kl19!DU7*&6J)?r;4b( z9$Pp0M6S@4rB@+1(;)9a9PcKf{U&ip+~+~3K0l2}3{1rM5s59Vi(!J00HZ4hHonk@ z{m|IW)?#6@cg968>1TE`r~h5MZZQB)m@{d!eSPLYk6vOTSw5O|X>n~u!zNbAH4zB^ z>cJWqw=$PxOAEap>NtBDQ$@6Qy2Fwq{iln1?vG3SHq7+;N$=#a@V03)#;osKdkt3f ziI`Dy>T?wD?3Wt#DjS6Bt?#Nbg-&aihW0cJS`;6#ikwB>Gn!`fdi(rNL}a>aU;RzD$bE@FGQ_w(@wv*7%IqE@WrA%HjKK5(GiJ@Iud5rgUh-E$k?Ln$ zxZ9+al*rM+0t~Z33ib5UC%+&*k*T{5--T`!~AQhB%>Ml~y$EGz%J+Cc|2a+cq*n2Lo&$!KIi`6 zhlTW=H>}zH!Tp-`Q%IQ-m|yTUb=xknenGWSi&X3atB+N?m>nJ6Z0VIIO5T>lej_U{ zt;_MrTCO!nbJlS!V7oiP>ln#FXzJKsRV2LSp{rUh^uYYaSUWM6jzYU@*P3gs`#_(i z@fQg)slAiz!L^|}2qO|`C-4X?pCx?-zIpReK57w&{M(X}FW5LBoLcnqXyVZ*OU>6q zA}77uIjz<&aI#C{$ra6dcc~kyIX=q6#$h;v7xLmF)IuWe?)kLkfzLhDZ`V}bb=rJG+MmvelR{5z8)Q~0=q?xg4X~)JthFl)` zUAK;mt&&tJK0>E%)RY0WG8goshBNed!-u2(I<@v9CBJ5RvR6t6Oy6C_-@Fk+PbUsm?Gy;xA4aGUsB+jzQ zu)J4(+^Z3G;+UAugf*R+R1rs>-9^%uG$_tXxXlmiwDL=FB& z`&nRilg3T1e|H`xR+J8HUz`(r5cdz?+gG&?jFQS7=f|$9ctAdZs1MK}OdZD=11c>8 z3f{bX*Ap)2t5*V^3CJK=`#_(7Tg*w&FT3Q*xj9V1padc98W)c79EWTTn1mQID2hS#A( z=KwLVV&o2c-l64PnBam1)caL+>rruXIsK2f_W6r6z%zl3=05hhpVg8s@`j zi^!niS!AA6x$6L9_%^I}*O6PBnZ4zN7iMkwYRY+-O^RTs07P|C?xAkupxu$8Pr#?@ zyE<`87&#F%rB9bG=WPln4Dp9vAf#?z;T)2LvF3%gc#oZyn?~MV)Z^x+v`+h8kIgk# zTpa+dcFrn9!IYQ9Xy;Rp1_hdFb@f@W`n9iwnfKfP8mQRT1kw=<(}oPCepJ7DZcJuvynT7va!gHZv}pKe_uTHoLGN80XD}Gdzv85t<3V3?_^O&Q4G$whQjk;hJTpPCx^BIuLKHp?|{M6^^a zEdy4%h?bpfy|L=NjZRN1#1xa_*F`&f<{5-<*Ys{SH06rH%qzE>*rv3gn*a&{tv}bS z`BYQSmOC0r0rB6y3vjeNU7!rGKe3&;SM(7l2j6$T-ri<7y1#zi-;F`(3|hVp))g^j zHfm;^i_Zl@gcX#`+x20bfE_vx>A^f}2&0!sxf4J0rXL06O%EFAg#bY=1YNfK0-u7u zaeKe|6rTeZCR>pH_(3Pta$ho%{mEK|FYTj;Sd-<R{+N zhPh8ZT?lIN*m_XVmX=ySKIxIQ8NZ3w=Ip?r4X@fj43wS0x%h z!uXihc{|zAvh8&;t)EwK4?bo-ka5(T@x!Tkd|h+LN?Wfhv0?ekx^3@%x1c(>afw&; zr=RShEoC~o`BqLFHcTQ$!nK0#@)kz|8skqob)M?buZ?))Yiv9qUUD4rvB(C~*vQ_^xq%7AQ`dqxj*yZi7Va_=klx|=p7#Z*(E z0mLIJSTQ1rKA14xY1F6>+>`^?j0a2WO6uI1qmJiQ(l8s;J~NPq%#`t)i#7Q{)6TtwY3X{tGYe4{?3 zD2bY%iJaPvl&%c=qfH}NBvHkoHfK33jL;#QEGxWx5yKHOhtN+4ZPms!ZB?G@s=$r6 zQ&VX(nG0`m;#5Oqxa+WeZP%54-ZqSCO+&--2ST`h{bvjq_=q0QzlgT*Te9oEerva9 zhFALSO%t%x@8%B93pv~L99Q@By4SI}T}GK2lx$YREY>HkCj!u;Y`IbqN65vmb?bPq zu1gX#lmidesHXpXFVkA?aKsfl*Q1Il1b;wUd5j7(yDCe?D|%UE(rhhK(Ed z1V%1oIRlZJMMoiTYBeQe-*5PTgju|C=|FQyeLqF$%!*n73Y~>F3z-8*n92H)&zA2N0V=#P$j*? z#z|&^z4^eD9Y0IEtKT(|vt11H_RE23qgSUM%%>cC2i?qz$Qt`2ry zW4#1B3y2gaTWs7VOxEI9qI;Wd-#0rHHio>o_n||I=IOy4Mi=zYn|bxF0OJ-~h|pAZ z9GdCvLTT^i(tXa-YzLE8o|Rbzb;F|F4&;@g%F`Wa7q#`iY-E7_V3$qi*$X z`zGC7Z^yHe6(JWod(Sr*RQ@PY)<61jophDJiDtYM%_TlHx zpSKCRpZJ2NV&hx?HKBE*fGb@+#T8^{F!2%Yt?n(+pLa<_Cw0(a%@!-iNO8_uj4~Qjt#z z*X=I0oFMV@iy|Vr2N3vACv-6v62eAQ=~M`zim_J|&s82ZBE^}_XA({x>b;mwnJ z(@;o(+~>T$9@{He&kVexDIz~=FM}?rBf7SA{}3TSywnI@Qq@;<-j8XP)tC7|JHUS^ zA-g9WlT;VE`uaxZ_3M`wXf)p6JJGn}<b7(?v49oHfB;w~2|FLPUo}Lpt zt;4K@7zjEgFp-$a1C#k3$6b5T)7R>oiv;)NBQFpU|LdBzIBO42}9kz%! zpfM$Yq!e6!=n5pR|4PGEcM+X8k)UVlvg|O>5p9uE63}dej^?p(3u*`Ty3HuJWDMfU z_O*8KURN_x@#@b-d}%4ZYUDnF_&FkeCF>5{TxSs>%!@}2#>b{Z4eCk52NZh5s$-n* z*g4)4Y?pL8;9Er=GGDo6BN(8Ev~uLql+A2iieR|Cc(*+R_~sEY9wjL`8Q%OwqNaS( zT#@YC=T5c|v0MzXgsO=^s7%=_G{q^#e&njEyJ(mRR&DnN1r?kzna*(*+CU{D?-fa5 zOF9Siksi;;VFn1?UUn5hlV9RU5oJ}4-pc0UZQ8&vj5)YLq|L;p`53}y)f!)Sd8$Tz zZ!=TVHnM(77X6f+njJhX|C0-_VZ-d!Bs8kKP~oU|Bw2+THNJnJ@wO}3AHY%Bmhp5A z`PDAt9N#xG((rR-pWX~ zP-|xUlJ={jMrD8lLM)>+b{~WYCy;TB`f?rkl|FQPw0X47P`~NnFP=pjxG8952N=kzU zp){cpAxTIRQc-51l87i&DvDAmLq(*_L#9wks7#q6s_*Na z_r315uIpOY68s`PvM18jSX>Xeh#=@hQfXVW=to_lY>8W z(fO+SV@OvdK6FDDY?f^Q4&IO7{JU*Tn+zeN?PiTa-_L(@%^%BI6dn`-wUVVQzZky@gYfKXe2`Pyd+R5+-+8}}47qQQg zrgL;s;4#`>kJuxi3^F0{3i-JWHOU-e&E@4f>?w@-!3t;!{Q0#uYu@Fp$Yh0x1;oPS zVJk0oOpk~>vxF0lxzA&&u4VejQPu!V*Kc-6;wd6%5f%6R|wIguy?EcCTy{v zv#kn9Y}s1J%9tf6)3fJ-r|I3ZI>xjQZEHQm^5pm~?<3RGS5Dg`D!(%`w9CUAOJllD zoLGOn)1T8tmxlGgj^cE&BDk$)(k+WkRft9t^~QmI^5$CGE%Jx9|MTN{m9JT_G48Oi z0*#TZEiEe9sCcqaU)H8DYmfiOA6vV@^#n9EhUGurY8l^(B(U1-?3=KK@73*v+lLAr zrJzbA7c{w01G3KEy2#-;CxRf0L&$nt$&Ge8I9XZxpVirW6j7N*ure*EXQH~c%G1;D z{)oip?x!~a{yViLZ5SV)R~diTwt8P_s*st3|EI>_W4P6-6r)(U;F)m{MahfGM+u<~g-LJ!feC2>FhZq}o z%o*EmB>-)(1n2**9y#eIi2nbgM~A$` zJo_{nJYL8i$KlYcCtGH545i;n${cn#?opZ)eYpd9C90{sqZZR$-VdWfMtzY+6Pdz`B!A$T(al<`?oG5Z>V{g-8wY= z*Xx|YSq@sYsWvy(91ih$WP8Z|%rC=7`;&X0%c}UX=-|_Ht0ynaeD!t15`T?4xg|@k zO&+QBv*Lx)xUW5{x@o?xdcE`D_gfhU_Sf26->2cTz$|ysjOgsWj%F@P7i9ZiKJe{= z!_2(wtWRaDo3E|aK9I9&Snh_%!c4DibFy4qJv72&YYvVMPq@Be(ZuSgkkL7|)Hdlyy*-0?F{8~C}bHfgi**3qPKc406 zT5=@?_+pfTj7$@&z^Zj>}4ue$;fkc)w%mxKxJ$!P4Dx3X1Q(D6T%SsB4Pm&)TX9 z+a5k&`RLJy7xUC}eX0x8pB<_m8vMQ9XUM#9=VhB4ds|$&@KpQz4b96waqdUrRT>9s z{e0PUYi0O1cL%N9*b~zx-0QPx&Q1H>Jr33#ZOF1y8!7)MeyXigJUPeoFDT6WU6Q3T zrX5ft?K#m1@J!xu5}_EF4n|khLMJDu5`FQ#53iJ%HzdTjX{9{lr@H+%?q&F7zv{bj zR5lFi;R@S-HWRG$ciy-fFKnfr3w9&)GwL8T&*EFz*gih_!%(fG7Y2$Z7B4iFzMqnD zH*<31F8T8*OFYVKC7$HPJ7lHwoAYz*w26llgQc5Hd{P%qqsU4aGG~Wu-HX`DMRA>P zHLYItqcptd1MBzh(^n=m`#6>-C+_>{KQY7qa^FQL2);_mjo6pdT9ZR}Pd%$(z>4jB2M;-s zX7h&|50tsg<@CJGo+e>#ZP7OxQTuYEO`g*J{kAU=rnIV#0W5I` zYMtmkBf_^NG??BCS+?xqfPupbpQo&o(0w9rE@qy4@bJku(~XT2kE-7HQ1;RN zl`A}U^lD61vfQ7FamW-4(RJJ?E32+N1?4 z=Z-H?-#+B`%xjUTyiSMP*Lsjp$o20ZVInYSi^s}qdL|=EC*5hGwob$f@DeFUP_jaB!cj)g8B zIm6+oQ7&zra%9Wq&1OTTs;>J2#AeK)ba)4iK{K#Y8`EF*Wp&&`{3lI@Df^ES1Na~??nVBa@A1>0>g>8t8n-;Jc3qo`@i!Zf&ZtlDOz>X%tFUTVbx3LZ zuYD$|I~$GMkP&hJ!qR7@M1xyjx-EJ0OuIbpp?_0V)~AHM+Vd@6rs##t>C#uDg8Z;o zV~J+F4F(SW`Oyx0pT?f3AM#;(ZrR*~kbps+uQpA;5OhJid#+Edw%59)j?LaZYzh+` z4lFEtQMF?3HTT!O_l$YgsM`B?EX~gT^Ra!Ue%0?x!r8iDD+t9*ds}Nj`Gy zZKKJBkE{FIJ=PbCqu2T#UG@3J4x7*Cx?Q9I zGJm``Zi(DCnNlb_`ZBk}vgXz?Mr`!^$CNi}X#9iAh4q3Y^wdTnul|6?~gfz?9 z`ZSf9Hn<*-NHzaf5k*VyRl7A?o8>-d?!6?J^7x?d(8I6RH;gRHTXC(|G?_1V)7AQk z1!~;zjrKeDx}8~i|Ci@)<(RKH{tk!b`&TliZ_V~@6t9_l|4P|qQK0e8^3*ujpC1km zU!ox`l6dhUc!>F_iKAksPw;tvV8xLl272k(_X>C)c0^B4F79W^{p=_+$tI zWu}lke!NQXt{lUR&Eu)5sYMnLz2e=v<-Qg}C<*{_ccXq!%ciS>%<{C0`DH`ll=V-F z@xRry!h4PT-RIgj-5s00IWI{ze9_I{a>f3~o&UJI2fBVV`ZZ5fLOd|GU1$9S(~py` zB}udkSy~x&Q&3baz>4hPGxBik#0bVoe$IcMxA6Cvh2|ZPyN8<0?ITqHTJn&FT^h@7 zGxHP)A#E9x1*0f+uNq6tzL{YF%>yVRCJ$Ob=MA!Ve6VOfN9YnKY3e;r{Y>^vhP)ud zsJ(M!6aCSY2VKTZup&c9JLd#66g`e%8k>THkCoIg0Qt?WIJ2Q>l$mq5 z2DK+DZpeA77h6;(q)8}@AAg33hU^vz406fi1y@D=m!;*x;r#RI19LXK8&E58!g`5{ z+FUGz=v>kjqd8PwAM;7d9ppTSLWc&U)}4--4^PU}Va=_Z4MCA*s{oo9)ge~#;X?qD zC6lL>xTPI!gE2h-!r;M!t>;OE|F24{P|IG3>SP+FD>cEO&#>lw-t2{%d6>SzkYoy^zx0H==IdyjDXQdKsm1|xvl*D#RNA34WKn; zM&n%V*9ULx+W-rP!om)hxH3m+g5UR#CgSr@Pw$bqNDty_p%2z-U>o0afU^B2`Ed_= zQ48W=NKW|TLz-aFf`WGqRSU2m>hf({w+fc+($dH7xFEcGU0Ioq#u{M~&?PB1DhGU9 z#Q9U~mRD&W|0;I9dKf!N=!#9f)?6QP8-ovdeXIbfi{7t#r=?lj&EIig?bRxemDNic zK7IZycMzjFb z?fBK_LEXoXq!R$}RX%(MAaGn6nO#CbA^-)881vV&(`6#{`w7v;1SFd0LB@Is?Yu&x zk4GhSvGIiX?v3ZH!qvKV>!A#Wl?%2ZlhS!`S7Ij;XxyVn4b)k3zjX!$sr!kL7YTZQuD%00oo z1Bmg;yD%7L%)*PFKK^9bOBW9X!S1I1TwhV~BD>7xd4a87Y1DQant}`#(HOdWx^byS zQf~(SYv1i04-qIbJ5fB+*5!Ejc2fWPUtXO+Y<vgE5&gH1FDT~p+f)p zZ!x_Di1FXA|M4T~$E*3o&Z_%7V@h0?jQh`DX$6qs1xJ0aXm@>M*i+8sVxK4$7w?7l4-fp)y~4w zFhFQ#A{|vurl#AQuDWLAK22#oy#>RJCGk}nAr8pzO>g$Tlg=nDHK?^BR(bcOGx*S)- z9HCR7RdTr~Z@yrLgK&e`4|ojW?e^gKWAG)<5;_;7t_%smKv$w9|;KAeYyilIsE^toDnKQny)$ovrztFk}JwvEL zzlP_*c`$f!NH7zY#;F@2&81X>OOG`hx*F9W@co*b!%BScPk89_clt=uc!l#cSc+Hg z-f&F3H~n)#Aw}ZjCrs$lM^zDD&K9x<>C-BQWe!7V7pEm)>co9{w355cL{>kl_P5~8LRK=)f$?bGxm?0_E0d6 zLa4UY?mZa*HZ0*q*S(~F^AtxbSt3D3hN6kOq?`1(z$cff=g#K6J{lCY<6rM7(gW?! zV*WTl|BWd#ttNdh4}#ocAM59iZYeu*6e8)~OSVkH1j6!YI*r`WU8JGf4R4MV7j%kw zAP86P$^YwfJN1gltC84e8sE5ocb8tWvZX@m@a_r0aTQ8EIHa7`bN=sbAgN0R&J#it zFBld;^52fQiv8+-Iugm5TD0)+57*NJsTvz7ysd0qHh?u%)~y>b3e<;1fDw?*do!5giPtk#TgSsmLbZ+ zV|*Qpm5v{C9Qt=N8;>j9sC9BJJ~;Fs3hvD^H<08!I9`{U+5e9gV73JoLcu^Jz#@$F z)1oG0W+zgeU_rW+9QHxL(Q-1D|> zb!FJ>oD(}XZ)Su6j1P1*F1s^tK_p*uPNT;IBPqNgs%hI((f;&*3neApj5%7&eh<1? zrSF2W?mr8h@8KO|c7!*ch;Ngq`uigM&kfuEQP;GT&!0Y}WoFX5hK0q~mPv`I8AxIY zP4~Q{xt~a>|8H!yN!0uQDu|Az!&|XLx?&`Ia2QdYkNoctJ_Iq$p!!+c0X7lUBLd%nXB|%Kt$r-3^n5sRq`HkB=7!C?vzIak?J#~$$ zGx35T?Z)L0+ZHL^;dm~Y9D*1Zus*aV^uG(Td3PQM?e0kAxxP!!`rvR{4RvSDkoFrc z9v{&jM4gQ$i$|(~&lavoOcpc=A$7%~h3k=9jS6sUOBa?%RIj-5-E59liT?hzXX5oZ zV#kiK!}L5+n-tz%hw4<~B4U|hZBpl5-u@H+M_nb1#R#VN&~q+H>(QY5_bui1K{StU zq8+)xYB?hIqis;Tam}whMe8e*4ouY-@}qEKNiX6*^own^*x}hyT-2?tq(wFHLi-TP zSW1MEB=Cad8^U92Zt@84H@D^4s;Cs|zkZG8lE1I5pup^)^L(Sb-lx%PlADhk=Z#$_ zRe;k+>T-4_TaFWvJG1 zD178P>dRDunF8yEhN_(~XR>|hSof#1R0LmblOX=WsLN-sZ|t-3ZyDCSfMLz3EB<2V zu7o6YYLjy7SGtC&>qL^LXw$YP%3R`bzcukNn~bCs!VKeM23cJRHG5 zQiR83 z+|c-8$?`T*CjaD9frh<|okqoyJqw1x0^0uVZJ%Df9$-0~sHLj<35^%Q1o0g5n^a4^ zsbZ&KMKP8XgwLg=G`xO4s5wF4iV0rqUy=r#9_a#4SNN6cs6~5U1#_HGRW;yLz9-lm8VV+&^U)8H| z{mI`t47K+Jz5!dk+MIDDW9&O-;db5FSx7%vj17sd+XSs$fP{T31AF_?;hr11*_@bD zLR%nc8XF1ekxfy^n@)pnQo$(izPjUI*~`bxF~UGN{4nG6*l}bxp}{*3I%OroF7k+WhzJ zeQB+9OI{X~ymCr7IPqVvm>q)C3yqAgZ|q+*f4+sqX!5Xy&dw-LpOIX=u+i!y%%5&4 z44DujRnqHsL2tHZExJi=hC&kRq=^wienY8br5S%=Q|}4<@)}j}WkzGquVq7_2tQsu z^!n;TsXr3R8vd3+6%uir=lWB-M%0}q#md)>06|0zSRP!w0!R^+UhZ4R%e^5+5(GXm~)# zRSJU*60h1n#Wql?ndWs^ptvcRd4v}ciU(>j-h@JrxT3pRa5}9ixyGnN6p6sKV>kbb zJ+II599t>W2!Flu)*^$nPPF7~5Kq|W7DJ@~R%RF(&4Q`AAB%gBAi+R)h7-pr5>7$H z3rftlWHj`TLhU9&`OJT_s9A-)jHDENKyZ2IPC`e_IF!@w3Rr;Pmx5g!T23IoX~`u3 zIVMlmjpjB(b~j9eroQyJRCboJL&ESPZdaZ$wm3|u%$oet z>SGHZr7M;hq#uGz&>o8}lepC%V>#l_(Gr4bux5hhduAo*2+riB8Y^yH0}P}^7PHP9 zYlqQC=@K_nX>G0sgfo#023(L;BDCI1BXm&Vp9@rH#Bc0d7+B%{tfsvDBt@7zmejRF5?UJ&)2lvP4PT40v#!K$4;F*yuAgZAUe{g9u8ixBqPFIVEJ$U) z@c9G{Wlq6(C6WD0t1mN!?WMS`WOU9l?dw$&OElydQVY9F(XRJ?%rU!TvBK zAZ60ZALQR$army(!i(adV#jzf22`m2Jt^Mo=L8HXY;C7%@A6r(;!a7vvXYXdU^Tr8 z#WVat$d)Zg(v9d4#8>3YnocWoPe}70Y?qxM)Q@gFE?v5QJIRxpVH~nS;%;tS-LUhK z^MGIgWYLbO6qzc#do(Ll5~gQJJ4`+YWf-lC5RfbcwfiF@6Uxd4SbDGHhRwT_=e_GM zRIZ`@z;WX;1w!^o2Epbt!~<%&D*yFI1>f%X}$BoO+_~xz17jux9F58cv9AaKyb}7kJqm% z!iE_Z(!G1zRJ`slN)jwW=o8bc32=;N`(u*)J@hxsq4P{J;%XZ4@#IO4P=pL4Tjnob z%rxw8U~tpXsv&w0dqP4P{>oF#&Iv`VVEf^wJZ6jT`xV zGGkqK9XRj{10`JNL9c9l961db5Y-YI*rda%efl(nmet?u#1`EgT7uz!ypN34?>E$dBFxpgvMTFKy; zbu!0p?(OUYVj=h>3T93?{m~*#&)k)Mgvt{%PB%7Q+bN-AKk%pRv<{z+G1OR_@bpK4 z7#LMYTL#*HC%`=d{oSS49&r{Cr(L;or%o7z_w>vuW=q7y3GJd7Em0@mraz8qi#KdW zpeGOpn2{0FQS>1eJTP|gOx#rnNM(d;x^XpsPr|}w^_Bn3hcIk_`Osk3^YbeNQy1d( z3b~bSGMS=80n4={Ou^t8^Dl8t)I9`rFK=%gxtXZqwS4)mC$whd(rKBOmxpy8^Ve#@ z``d@wyw4U;mhIFd4=D!m3jB#GsiA@1&a2L8jEt8r;H|;E-6#;Ns?=al*<5tyLn#ZT zWvtm3C{Nz(t{6`dh-9?tk>~wZ4M1TKC@S=#}OyQEF~pYr1q*=Kh;3$=m6KAr|0NY zdnFG&^I)xw{%NaWb6h2l_l)yu6}vgA?RVMrk`j`)MKU^@+s@N{-fiWFRrlNmtarQh zL2v(o>z}S42=DmHbYZWF0Zj+4RrM#+!YgxlFIj2n^2)wl6LNA^6H$ml^G->BkeL9` z%q@EV!2=Qz0T)gaGDu#x<&W9-6Mgqpd_8FM<$1pXbz=tvW5oJA<)ChC`TlwiRTBs% zmwUmy6-$?%ICMyE)1}E``=X*=Y=_lCqGY*IMr8S%UBIij;PGB{?TAUiKygG&+`83-cieOd%onVuoNHxwB(oYAi`cLG zma#CqT-hTqJB2Pl`%h_B=$NCl$!5{+{SNMx?QE;bqnws1KAn(bfwAzKA!P^Xv23$ zE?cg2EC`sU=kHu1UVNCF!#)FnD>w6hKP!qGi6Hqy8F+bHBxSf z#nM*}KBTa~*LQsM^jyCmsvC3{ySlD#yeSfeeYBgo{kuXnB|8;0H4CAS5#7DT+I~Ot zR(U&*#;tJu=B0K^>(-wCP_un&)NiArmanDruzPbUDbZPt-w20Dqx12$?Ozhq^XSOJ zveeDhHR;Ha%8H70JMoworYtoyG?3KctD@|n*IE9HFu{g#c$Y87WoCNw6uFX$uVMM? z3;e-M6-+Ro957~A4ZaP~X>*)RYHn;|qF`A76_+*e6UoBL@qJm6!QprWKuiB3_$ci( zv#|IKSqmn`E#Js7Lfk(RDob+;o|&kGe&n5`KM-{T4ItjLY@YQk}h~JT55SuaxnGuO0Y2*!kt1 z68XUXGwi$)lJ!I}``3@|^<}`Qy?@s;&)S-{uDwU|8ZSv*;M4D7I}0y$BZJ@-cb6un z9>W$+i`Iykr8tEk&%pz>2sa^RUi)GNxz5X}T;IIH3^^=x2R_g0ICI-QiP~^ub18Yj z2(Np0-HC*oX)|U-njDFXYqvzdjp+Hdw@F*E`!?IXca}sQR}3eHT>J5v6$AZ?o; zbH@c_QY@C>O>BniN=zQe+>Q6!W?9|2bZOx5;oE0fnTL{Nfpn52VHLy-KgrGtDYjWE z+S&m~Dg~60^Yz^Ie1YpWiZt3C-5ggNX9zdmHec>c^#ApU2C^qlp3sSeizn9A?|02xJT?li%^%J9C1spG zjSNFgO${3#va20(+D-Jb>d$-eUGRI{x>ZB5y>UUi+uy$Q^KDrEuHQ_lmUHn&qWRhW zM9$%oO5c&LuC8LSg;r|z{jM6maJny-k#&CjGQ+h>423(5@{5qrrcDqWHgmhYj82&d z(+0l9;MmXn;6*lFGffSw_@d==fwlA}93v^^B@BeeFN@{{?6M|Q~0 zZ}n!V@Ajo-nv#wsT2=PjkG$IwQ1~r+MH|NutxtWw9S5LjGk-G2nu>ma@ym!nTtYei9(dsbS`|2r~8k2Njopk%Sb)Evl8$YT#b@vb5@r6 z7JUtPEI7Vd!wE4DI_&8yE4zlPpN`F`{e=n#!!%m?U4!~S2mL<0s zx|pQg8re$0*)cbI|hxX3p*R^Ujk9E8A@cm_xX!R*~ zU)!XFvNh}94fxsi*CL+|FFdk&H@=QTVXsnex|{5+)LNd_pTB&pkQToJcMSGO@VT*SB+xC|Gy&XL#9 z!Ufq_(o~gJw21uPZ7fd-Sldw4`7k zzD{QpO9iUoM>h5So6wv@86?;))YQ}vStn73Q?|`q1tsma4wbrl-pun-l9G3B-{x0k z(V|NOPw=iVJJLN2)63`(Apq2c0?-Ma$eNmKppK|bpsxI|zd`c1Zrx-LkF?m>xutF9 zkCNuh?bg}}G;bglYIGEyQzCiCXzA_X4;6(%>o7-Jab;0RTY0ITJufdzH&*Pv>5?$T zDsx%c^n`ouT2EfS{3ErEgs#WPK+;g!hb2e8mh0J*?rQuozxy?D*>IzwPQ&R8(rEKN z;p_M8S+ZmL9$U@dM`$oMZTwSAWa;o*g!;1@Du14nC~#6pzEfYV)%WRWwy~+_p%POI z>ey|S9i%!{kuZ=uJ-C10bjA!rF*)~u{!xDa4HeAwjg9+&7VcKEU>eW7ab_tH7$}iEF-z8=JNsrlNvWAdIShgUuL-8_)faaPCUkwNdivCdbY&FTI3a*I4;U%gt` zYa1ofu%%1i5wIBB2(3d&tq?3NzA-s@nC?*IaGIJ7l^76QQ(N1mOBaMToEEM)N!^Vb zH%^%{r9g3%!ED$&0`-a_@>hgi9z)jIgYM8bHCc>c$(#&I3Pz!EGGdF}Fo zS1(^uSIWJvf#c!4PzvLX(z9>h>#skP@KCP5d}TE=#xif_DTYaqR%|V-ln-`YvV>n2 z@tRdYRe0v5%2qBvPA-hJn7l@`|JNETdwcufUE$$9BCjo7;}n))`e`BpkyOqE-;ydm zhXeyL*p^Bjf+c6P8JRpWChP%PYl!sdlrxJ2k>Zl z+&Kmk;`s6FckYA^%`YjTVIW zJ7&zKdt11A`t|EKp>J2+V{A;*!OW819T^E8O4=8^%WUXyW+5Z91#ridVns)a4+;Q~ z+mhi0rqKio>QH!uBBL{QxR6#sAAP(>sf5DlcJ&tuS-=;gc&RP=!+Uj3b>AStA~*Au z+P2Oo401Y!$(^*I(&ljW##t`b$3Y%#_LwfGLWYyVCYYc$e&E3Qh%LcNEe_I3keZli zoK!=q762TM8jPFMH)43O89~p?Y}ZqlD(ie_)oG@tN4=BLm&wS;R8>_ut4<&pW=D+F zz2dA&9s@PB^<}7R$A+@UKFgQui19O$9ox2Uwf}~9fER71yBakmUy$FEL61l zq`{Aab8gjP9Gp~eAcOp`AeFm7%x6RWUN2gGJmq3-jR~wBufgRZwTCM4w$a6 zWM}zcm$7p|#TfFcJ9PBuQ%Om}r0}Ote}PjarKTE+)&2Md<|ZFJzV8l>QGER1n~&f+ zkqD(Y=JuDrfA=l|1V#d{lL*^y^L}!6tErdq1(KdWzmj0W9gui_WYsG$&{RI7s;a7l zZtHad-U0}O6JQVB&C?S)w_VS4$6zy{w^ggM@rW;NGca@QZjGJXW_k8Gz)l*`JFXQL z_KaSe9comvWbWMjd8hOh%u)R!5MtIO5&WftsHCKXd_YV-)JUpdzmTb;#*E<_X}wM) zFR<&#th^eY+$r){Vsn2=%NGAwmv7?q*Jc+5`eAmsy6M*{^6j_LVdDg=5%8_2kw~*X zb8nqFGd{7T>l2$Og|KN{Zvb)yXMgc<%IYeDpjJHFw+~uD5sDBQUx$PQA7n_h^$gq+ z(r?hB3W*MlzkWeIGstn#k|jU6q+TqQDBXLRcn@H3@1BKncbO1jB-XB7yAY#rgdKAI zqfO%YHozR&XU@1Vg!b4mm}}6PeS7zAM;t=8Ji0LT3VCl}U`h4Zd z6AiKp1B1AC>ncKIP>$5qfw=dh1w7wryNp^VIbn_}G7_c`Uqv`sUBMmJ~X zt#9zIS;ODg=rqB&2-QEgjGTid6c&l({-`LwwQCujx2_ulm}_fl-ox;gyygDXjXeo; zV&414A?-5!I{~f5Vu99#NeG@A_EV=Or=@+m6!hVmkz#k(5C4(gdS|UT^0_?ul;Oc6 zNt)!=YX+Z7a&|t=lZ62XbRwuUkdF!dfDFikY&daZgsuy8 zvD>))g_V6|WC)b#>ddUH;Cuoa;TE_>1TvFkK>#RLe=W|-8-QOtsbF){hvxewB?+ec z1lxLwIJ?jb7n*=_nHYeHE>I=51Iv~y8J4}K^QKF4(;q{)`jHaG$G^fTkEtFGFS_os zd<5kxCN9ndY-VRZqUUTutzZMk$6daMREwymv}Ib_Y09S4XFF1vcrRZ*N>%mZp-hjn zJKlVo-l%`2Qt#I4)O81ww-pw7m;98x@@QxLrmnC2CZTVQQ^(acHC27=SaC72M`wLT zjvmaH_yyTZ&^^;B*bJ{fw|)9X>{EbzrK>hxxq7wsT**wvnw$S9q~Q#|>OS z0v1SM0r8~K0*N3PQ#vk1RE&lPDrBpBrIn4%7>HY{o_?Cv?&q$?w%42GZ=S+M1X$klAbalt~ z?V7^i?ODeA>{M(3Ge~NAt^g>}4+_bOZxi8gWkP=f5$Fd9I7zdOxO{=rDAItl8l8f3 zEEHS9YmE9j+^$%^t~v^#n^Q?rv0Za}dd7TsujItU8wVzg!Jh{=Uf)(H$mq!UNtCF= zMq`ENP!PH4Z=agnG`uM=#fumiUF^! zgF}BAnTA8nzXVrLP#xirI6EswUPCPOn60{{V5`FJq4MRzLL51-6c!S61Y1+!BJzIVb1``kb!sK*&YBw6U!RZjER-XZr8?2} zN?EQPYqodq-m8^$61wP1mbtlIzjdpdm{{HhfZhGy%_BE%yux`oW?2Ic?QqUFzsdvE z@pCX$ei}>L(!9KK;3vOH%|g#jw#Oh{IySfDJ0U~Iz^`cIw78kzI3KTUV?RZlsE6NU zLz2?7J9BVQcsf?!O@DE5c*YYUBT>-JwtqM`fySw(6NOz~eLtj(&cM*iD+AQl$!S1c zSW;3AD$tbJSSH2as#t!;?mY>@%RPw+37aGYBS)$&W5qDk>wJ67^Qo;wI#+l{Zo6kC z=ANB>gRZ`h`KkX~nzFhFGf-K)H^W&_a&m<4*Q%I~NWN#P*gdxSS@W^vWKzKIYh$|QBlPU(=jGuasYi% zki#;)dkYc^w#A$|TNee&2h(I~q7cf>%<)>ubH|Np=+21~Cg3Z1|Mu;V3}qNOVuY6O z#{oOgqVIf;ptRSDVx0?YO5+w~PV zB-ORG;Fi0LK5~gOf>D^)4B5zAaHmG00%4b}ST9JR2$rPXyuG2=S{jmhym)S1NxivW zy<2KFHpflh>*gEG6>Ga54&^hYGJhOwU$7ybH}3^tzQ)mz;(@yvb5aL~NB0Du1iEbp zhCO=ogwqtsAyx=Rl`~X|3*P2qKJR9cc%Pyfi57VvCHIR;LC}Cln~6y=_uO1(=P%qh zzkc~CMB0&0`R>SoTVQoLJV+*>8rTgJ`rhPcwpfjbaG833>GpSR_J701F^GjGE@1I+L0C;MT33mnsGXn@*dyVhTC+ zubAV<#pTDsi2kxv>~7o?Y;S8Tt4(*Ld739@&ui+`&gSu3wir`Y8jj8RDi&A1ddou6 z3?ECuE~(+T;Ibh|v;7-2!ix}zOq}GhXi+_y5$efqTz+!Ab94lx z8!-#~29&wvnDm~r(NVD00|yR-5a0q@%PHezyJHJYDO^@2%z9cn+nx;*FKo#8cSTZa zt(KjQKU&L|pXzxj|A0vxLW{515^FHzYW=)-1%Vn>aMrGeg+n4l^oy(m>wL;h?3*H!ci^cULnF-s<^v}4s zf=W&}C_$vJfHn%*-n+RyUOqrA@z7P~@!d%$JD%{4e)^pg`)u_ar%A{&+6UeFro4N% zu|g;z2aQwzDz(-kolQsXxWFru9?>Y-c~W;onsRahKff&n`?z`R6tpxLJzDaD%-oqg zK8l8CeXO$Ri$}Fk3(h7MyMBFZCeFvi#BiVb7*&LI2>^bi853AU%Il(`nWN*fxpU1? zkHB1X@6LmdOG;Wz)DVSbno#Mpm|6YX;`XZqZLVc8sa& zQ^aV+L8JwnZLb?UimjrlDLdrB!-t3HI-NC38hC?-9vW4Qjm;e{?A!MkmGv1rl@%Os zFM2;nP~6?zX!jxS+>RrJp_<{UVA66vBeZLQg^y1?t0^B$5=7>^WjBse>?F3Go*0#V z$F}QtY{gkqr))Py>qI85dZ8Bv8;OFoBl*BuV&bppnUDu0;xmUA70ke*Ci2js8FAz} z_L_-T5a=^>Qsuy}qiuuo88S6q_YF~ANY#1Hny&4o8+l{IV6ST;5zp%d(u5g&?)Y*B8-+WbQd3hX4>GQ|AUi zLt)})CGbyV2KbkQaggYr&IzyN&DykXjX&lX#`l7Bz6gSq;2uP*j4L$mk#jJ#*Hn;0 zMHUxVg^R0q&3z@I36{aPGO?ui+_Kc1L`uBM*Y95i*u*jtG7<9bF%tf@OP3H5Q%ftW z#V#(M&mV^Jfg3iHd#%WR%Gv`478Vqg8w}O#SY5V0C`dCEISDBHeHu|m0LkD zb{B77$wxRju7Cd> z60R;TVx2p$^zq3`PydOO4xUj$mkmwH%B2uOGbc(^usm*YRR&}bzbSQbj?RdW7ZOG! zypM%;9EL92O>&6qFTXo9bhP`^@g%vLnrG2A7#XOjr@Dn~oo8|12AJEH?n@Fd06@;u zRD;J0y79ZbNEEr`(JsnSu5e{3PTk`=K4ePz$&-7TKA4fACb=j%w%B{~QrQkN)tjt+2pdlE+3orSh%mRA6jlPqqZx@X#NsoUxeLFP#y`hRu5oC0YSKO_1Ic-GOYkbNu(h>)yw+Aimv=e&nbR8Bztg0P#Npn7`F%yV zdoVopd5+gqP|3ndG$QCUYpbgzQ&pwK0|ElLL6LPMR0nFO9paqKp2O!*=J296D_=gI zi~76l5LDZM6m-;Qo<40Ft)Vt(&;rJ8ko}SyQ67MNbG?9hH-q;u&ErLRxkRsC8zrJf z&DDiXB`o?*JO~*JihUqDn(Z6B1e81BjtdMl=el65k}v>c!RO)==I(ADKev*tMnp_I zIB^1QC#0`ZZ%Wd-v&Myc=xXsc0kJjhhN9Y3MVywOxZy zbo_J!FUbv8g{RlEo!k8RdI|RuEnQcwn&AGH`El$_dT)J*6_9{kaQulruN=j38QGA-CO!xahLNT-q0O-;CGpdfir0>&MC zvA^(aS?!e6)WZGZe}T~Qp3pJ;Iu+YYad{Bn1(;J+EN3ydd_>QK9Fu;2gyg2@RQpUe zcX%w*^YY;2?Cc2`YK|ZOUBC=LG0a2Vyt6wH(@4Nq8~_ERyi4*sTp=be6XFdQ1KKM9 zDOa@axgJaFr(m1-R96_lWMV=kwR{~hNKC$c&^nvPL&oJ7w8Ne4s<6{_RNkGcJd59) zRMM^Dw>1(v>g~ewSfN1o*mLLn&<3Cq0&f=@BQrAIy_FH5>@~Mp(g6cv(vyW{{_7?8 z0vLk*e}-|H>~)%X=s}>V+wdHQbr{~Vc)zuTAV?wGw=>EFQlV$n0w^Qk!pCIX^sjL~ zmpwfrDJ|_wr*2WwwQJXuq{uwF=o$@`>Ln$Gu{Wi}saeA(-ecI=&b@0CCBz=NW#U)r z+;OZ7JMkTQVj>Q=76_f91IVU(h%mA+WSYw0@Wj+q#&HCx?>^^Sryu~B*A~JIyeV#rI;@USkaNlD$s+LAL4-qDTsG`Ba=z;bm;=1hZDJ7v|Udzj2NFle{W z^vZtmQPSJ7acku>$KQX_`>}~%T2>=QUEas5<)3uK=X$OM5pys5JXJy_PgP#w3^3THOQ!H>6*B< zu)di?+%>E6F?wvD`()2JWiSuU)lc}W>8_YEKbz#|^j1-BrHiYfgF>M9OM`a}VrDPU zITMRWP3TWpddq+bgNk<Zj1&dkJ~%AQ$UalX{0dXxKDOWBH%acp z>!H~fr2e4YFPD!8NAlH(+_0hDw#(hO==0ooW_8GS$BY>`Z+`k?XVq1Zj9e(7iIz3F z*28uQ&(ULk<>wz%;0mEe?#qM`spQ|lsbcck+z5B8J=f`&+1YKEpzTF@kpN!(AK2pa(DzExviP|5z8ZWTngVMw=@I8@4rthch5DAx^X942`-f2)9wWRfwew19=6R1h)rvzxrW_IMY{@YqYPuXCcN6Lo_8{hAV5J#u z-j7umkDWux0g}V-p1*WybW~IlbC+kIalS;pzPZQbBX>5Rn&W=VL_^;_&Z9FOgwv)@ zT}e~X-Mcc#g~|e&r+uL#eG4_wq{^`9!4Xa8Q>X!X-M-Q2^WpPBwYdV%D*xq7Qhaio zA4Yw*HymMrp-8l`?B~`iizar@{7`Z;sP>)aS+mN<^2_s9*mP)}m%GbI@&0okg$qe* ziqA?LmiB1g@lLa{{RNpdFDE3`?2c2@=vZ{MjhDgo<`Y?CQWu??bsYNO!*eax$nM?KsuI!~oZT*Mr$FoaK{UMhwOqLzRPbw9m%yBlag|iKgA>P*c!;8YqG!KHsXIW^RZ9w z{ugnM%ywGak)_U0CxCsBlk2C!B2aA$#HlbW!^Nfi^N+NiRD2sYZNi?n=FOY!{k3vH z)WJOUduVj*FSq)^nl4}L>?cmoOm;As?oJQ|rC%f~|H&h88MVDv_(spCB50sn`h}($G-Z(_VRGS5#E&?5}nA!2@Ad zgV|7KL~MTg%5ch*No&55>eIKl{nl%qhR686iQOh=hcq_#Ru+Ht$un<_T+Zn(tM5H} zzV_n}KN#p>Gqw|b-*opgk@Hc>WUuq2=nN|dLP&mS^F+S}FmMxpn7io6i zuEJ!c)eT>iw&dk;?rBFpkP$Pk8vH zh3Nv{p|FmF7SZtY=bF{4Q5){Mu@Jv}8n28V=$al1JF#KP5x~p0JU6#-rErZTqvnfI z5%^6yG(7=8oU+xVJzK#}^?BhYBX59lLFId9IUOYElvD8$cQ@c?ynTEYsqTaQL-=rJ z*YxOC?L{tG>~Ea1evhQDU@P{Bqo(d?&M^yBSgju4-#xF-A+v{+phe^8IlR$H<^-z^h4- zNO`e7n6&DX;&ss_YRR)_*Ek;gt+e{m`eZ)=>As!JWMYAZb{qHe(l*M~QpV+ysnRAu z+43>JyxfUTjQ%zw3OT;rP$_FGE2W0eT2_>si=1wUL<1%jF#iqUNhrOVUTZhc&hf0? zBs9&$B*10@eTNOpKq>;y_M%^Y!MxE9&VvRHtfYr!V*hUPmbSLre8O2<`EMrS$~~3^ z&4YcyT8XTkiXODWBtEowm~A!mFSm!0A{mi^*othsP8$@mI;Lg7$5a2jDEyrfx-X`z z=W0ZFa>f}SlcMsfar>qmsp#gS&_{PO+N0OkHEq(!N;>u5pZo_Ai>DbTL@E_Ta&uOBFa7 zT>BRLHv7_;EUAb*r%|LMkX(aSs;R4|&l*l)NAnnLFN@en?FkN5U{Ew}0(v_3IHaGL zJg`}tHf^}E3~tPWEy}wsjrWh)HA_z@uyK-%gLfl zYEePx6y_yIA9;WNWb+zf5I7Y+LfC<;=+BlYo3hSK!JTqG?EP5pH@Urew*V4w_fBf>8lEFqLV0OIpj&A@< zri)iU;ogF&cpx{QSy8F@dZi59PmdAkd_waRw;BR-8v)(`Qv(j zXz;GXTQ{qPwX(a*Bl!guyeX#*jaX4v1BV~jdI5U*sP7H z%(UD`h)a8hb(zxP)IZt?Fri)V^b#-j5x>H)9BQL$*TQXE)6&uSut$rcgyyD|D^_#_ z!(ytvs%mjj5k{+#rLQ@=dq>%DuLDXgTZY$2m&dOFYX4hjviH95Ad5A@eExdbcg_qF z5LXS+7X9wc-41pUb^=wbAI%x`9g^B{)fMbi!u>C+rX>pmcLp3yV;^GWetz3BPATZc$YwKPzG7R(WBM2r?_^js-F_RE0 zq2c>xnFo8&)>gjIpANe)ZP$rx6tH#HUK>FkJD<8@T)h?vzr(O0LpGhM-!5_Zj!VHk z5=Ei~c-dW-(+IN36x7w!$O|ep%ldXT)YA*v`_N#3^;|gM|4fLRo7e8PB;*4bH$yK1 z@QTS#I+W`2TL1B!H=a2<191JCB1Q;+VEx(9P&`6dkbEbxwylG26DWdpV3E%bC{ zTa|XIYIS=EFZuN6!%{n=2c&HIcSsKa@ER8_@veyo^@<+vXFmFg!+ai@P{l15A zw4q4h;k0c%8N(RLzNdp_Wn`#Mx9T4z71^+HBhw*5i=4A>L>>>lJP$k@xw*+&vEq%& zvhsgz9Zz9Owcw(_Wt7~eRm`HG-w|LDKZc?m&?<*G2G+g&&?|Z1WY&K-APCZY%_@ zaLn;6x^w3gW??ESOqPll4*Kb_ii&L$m87A%W*U8Q+)5t9s71z%8g&w?W%T@w)KG8Rb<|ORxM!XD59yK&u8}^` zXxK|f3)jdh(b7IyRo}L|)gzn0Va}6k0=@|;7doz7<M1iXxET5ziI3kXvD(h+UdcK?#jaBt%^h7wibR(_tTm_{)4yYB zz3c1zuMZY2@PE1b?AC9O>fQwG*M7l3-4(ySQ^SzZP=3dgjuEs`E2@nhix!Q^*n>KE zWUlPC%PjUNb++M1t~Eok5d8Hn26u!z3TSM|h>fiPA4X3np$mLD>-=i9ZI^Y$gqG<6 z0|rd|f5g3cT#ak{_n$elLWn{#mkgDeWFaMrCZP-=4TgxQ6pBI;l0s6VQ9{vdDw0$* zmkddiO16|C{oYsh-uJ$T-}8F@d)Djw+TVTKYOQr$=XIXP@tKYpgNEK@YE+wc9Y2=F z^&Yx|jgiAftM>WOUgC(wWM?_JrMy9x{s*lWzUmx{cAzvIp+qu{+&vy+DNCKIs44V> zIDVYz8i5=6WVj36HXNg;zkh!nY>4Rf+UO=)bg3?`G}YEKx~fT;9J%UPCvwnlJhf}W zvDlHnWJ)YmJ*@lw?s?+5NQs?Jcy+2ee5Pf^mJ4zI(;t8bl8@10Y-m7>N6(qnNgelG z9Va`oM8EFgpml4^zi)kUr6;mc6P3t+DnLFaR;?cI6W*@uM|QBa*t!Hsswi+HES>Tv zSD1DPV0AjR{DRRg$jSM3Cy<_S5+y&& z*y2rfwl*a_W=ZckxAUM8+%rMm!!_GWLpvKb z4sfuyj7&57ZH9@$7w~|t(9*KR!fUs04NngEY*B^SR$U%IuyJG`ENVJ50%6p|g-3@U znIW5X=gw+`UDzN5;c1wF?wtsR^ahG}-4+nn4tZM_*Xt0@pn)#Oty~2APq4n8p2N*q zKb!UxiD!4;qSf%AG5KxM$Uhl)F}r>mN1LX3{$&d@JB%&t{9wwqnhzf~(e-cIw42|$ zPwmd@t-aLI`%MXQckjFxsU?^%pnX}{He^6l38G*C&!&Bc4|lncW!PuMe~_0dD|fpr z-I^qtRIfLFAw$Ae@!uJzvcR+JTSX#Y@}!If%X5y zSD$VR3Kmeph+Za4n3q411%ZK4+SRe}ht#|)&)I@-L1G=-uweu_QO`e+1>+Pob^ZyJ z*kRMv-R`cw9TzvjchS!;AiLkbeWOvS-G5|oZBqRExm^tPyo?l3XWqUqq0Yy+;Cj^q zZbvQaGX*4;6Tlh3E$q8ypx}IHAVMSTlQ7F9;(Z|pVkK6|hYu@x%BfX(;%G*FGV*eB zsVl54EQnh~ML$9PQAS2J=s8+Y66@9?(L?=dl?P}uar}5SaddR&W;^*emAhnAkXwW6 z-B4d29jANh+BgYK@BH149n=~Z)Km%kl(R{o;_M0_vKg{l=)jPq;=xyS7YRBhO1Dql zA|d!^%n7@GT~aARg)9yi9gfwq$(IzlM0)b5!G=H;_vqB`>Fce0#+Ns?bs6p1%gM`S zxSFg63_{79sX#Nl^&|lWtrMA7a`eKKlhF=yq zr&x3v960dnYnYsP(BV6WI2qR7D57EDD-h|E4%&+4lCTU(Y(e8~r~Ei;IromWf{T#s33j@GFcr98!4vvI(PtTK^2w8j%2nms1iCO5T zMF@}(g zvkFHVtBBIgPP9|VALtR+=jE)lpFBS4h zP`BB{aTMzni9;ppZ4&#keEh?~e4?h1|EKJ7OUs+9KtDUCH3R=M;3YJ)vy$&`YC^4U z#MO92GertH&SgIry08??I{L zuvvo*o}ID#y49T%!!`0Wf^wz|dMeCT2O5%eKjrT~?pFHs^8zFA>XnX>QPcA!vx(Vr zVf(gwtNQ%m!%mI!ktnjyU~vvK?%$2!I#X$5sBE}hv}nO?(;TNG``LJ<#V*wtH6afzjxX<~zU8Pr5}5`(DEyz*RqqjLb{U+Sg+JlRzS~&Tf!$}_{nrCB1)@Y9QCIb zV7A%)<-IP{4Oow0q++RYEaR71tf4VpS$WX(oeGQ7%ImSCAC})cQyBLND0OR?U_s)w zr`HLuhp%fciVqFSatJe8xHKwuee@c!`0NEMB6>K_I&yb)X~Hf}YPZxk9K@VV^ggsv zrKJ(U!M2pH)6S2RbpPb9$#iYuI0u%0mvzBY3%jqtU3xO7Jug2WsTvSG2NVeoaxUFa z2^>B8>4{>|sYt2eeHA_C3(C?S1M8Bww+Na@J!1#e9&xg72Ze>#=l^C869=9$QsA7j zib2JJWv7B#<>N=DamP_MAcon9b>qRH(V+%>+^GM8ZHCL7J%8R~a6v&q`T1+|?SxoK z-m`w!HVzE(B?t9*SXAUIp7rRFImHnx5$gWI*pm{*HBRXdZ=b~R^U317=ur7$riPA5 zZmD_q4v;MmOPYZJ77`7!2k!1|`^FefG^SPrGYHs1)_?`iFsKZZ)K;6Bxy;T?LD~VY zFZ4Lvb2PXS0NEB6ClW%n5DBp)DJbxaPG(>pjK`I2#M0=FI)xZy?n1$UK*8CRHMWPCA6Yl$$*V zO&Q{=^_w8AfB(PfSYmd|Yip17-ah3VRUOWTxX~*VHLsUJf6uzGg_vJmT}<%!5m-_p zxg0QddeTo@WGXsFjB4U9;V*=-f78TCPsr)T#P-YuB{~+($D22j)Y>vK)@Ej>c$2z1 zrCWWiR0n45n=6janUzseQX^2>ot4DMkb# z6FxM3$9tW`S(?~l7Aq_d2>e5CfHiGn;4Es=>HK)g+poiZ2-X zE(+_*?`6mRr;kbSpDLcXa^P>Ar{mFH*RNe$9c?7%6@p5F;*rb_R3;)T2(?8c__g?H zugAp=$a*ZdXUT3>gS@S^Ms0^8suDdtmtLBS7Da@GeXg$$y?PZX+X8WSkzi;&XLMaH zuEzVYL0R7}Y#)=e^YSo!k5f|enK6Y18dzS~Z*p^iY(yf_?Sup&7LrDcN>xE>EDg2p zK6%Mahy(GZQM9FQC;sy$84R5MlmXBLfD)XTZw+e7%TXm4mzEyAm2_HDhuGHAQY+Nw zlhxz8w+Yy?-}?@?=Ko$>(WOfl9QuUn=2~bXdyqQf?s399==ld|{Kvh=j@D6-iZYHF zgDIE%1DU>(-*>H}FN8+#Tj4#>X<*Qa?%iH0U@iLxT^zl9(ILwpn>qw24I8j~h|2^0 zmh;El4O{8$OE;%=eo{~{dF@`=GyXe-#Z zNLEQEMG5qT3q0@}&E)!$v3;#eqE>LH*fU~qHO;h?OF z5)9D;@DIKd_IVg?+xaYQ3`dYzzfBX!>r*Ri&?Su> zc+G4dx0x+}sW(pzM50vRz9jt#HVlfVrJYr`ltm=ApXfViz<_Uv>(h0n4mxJGjvyXy zO^?HeE!O>{lQ^OK?fZA$BU_MSkd~3S`Ng!N%dZE2ALgR2uFm4%bAKX(WTNj3QrGFV zWr-rkrn0#Puy)3bpJ*Sc+vvU!OfEP!$jjasRkM8FA{sNwHH}!I4Oh)=acVxU5ppG| zKrJgTwfxeeq^8>n>8ETS8i~aZ#C!Dp_=GFrY2p4M2_7|dUj5R(*1BX>lEyK_1ziXb zWYnqzRW|smJ;F8~@H|*{apYdv*JteWcj*icjCyh8!FXl7Y8>)lnbh? zXD2V&Y;~f;n6Mp)AUPd>5jXyJgt-ReU5(6p;Y(QOaqo^Ilf3=jI>0>0q3C#|lh zq@=WRtZNt#jJX%UKiYYpRZXjO@L$@&2a|VQzoNf+68*A5(b7xz9i5Zg{Z@ku*Xz9)_yZ^t*+%Fg)T;N}wd4D9{@WQWqgy6>f0hYHS7XE+aeB9Z zH*0TFF6JSAdvN6PfD@YagGR@7E?&C7RL4Cn&}mD-v$Uq+L3_YETkHP6s?knM+74?w zO!@zhos=K3Z(-hE(7b<_`+ZVXwpkJO{-}n(L8wlNP3Jb*8)NJvU0Vs_RrAWr{$_-K zU96{wdq2hQynJ?d0cj%JrS5O zbtLN0;8b|4b$j}hDMMUf;Dq zGh4T9D9k}!-`NuSIHe}I0?u43vciKOdPkhm9Ay14;50RLIPnw=o_O>Kd;Y_hFHJYs zSgG1`2u#_+!g6#ZjwY$}^q6VGPAGbJ*Z+D6lSlfvj$c~}6aKh;`B;O~t0n5~+jnsr zvZ7C)@Z0U^HfwZ|IW)^F+e=RhBfpL|0xi zsXlEW#20Q&=E>pB!lsqZ`U#0oic_ zbVjkEoK{#qk>TL5hTAT&-AHG-Rc+Gm*^sI<#JoqBw!~zk8RK#}esDQmKZ<)}1@^Ic{QNBAwn7ZLc(Ad!v)J@%3%hL-(nTZTwYl zk(K|YxuaT%b6l-hz)THh>2~emyKl0K<@gUJ)4m{ zeNWM85}SZoR(LvAORi|Pn22W&wHX=|(Isg!?i6jkKL)tQGjVhEmM#t48===zeWrA$ z5E+w&EFq5rjh^p%Tv}g5p`Y@rA&SFi>wwjww{>-O6&3nEFK%4FKF&0G<-=qIz`(^f zp~3b%=qx7Iosm+LpngFfrcRlH*_$kw8IIp~AZ0{C4@C48YA6t~=sq{PjzirBJOfYY zIjc#{QR(|jmEPgQUA9&5x3K-hQ&NFsHGKJkKp1K9WFLK%u;~`v6w;qu`%4Sp?S>v6 z)`x-im!j2I8E5wot6E(xkz%1ou>>Cco(dKU=$peY;ta!QDK`vdM~F0v4g?cq8}8f1 zRag^P(m)D?0G<35TRv1(v07s3wrEIWKd*HEli-JiKTNQ8A5HRJ69sSR2jM z$8@J(<>W#mK^neq_{fp79hw-ywU&}@<$C-M6yYGdOmjOqc8dalBw(0I#bRJ{wA|l^ zEAj&i=FL-)e;xX@u*&e{2h6gt1{boTq%N^=l+ClXQlH4kc|6pNY2KsULnonS?-4z2 zdg8W3@&#n%G@oW}sa5mS7`(l=#gg(4Vh58NE#qh17`vv~-_h16CAHwH>b8{3)NJea z&3|-VoHw{)dkKXvXAp-G-3!VDKnAlzZf^9~DC15aKfaX&0lDuLKBg|}ufbiHoSy~( z4G+SExW{8iuV)`=K@!9;JW9Fg_Fp4N%)ttPhaZHDY>U;XHAR%wU8NLI2o@$g+RvYV z5UUB2dKNN~INBb)1Zf<|g5dK!caBJyCPoS95*Xw5`SWL7ld!St!NOpc@g@6bRTfMf zB>urSlBkgr>U5X+cGkQ*=S6J_92N-8ys`R~6XnpT{QtzVh_?W~a%Wp>3Z@2pKtzxphO6=q9diR&ER9se*aVY8Y-jdAf zxJ-C*KHxA3G+mUBLNU{P^Gn|~1&8t*Oe|0ORkwZi!1&$x>WOpDRL!0c<~=@dLm?Yl z6<%QIofUf<2^wayjbU?0x9r>M%5_Jw zva&C~UNW~NTe?Ly`pk-gT{_)!%4$=U`!&>ExG>wPj9M932<7_8v1GOjBL}%~1hxw; z8=08sbYTurSR#``wc!A+O|NfC%u}!vlfwFq^)@4^(ObgM|1{W&C*5 zQgGx=nD~J7jp7TzLET5qp6vu90X4_~Vx&sss=1Nb2c@(d!x$fcLX!2*#;vpNCnZww zq7hwt_N?5KYh=yl4hUrGQ17ZYhG7bCz!Bni)>OTIJ=7Pd*CAsz~k|v`Of@0bMPm zljol)<5UR9aYXkG{4+?^%1B2in{Q*f3H~xy-FIO4-V_hVBaQbG+kBlX&V%svc<_Fl z(!F2#CWLQj4BO~TF{n0h>(`IVUDfYyNT>wmLC(=j*TErCBsZ0Hf`o$0obsb~x?C4= zah`(|G)w#;7`YG&AzB-ao6(X^0_B$=YC)Vawv?K;x@Gl^r$Dng!1ZB>3F5YXdP8qd39USc1NY<;0{+ z7}N<2>!|ItV4aopkI2vw!+ME>8;u<^W^-BMLea+uHC#agcqz;{5+GUf_M4S6EtGfG zUbygey`6$Q{wZNL4rZ_6Qb$0V?kDv(DyVuGX8c2XV1b>PSd~V0seqNU-1Mx*%9 z^IkFCOjprLfdhhp@*K?E_C^HkIp3X+XmRgF=Ch_@t0NASju48zOqsT71Fvk8zE)gm z9Fp;50!5%mk3|)?eWTpttcRCAi-~E6jk_@eW4&6nEzJvCMflV7Q;0}X&2t*|U2}}e7pognE&(s_dboj@S-vw#vkt6F$c-+BIg!y_47xE~DEn5UgRLVI{ z1Bvm13zW_-!*TY|+v!Wr0`l=Es;UY^N8ZUhMn5!zuLlOM<*z!-GQ9|(rT4zN`eAA+ z0N|-i1%|9M@e53O86np?Izj}v9Pm^1v*08AnRY#iL|clkyH;PlY{3J*oH>X9%4D33 zXRevS)Cm)|A$*AW7`%5YaoB;fXVavvnk0oqUml~{yHH3w!4!&6oK1_W=`|GT6(@rY zdfiXBdwR~^RXb>f0ny>?Ms5E*og^Fsyh^cA=g2f{p>l z7yt;EBTn>i+Hm8-7yaZWPM8oHtF{Kc`0bjbN4v>MW3;vpK{Aj(i$xtL49xQN@u?)D zf`PGLJ1-3q9v#H1%tA37;|*$ETBmEV$>qmQ0&!Ou7|a(TXoiJGSr}3J?AeJUiKkyH zixlr09{PZn#IL`W=AG_}Y=c*#PZu-56#x%UC3(#i06IvA4_{a$CZ^nd{pN_OP8|xqch4{Z z5^^6!IC^2>nHRMSwYAY+0=^_}uk6w9%F1y|w6$f%uT}%v1U4{Q)7qWK9yoBH_sJ_q z;*B$l*y{>S|U zjq^bcc9SEQupN*_h;o*z!>pI&o~dZ4n#8Rv3pZ36_Y2XaP2~C6PP1rHk%O0({-o-v zOKQZPJ8PF)uBU#?fq>|G-ofKx?|@_11|jlRE7$ooH)cFBbJjv=DJN>!lFsd0X7@dt znd(hgNB&Mu9<$xLA~SRICgKu;FJDHENHsox!Gi7f_1_%wY8e+mC-Ae(zK#+Hk_9nN zZIQ9GZb7hCKd$(@_9Ns%^&W5N6XH0fyKcs(qVWrd#~eFb<~;Mk7gk=BbXMt$9LF|! z%3HdtC7C+}@9uQ9a>dcS>w|tgHq95y)NHmf_7s(@xqpxtsb3TkJoGnWV$P3W({?PW zRg7S`bmT||199u#y~`JWjmtbqZ^e-7wP;8I*DUs^4jJ-_!`MP?C96iqiE=xRz61o@ zU1OXN1fCE@yy3aZaCv!V&r@AX=yDDd*o#dkCZ>UqMDi5eLn0zRvL-|i@&}o9A2ED5 zABEm^TgI#~$s?)U=Z{k9C}P05jebNVULK-fVi?Jtdlc)czJ|FE>K8-8!iojF@Z1k$`>LK05*uvOt5ms=--TN3qO;lDPEqXZZp zF`yIEj7uetTlH&LryuF);bA#rB6BkZ;Ds`TL<3gU68{;3P7^-ZA}pV6mkcaG?8j!; z`TdkK#HSyeY0H8AH5%CIf}5U`I3pgA8Zwxq@IFB^=@mAV%d(!#Vz7Plp!3xYiXI`) z^Yi^Du76DK5OqCg#NJP@=8XG1tw-hhyonBSP+d&&ES0M+{nAnN;PT{G7Elf-bQ%0{ z&JAp*!e;lndE#Q(PdnpzGCx+=^sYzy;@dsi-aUEhj7Rv(O|@!be)}g*KK&y~HbJ1# zB>2ncB5hgi8v9v z*^8-lZif$lry4~vN?8MEdY`y7)hq)JeYSNle3}LhhQ$|Vy|_5H6ITeDh+_t=e?mfn zpgg{G`ci7-Y&+D6wJobRErc|uxm>SeYF`rrB_ca>&nfR4X2U#8&a{8``gIO<`R~^F z)3=|v$$RA>ouZX01+iyOrEJPiPHQ5VF}&fbNev7qJ0F&itLQ8Fi|%goHdEWt8ZvQ& zel>pZ@3Qu?Ul?f`QT=mX($LqdolaA&!Z)S0VH2 zDH|{uET`LJe8k$+!!(7xb12!Fj4=9SI*dJ2gA8lNJrzzdMt1E}`$UO`Kw~RF2G0~{ zAR&BfQ{>6;b5iuU{TH0&>4wc8M2@q5u?U_IXOu8g!{5J*92_CXD>zs`W2;cANl>ad zG;RI56r<_{RFpFZ_B<$*a0?u~}4A{^xNUa$?i6qGMK0F7E%;!pgfcL|^g6 zz1lHJ@n?3ws~zt7G;zb^IOBdTHMd?Q`d{1@U45YH$l;B(CSMDb;^S4u*>{h+7oO~V zvzMaNnX2%Eucf<2?*E=TC}d5+xr23G6$kIKuAF%1_6ZsWlmUPc1Z@gZoPbN&xzSePU4Da%-rSqF>?dSa1SdQBvz-D5-(Kj~#^k)} z&JO1LZUr0vNE#`>FQzTCgv>7-Z=e4;Z+K@b#-Jcnu(}sua#2FxMMs^ zeqZRV^rgLz2Z(uSt&=?SJ>#}YnZ5a{;&h44-|jmUSw^J!t_zTO9koK{_2QKIOlB=^ zZcID+*gLUUW#p()k4Pw0>HGwJR#DMz6hVmC8K!4^YqQLWI{~TpE*y-#SmCtSfDOy8 zuSwO9jf~!dsb-;k>)WYAcK+XumArZFY93`?0mI*H9)7*M$JA+JQR1~`?Q+|W))dn@ z`Sp)Yk#UlJEb4C64qkmqbG^)@J%Cq2(*q?6t-?dfo|zvl3|uuQGrW1%_CuVNF0Bx? zxf^s;NWZVlT*}IdN++nudH(&&zrqZjt-Px?{ccj)r(*mv&Z-B`u4#1Y;;kv`Ndr_y z6qX!ob!|^q_1EF}Ca3#1F(;Cw6ym!rbY3`SP2jH4ibbXPy^+N3rrjOkBsrFQ|5p#|Wi@y3v z{bF`%Y6a*Kv1Y`{z2>ltmZMhSmD|46Ptc&}P-7un60uLF+EZOmq$L;To(bE%x>XB& zk#T{9S1mvbpC< zgGxuz`avA6o2TFSO~%r9q~u9aTQ$o|-yhyAbLuTj1N7EhKXJf?EbKO%$&Kt6?xWZO zMvZ!pP6_T`O;|{ei_IVx=6U)Q0gi{lC>vUFS_-4a!#(P;&n4dlS1G;YdbU{LC za^-7UwZw`YJHAj_=diIyC4Uc-=$)+}gtBB0OdqjTRsGiVwtQ9J-dxkpgXV*m+5z*G zgNnG0a$W!=LB??xE|}t?SU<6d49{^ZZ)eN5QSa(HNXa=q+;PBn1E_+RcqHS1%FWFl zmlhtp6i1xHKMpI&({1L9U}Y15tax~VX?hPFctm-*`6}tAWPa#AtUAr6(NeFf*fGom z3=Zx)a9~E|AE|2@=`vU50_|v;>-cZ#T`MvAuT@l;&A6pt4v2LgOfA(t;>z_Z}w9@vbvFnJg zmmS}XYukOvBg=229TjKaGY-j$)ey1GmfhaA4&w@;Ky1u(wC+C@ zOXVfGC#LlAbmGIR>(^KA%AK-AeuR5_=lmXnjkz@eQgqIMNA!1`Jfx+6dmrQpQuL~( zM$spOBT1W`1N8j7HBHVmWo3aYq7R-StHeBHrB6%9^-&F78RcigiFNw8Kv;icvDbT{z<>LhDl05 z8Z)$AVEPVy}Wcumy<3q3W-jzNWxmNOyx5tiO2ac{}?!1=FG2Z{?t~vP3v~W z1-_%T`qu5R;APiljL-Yn-UI2K8(Q7NGa;y>M$9)?QBFQ5rlzmGJa)o_36!|ch)yCf z#m=q?Cf`j1%@BPIh!LmfAQg*KNlA{Jra%vX?yT^#J=KahYow0om!SAVOXCEGb31fB z+K3Ed?8=hDgM(F2*)Y9XfGctkC?T2JJwsqF=)I^=-5zCSWfc{DL%;a@2!S!Y>No}1 zofn?2Fju7#aWS=$=V==ptoE5SE$J&1zyz7Uqc(uqbT3pHB4oHn^{zkb^W| zOC6A*qXt5)4^U>{VW1#|2-s-m3EBke$Z!#XPc{+M_f&tm0GKM2o*BK|1#{k9gbpqR#s_Z)}j<6WN0^{u404?V_H8o^ubBE+~32H{UA>Sw3Rb=&YXQwQA!d3#776uHd&Ve6i+nCG@e9|{`}Bo zBMp4rZh!CMx?gL~I?L_7bb)cGjYGWN?Rp?D#BqT#9sJ+mM6&ut4NXm(ty_o4Lk)RkmA*n#AfWoFpV6&NaAUe1P4a+DXt!#DtLH zy_dcV6Kuq)gs9B!yIe60k@#&^O*wHzwu4D;rXR$bx*Mx8r?+vr*UySY~L7D{pRDxMM4inb7~ehC#>X>szkpM zG~T0>1Qq#E2^kPVB_)>0A3)qzT{gO^*QbxXu+=_Pm13GHfb(MI)+}FM#5UzV3eRX( zC8@sP_%Swd=YqYq0jTz*RkZNx<)t%fk*4O-QGM74InRVa*xugyG3JEw7Vc!|)~!fc zeFujbw+wk`C^C2o?#G|Zs1SW&>t(6+J4oYi2EvKqQP{GolJus}QTnLY{OPo}H=l9k zMV;IaecNS^|Lb88>t1#KSL(l)VgDO5sE``cPABh<&tNtCtw8elmMO9MK8&U7l|yNR z-j--Z&xagPL?pHk9{`OpV8HHHVgo4{yG5qTz2s^^JV_~&jN3r2sxH*SpR!Mj}%57nfDg+9UDx3H7FLt-cAuTNgSY=KUopkd3&dH#G|s4f5| z_!G4d7?8n>%Pp(&bZr$M5s=7kI(6E#>w}H3D|2wXt*qo&vWCdg3_ek!6*K35pcbN= zY^H$b>`_fWehi*!d7g&bqx<)RsE;Tlc~~I?;mC%>oQg3%aYrxc zu%~CGKXdac_vG|fe2AnOpZeXqYw)mAc=Q!-Z`;}Z_es)vTU2Zxd#E>mB1BjSy0G0j z!P&4f<#`-xJ>@Nfl<;~VayzlTB%`kFk27a=?4^~&#(zvQecs@^s&jSY$ME~#6_XD} zeQaYqcJ3{S+&yKf3dQ+NQw_=wFSeHKF#G=Bxd1C>hUxnU88p05{xQ|IdF^HwM=03= z()|)<-Mrdpd^Y#^5w&vF&zdnm#q*LrNmqaTC-16V!Bn~cuJy^=}iuM z0e>*=I`ZQ_*6oeOS3Xg(c$c-I=G_kE0=pFjm6guUVzgP`SLv=>yH=R2a^l3Z_qv^3 z@9}_;$`(KPFkwi1WR{_YL+sG|F7pq~?ruHT^5@xmYd5cYIY*^EjIl?4Q}d*oovc50 z$!@zvD<-WmxhiSo-6Lb@YlT7Tm2Fdt47=jT}z?2tW z5eEHbWuIDuh|Pu(vBt`N-E3msV}wI*V+GF2`o=ezYT0jGpxmyeu@dy2`yQ6Z-0x{i z8Gc=+G(M;jux);g*2M zt`GjwI|p8X?~G6wpW9p!O1vYXp&vNhNiApC>Fh0KiByn(d~=W^X68S1JL?s5l`ocq zwoSGwJbwB#!gj3qs-SWN$k3=z9ubM=Tq7$j9l!eS{^CPHvP@(U=ISC^)cfc`N;lSG=jSSBAJSYCeO!TbX~oDVjHoW-5Z*IbP&rv`u7(TzS{;w|5dL1B8myi z&qiWm#({qCGLvw*QY5GiIWvCEJVM20}byP0$BlN#Be(f0ZK^@loZ zFYz5%QaTiP#Se$(yB=*`IfY~`-uPbi&5??_Ewi@j1Ozv{|B}AJy^C>=zxtZiZzHBG z<57KuJMC+YArN3SWL93#f}WeFBdBJU2o%;#7MhuNQ46u-(VzQ`u>D;UCHuG236fsJ zj6jKP9%K6)_8T!f{E&~#2!5&BS>~pBOK$&Z{H6x<+HY`5+@FtGop2vg3?@EYj|&KROwn0N#fqzwG(o zH?Hx4g)IDN0Bs#(L4*V^Sb3tW!$bWT+C{H}v*a^fFgpV$-Sx+RgG@pdcc0VCCZVvT zgh9t1ZkLvRKm=_B#HvFjMB|JmOK%Lks}+1kxTlsjZMl`4z`62x)xK&b6%;;t1a+io`;yc*_H5(g-Jy>?0$F`L^-3S-m2a(bD>01GDPKN{ zJFTKp8)zKa`4|)ZQYY=&*pj#IB~KVw1rGT#XjLY2&rwu?!UO^+;y}|4nooM{^zq}5 zdy@nP^!p6d4-RnG_U+|Wg!H_Fx8$hn$@nYm#bXCCK$6>m2iyv~0#lIQruV*@OxX+W zMW!|qFaCb@gwrel47@#=OOB@vHGWw53b?YG(zxe1opAIchKNy~$brTw#R0mBZkVe? z3UG*H>&;SYx#Xm>t55cf_DWZOBW+^Y8p5!4?6&Ns8o^6Z!m)2K-K6EeH?fH8$BqdR z@f^Bme0`^q1Y~djgK`KAUsL`B&of^fd;3;J#{Tl^)S*LO@PefFwWkexAzDEzZU0?-J(U|S65Y_u;3+qz@5F{&CPDj6P0=7(A=h6ritDZ zk-}jl4CuHfj7Kq7h}!h~0XSZ@(lpN|Wqfy|>Ayj2;aQbK0t>puw0abi5Zv~a=XZey z2_Z_YJ@;$@D1e<)zj!?F0vTi_D3uZp9a_LPwXWfjKeJK~9y``Uf_XmjBS%ht%18{q zm8cyMD0x0SsTs_w&&IjUuSfb}Vr2B5ynH12QvLc-@+nN1ki+_bauIl`=}4x8X@6F~ z&VWe)sZrK4ssd^j)Q_7^Xl^rp&>BA|whlZ<#lM3-^FsRCB$&@Qix8BLAQA#h=)qxVl&h*+Nr3>F z&OLe%BP9e-r)`A$5~ixdSdTc?rFdvVXv*<6`Ll+$nlFXTOJv)Z2V%KaCi@Bd6`Jd> z*&I-jU4ir_FsrWNJ2hwt*O4`IRc}n!E?tPQF;$KA+hcY+cOOp_S2oG2Tue++1lqYY z6anRJ(jp~@DBjINqFKf?=7)xk`$N_74u27Z0Eh@}Z#m&O>!zayIDWj>RWF$G8{Gj$ z*fH>rQq|QW)Mf8Ou27{|2z3va{To_?Up0!gT239STsv#cJr{z>6;{RTsaWk(3qUcV zt9y5ZGm}9^2I4dkQn6uT6#RL%!fQ#vU1e-6-M8<0hRs6R7*e<*9c}Di*!zz8wOM7gb#~MC^%CiD37i1bJ=M+k+BxrB|IeE2wFhUnvJ`a2*CP`8D6FcWN^U%8cV~6Q z0v*@CATje%9&x5t<9g@yiDpt3>5169)~}x@qAFr_x&0PPnOHaClcd*gfon@=Tx^F`^<-1+PL4Z_WdCJE5J7WY>Fk2`yjqh7mqjkcTJd~%uH zfp8jAC(hi2-zqsCVvx4X-V<)Ni@D;I_eEiYxMj&FPY0e7UUtK&8e6M^L56`y(AGab zMd|~yAQfiLZ00&qs0<6_7jtIO%`>q^P^=86e`iwAuAMvI)!WgPu%YQ#m;POW$j;TC z*;ef40RD@^tQ1=Ok88k9VC9usurBjiw{F|ECQCE;8OkI269Ho!G=8+_GL=ew8*pv z58iV85j&BW7lSg0BC4#cOz6~gKoY}#aP=QoeCDy~EismXe>&EYrt3ls0OUgN6$>z(x{!D905plmEEz$rd3lT2^Ssu+trhVK=_h$XChuiCb^^S=2_ zyJofilvtu92pt;@`A|rKQ6zR6i;*6~^?HspQtDL5=)7}BO-}lM)E{zH&w?`$Zh_I) z)z&8O_&{y2D=!VaNMJx4sz>(eLcOCU;_*c@)QpQA@Q{&p)7f^6_waB{;^8`X?%eG| z>K8u=L7<)Q!O`+zs2v!adF%T1rQ>`UlzyAL3uGl9$TkaR-`h+5q7k#JEJZOfR0fn+ zs}O3e>&m`^TAMo$Fh)%@^Q^aKdF|3r0aoEVR^4ULqysua&g$WUTt^slfayQ1CZu+( zr2FkOBH-B;3?eh*^$cduvhB98oSiHL2vSke!;OQPnBptiXVFws`9or55=@Cxon3R= z6x+`88+3Aa$WG;e2@crC2_wS^Lq*KTTe5iZF9vw!+P8P^2*~%xlNUwvw?7n0E04L3 zeINNzuD?X@NQ5N&voMR1CUR`|ZpD#rEDbF$WFOHF`D%L7wNs{e#+={v*qv~M#X^-4 za+>3Q5Wrdz$~j&eW9|U}T(gZ*KHOTJypn|zoVzZ@Zx4=<5w|k)k!P8E+;(m0&-&mh zbf-wXb0+|83^I)0-6(yppeCmTda8Jlf#QYW6npIKm~1r0TQlFyqPSPV^)xB62k{e^ zS5|JMwZ3x2P_bFVb{9@VjIShqG)CSk6XrAO9oT581Q_GzM$!=3jAm(BHE=M5qmE;@o1o(xs>AU#{mD@(j{8CoizNVnCRX_5|WYP1G z^2RK{EH)rA1lIHv%E>S9>uKa~?Dk>foI;sQQIK3^ez7^^Lze*mE(XiaOW8JpK2%9ewb)|5HBXP@U|~NC6WDvD~379=ItX1IfTao@8>sN&Ri+C zpF{4Hx&3eMjC>mJ`_$A#P&#E)vP^*t4c)}tLC6~Y5`v2G`ah#MxMf{3Uxe3+_HP!{EPD;^x_H}g z>@z6K;X>!hWd*kyoJDf2@ zRL{ELM639T=tgbVXV4&GnFunUMqu{49=(fwEV_!;>OR^jK1q(-iV-Y=4%;*u;CC52$fAS0NW`Hz!L31S4&V5v;}~&X`D?kjc8cSBeRM0WYkaB zx{a4(cp1Fzzsw2+P24D9=q=zp78Aj0piX2A%nS}7L@y}0Ub_l{m)~A09mT)C7&Qtf ziSMGXp!@ubAdkSThEpODKvwYny}s8Wq60XOqrrId*~S%%R{#D+*+!@0q8kd2WI6>* z+tNnuMfAW64fZv2hJCLa7`J9*psw`pVB@_mRa-q=4cheE?jdcHx#{Zfn}0t`B1mtH z%Da6XI(FneyxoM*Go%Jv3a{;RyFEHNepg-X>(^dq&S;2GlLLgICLJmV8r7#u+T0;2fw*VH;$YCk{zwP z=JBjmyrbNH^4R{8_lo=e7e3{iOovoTTvm?~p{JU~_^~fvcF+mv=)9_~))Jw)U?(pq z{7iGfnT1lZxoG2s=mGZ-%DB0OQ$ybFqm1P}R*<`(pp#qMEPz=yd0(!_TecEH#uHD^ zd!c{;#xLB`+=H&8Z1q%)zm|-%LBwC+M3t)w;0w`eI1Q_kwX|y-h|jWWM9wiyRiD5I zAc$#c=`p5SDL@YX}rFWfsl z>2OJRQj{`eiQ-y8OlR7Bz6$3c$2&1#QAhY;5X&Q z>^1@O=1TVe{RNc!)D6y*K>=W&%h%_r{QOPnS704WlB>!NR+TWy`*HlnwiLoLXfSKHZARmOqQRV)6m-7+{w@OgzdT`_G!$Z8Fu4g z3#iShKJbl;zMwTiIREkElk$4*INRY}i;f*S%ma48=yp*@BlsD~NZUO~qLnNDzu}1f z6FsY*WGf0%{(U?vb!|!P)cQr8J7O1k?6h_FYOp61CNoQ@FOgbJEjgWTMn{PG0T2yz z$BcPa5-1Nkb?U^(9gq&8A!}IRf$Crd*be9&g$Xx7AiwjQKs!(pJO>j65hb!lj?cnO` zq6vz)oOU_){ws5b;UTvoq(5mTzZZMujlQKn@(oI%+E!_=#s92!4Yt#egEV4$j7BcO zdBXD(rjmz0NH9q&e~+HZ41S$<2*c6!TeoOD z1EvZk#PPhi>V(uslb<*$?%d$ zM}SQr*L@oDZ=P*mu7@_?!1}_n$kLLM1Wq&JW3scia_g+F@veHF7cA!t=|!}!fu0_k zp6?rXU;h{S!5dfousFJ#NKUY);^KJ5Z&ny?I=Zs_uAYon+A<8R6_u636n4M_?%U!s z5vy_4{w*D&j?(XAT38o<(^uMuvMM>$If(#WftMw6 zSYNbfr~UlkHq=G*mfbpc*3EoK4AC~BQ=HXtW-&n_7SXPe&CGuVSlTCO6LNm z1HCh%7~DqI)6mEW?7_0Gk61w8g&G?D*=Qx)Q{RAfUi(?hunPbv_5`lRjgM`(PjpPG zFZ$flQdhr+iNUC2A;%$vW#29xv^pG5HzV|dfvwt0mdxJ!bBbjwOEV$}`ZPa5L%ulP zc5I2PiiLm-llM&3;XvIP+jW7waOa5mObC(+x?!iNef`JN6SHrMQ{7$(W4=Ov^Y1qpw+ST_>dEHXwP(@RjVMuq_BRy z=nHs_BT9FKB(xX-0e1=teDqh}x}BeAV3J3mu}a-SW$68XZJ@%x6)+lF!KPvGJ{cl`-`A!a#*JRiTKph^o|YAxIX zEF);}<8036DX?V?5nCvlqo-=r&=igyF^(7kKpk6KMI|Nt_18cQ**?>vEsy$gKIE`Y zSh2Add4k)8A~$@&)#y3;fHKXwaFA1`PK{QNTj_t|1St`Bgl^C(%(y?zeZNk*~P{C)2PM7wj?+`FuG`QsuR>q3#e|k)UJbik;h(;K+h^~>1xVkiMk_7QA z5bZZs>y;SlN1BdfU%v!a&idMPG({Q#qvx#e=7=mrh_xFiXMxWHFLOhtqTkJ`O!@Zi zEFl13_-*$&Pd^$akt{qOmw8%&4$;ZMp8YH6Lq#=M_TYCd^#-1f3gOXkj_>X_Lu zKm%G3vHboRR<+Xd>ksntg)M_4V8OuwV#>Y#;=lvyi~fzsy!{zSaTcZ`Hy|!|92(a^ z_t?|fsJzq7`1B|Pr+}4Z>_isvA7!Ghee?VeY<9zSRuy__HNWnHL>B#@P^Cc5a2p$9 zhUiyTv!4z?i^FV6TE6*5`w#WfFnZ1Zf~v&!@t(xNUgG~At-(E19l(~#xykHx_7}Y) z%g9{;P9<#NJ@c(wnqRgs4!~eYucM4$A90e{V#WXkDJwtw63a5(qV*Q` zo;foK^rN>IYm9;mP*a;D>l?*OEVUTf6KFDlVn}4nl$oC=ZrcAS=hlZ0Q>pPNyP->c zvMPm4FO}5GvIncQ)SLghf5Kyun@S^2593G`MJb0m=!QBsQ%DwMmci_nZ%febQ!2Ux zmi?qmWha{G%RD@s)GIFP^vc0Hggtn))DdA)s-K^bNTFJ3Cl=7~qt2qA#%SwwBh?8{ zCB#C)njdGcEa=|qWYR8G0_6Xfyr^M-`>K(qw~b8B-jyn_^sXEQveRyN=Na2~g>8A_ zacxUx6iF68Pd1A`d;0WPR%J9Z}qHlpZKek{N#z6&Ft)yR|%3&sUjCkB^4?=FW zj%$}^lj`=UwW>Mk#yNXWlTFgJa5Q9Y1biNp4oSJf5UDtfJHpF+QCPTI*yV$Xa2J0a zfmT0|!DdZYR%oRty_DEqq* z;@5V6hBb-*Q{B}Emy8YQ%AaDaPr@8L`eoR{uwQy`E?DBfza7PoL~6)f=`co75lwj& zs~Ljqad|zZ=l7rAwtJ|cz~x8W-m|{>3l>j|+62gyPu?Ybg}+}l;zDDq5d@mj`1!L% zt?*m@ST6#LVPo^A-ma*qh$ApYkGpdNqXr{GIZxSwXw>7jw|FMmdst<)h#ippYvcU=HOhKP9SQ#4J+ocL)2D*`Cn>3!CJvne`yP;(`9^oq+Kn5pfWHB? zU|Xc~PW7mIeP5a-lk8jK#nVj`IYmQ78d5Nrnp3q|HQ_sW@bRDk#EIe4%D|n8r_XYHd;t} zCBr&$zSUYl*)ZH!u}Vpk!31J&XJ=lklBAsvuDn9Bn*dxkEwvX6=E&8F8&0Do>0+GwBB2{1{|O) zQASmJ>eSXL=dgJM(=?47`P_$uOo29B8%_C2DNHc)sFUf_6gv$dgaPj(Y~!j`3_ZYV z^`7xo-Mx-rBr*ao%u6Pog7NGWp09ZdfG;2+4C@HOS9^)!ZR0U8!ZYQZllUEDo^nN8 zj?-v9e-7Z44QhD+M1j@yN6f)4Vsks~{L^B@m+dc!d4|g|z4ilh=)U@-{0v@aZ`ge3 z^3_^NF|{aK-EN)_Z}2r^Vo-}JNQEaS`}dMWb4P1E&PRyu1~mj$f;gd%Ab=e6Ijjq3 z@icWTdyuGf6J$2=7Tg8Cv2Q(YfF_4oo)7VF0o|Dxt^wA8?Li1l7sy`3)J6|-8r9+QAJVzuO9&`7SM?;hxNZIl}W+4snd=U>GDW6 zH#pE|yaej8#E;^wpEkSQ-yOik&1|q77&X;w0(*pDWSk0A&H|(pzhkuaY-0woq3u=| z2bwj-h#-iP)gRHNP~3MOO1A(a0JJ2M5Jf zO#0*Lbb-xcG}F8OTui7+-?s+^=TKQ}7G(;iE_O#vXl^ zn+q&Vv#=U}6;~!Zjb#MnLIu@QyDOyx5yV0B>DG11@-go4o-comvppBxJcfBDOc*bI z`PRhlY@5|vb(`mJzW}@ln7}y5m1DfIt7BjC)|@x#=9yB3cX#k6^;)W@Cx0@X?T(RT z+FhSJXKn~jUCqI@;l?Ka0Yfjv$CFL_bG_jLrO@#3peu_~$F^QkyU4#c^{B%|=>bvg z+KBZ(ET{#ma_0VPVrO1alcRT_diGlfkH}AcLtdgSjvzJ;v;zaWVGbB2 zOgE_ATdG%{7p!+9T;9HW_lueq)v-ly0`C$1g)>+Q2;}Aj0uZRFe+kaC!-oZ=_|2O) zR|9KqCOto%JA!ZzhaU;K+tR*-d+_OA0_{*kB?Cdrc@l~+&z z7(i=xHmkC?I)V7KYM^f5c_cqGx`QW;)(@2$yi?TDP{fo}1>sRqOT<6ibc8aZc(i3) zV_PsvKzqO`Q-mm+H(&Mt|5!WoupHB{|38)?V=KF?g;dr`rP3lH2}xvWA(Tp@(n>Kx z_FbD)s3Zw(%94GJB1whpr6eh7QT;x5hQZA5J>Eaw=a^&0gnFL)zV7Qf&+m2~v~YKK zcXCpkampT)1+*0B2@yUmq+Ubi(A648GiB)zQ|ktHV%rHfsvAfZUfH#{U&k54>p399}6s5UK0eBUxE7OEi+)B#omwE4W2x_3YETcV3)s zsZ3Uxy+}0TPI~%MDojoWP&gsys5U)XN86j2FeapY-d85bP^s8@d@l{2C!V2-CYICx4oyi_L1V)gK;O=6 z@7|uCwTK!ZD%cbNi!cxpFL%s1nsb8be`sPWJba=`+03}xj-f4G$;;sAqNk?y0b(pJ zwwpFBgVqHNq~hvUrl2o zX~%{5l*>KXAxWKsgJ--%TAGik<~u!9kzr8)&e{Zh0Hr~D-#rpGT@Y+IJKKkLn;<4P ze7JSe5D*r&A%xtsqVBteL>r@Y?P(0UcA_!C!LtH*hXNmfQ3O7x5;hp zwCTv|Erh1C%u@S}iSIhci|xqHYeEzIaIs{A)6S-wC;B*dRrQOF(2`eP0Mmrl^kDe- zQUG~sQH~J`2ZAMh#Z`i_XA@A|YT?63UzL!v?YqHUXAxq#A27d^p3! zq`=DfJ`1_~g8sFkG73xQ7nWbhg#35%>g}Un=@EaBZeBckKxu(@S3A|3h-WiIYr3bh zpx9f*q=e$i>CK<9HDF32#|OM0-uJtEUqqt%mfx$bHKvD*qX|WKPEPlB9fVIRAzY00MtQ;XDT*3$j!cE;1-sC(xHte7A>WB;0>N9H zn3$iJ7cfkmP?1~d`r81?>g86igpaA*n=8{=H2)%Zgt1itiigj$$$ zA)Q|=7o-%KE6sRd-gcbL!e&OdMo1mf!+ra*`!#%Q4b;z7abpFi-z>Esdu)(zv_odL z!UlX761qGld?WGh-HE1&3y;cM11fao#aHfW*=$_}QUK5$vSXwA1b?OK?eB|mK!6so z1X6DaGHoG23$|eD;Zm2bAsZg9I0TlZ==RRhr!F{eYahogc~d^T%Wo^nOrbkQdPItk zm6a0=O0QnQIhulVLPKSHFV*4fkSnK=Ba_*0>eY=6t83l*iPm_(^ht}n zp*^uAqsXnxxrw68gKr0qv(!{AI@kV>8b@~vQPHqgCwvCBD2xf1pmEZB!l8^?RdR~! zdfoj~a%b87SCd!wxjA|MwvPifx21GHQCgc3&w9h!zZ3FVESJ8LtS2C}?8lFnSXq6d zf@{^X<;mH{+1Uj7?&#%fQjQ%zo(>Daxnb8&CehK6LE9=Ss1(*2M++&qf})xu2X<{X zeryVv%B*@YI%<>pV8;vL{-`Rm3JTIz_Y7gc7SbBV%mqcOFbfgX8=#`<`7E7|nT1y_ z*3Rv<*W!&-=Gk@UX4Pw7-fmI7wa*it9%tME=m0KsXlWtpSTXf;d4~14x1~ifpD#QL z4Q}XEM@ar2!SSI(IC@Nn zc5D0`=R+aw^Yv9frVaDiX<@W%9~==tSbO`g0u}gvR%6zPDh{6GsymMhi?2!8Q#qH(884E`tbS1_%cPtmmoD zIta*u@>NPoZ`!mS;#TwLhlPjSwLW|13|mz8jT<)DPr={Vm0y*+v+(KQ_#V`Sh(BBi z9_RR1Q|p7FP8=`({?LLQ-uFeKk&B)}^$Kf-!9Y9}wd%sKF|aJD`t|5h z4gD#u%MC%-09^#JAq)La|CC4irwjKAAtBrSm@!Xsa!j4i1_$SJE)kYFciue8JjTvU z5X+@pp?+bzAyx-*HBa=Yjs7GlcI~Q>$E*38SU#a?OnH1^K9B0R*T@8p$gOW3cP;C(>FlZ+Cj*1q9OjPu3>X4}DQrxh7WM>BdOZeT z=!r2fL&kS&Z?)Y?qztBQf8K1q{@8z{5PZiq-VB<^2MyNP7Q~rGl-S59>0RW+)n^Z& zlI`*5!TQM61DM(FJF-z{mpDgmHTM^ zb2q)?HL4pw2dk>Fr*{w&bKj%HQQK}A`(6gTNTJd&wr(UqbQ#yISjfmp?a!=YPo`oM zCU#SRF_MJ?+`{LkXynZw;&D$)a7eb4%)jqarN+>1lRx*8>1Zguiv&?%lpQ@3q@|?7 zBO=y|GY!E!+^7dL9dSH10VRO%1-1i}s%d=yXTYU7V(5N~*qb`(A~Qj73$st(nLp8( zS$Jm)>hC>%JX&7nf2veUR^z7xf!lvuu~N|DF2!daPZbWrD(r z>!w~tH>*>?loCEOJc+WRVl4*sHd06#I85lfs9pss9KYII3E;m^@L$|JC%ohQj*Gnl z6VP8(t^9i-eEZKh$0Lcxb^j_lp7-6MO;fY1YEe=z1wIWU#5%r}|BicrZp=ze zptuJv_VHjBf<#ot*T~4cB|RuTW~s`&SRd1EUHtQ(?(hz{ z8pldjXtRJyJpH{;E0UqFY$%BL#pK8XB8((2xmS-K!23w(O97C;6S+oo3s1KSGjtl+ zz8$TlQ_QB`QB4bcCz^j!_xpC?KJ$3Nxm%O2S*^ej8GNA0@bP>lt>~}EO|s9-{^D?9 zx88i}u5#fx>=U1vyjH_bPa$->(tXR1+ zVn)uxheFrNOo3_BMi5s?PRCvA&bkO5dD6XkTG3Gm`K!3a?9&39@Bp1qK)w7#dw+my z!cxKcG&MEz({Knej*1k;j5kg~m^H!%m+Z%gnfz((Qq1mI$8&;m9+5`tq3g$JWIiRm zRP*M|3ECO2;e%X_Yf5pLkd#C^cWv7NLh$hK4X&=ft?fIWaUKdn%H7@1#Kk$rJrjZx zb54Z!Pm4q3>u&o4e6v8*G8!v6(hi>b9pX+z0Wmy&XXK*s{|VN{{L**QUe1i>_Rs9y zA&T34dGzRrwJ`h ztOAJ7^iS=%iR(ni!>jIkb<^uatET(7Ca2l=A|>n#eKc6Sgf97%;Eva<6r_$|7e$E0 zu89&4NCB|`;)3)++$6;9;(Qujx?&7}2UV5d=QO%En*Y?e*-_-Ufo~GJ417a$CwVde zO97_eL14#_k$t~w0lopk&r0Sgi!PRA4j$xY86yl!h7@6Aza<(lV#aH<|0pw(gPl1C zIjT|6hPPhvO<>32+yBR{7Fw-cg))Sb}h#|V`lF^dnS}Rc-c4sF&iet>q(!AkH>4-Pr(XLmo9_zr1WI= z+@(=O+{J>V1f%O6R{8`Y8pFg|9l^=ky}Q6Y=b=zMXO}JCvEvT3?sOE)fhjoe<*${% zW~$%s`FCmrkl2Qsuz2yl0|%ZwdKBrQ#(v6>5UdJ>-N<%%uzLZp5gNsej4}iUr5bKs z7epN~mNSpsxUqHo;ek?D8Rs%^pk9A*m%9C!shVEx^#8f0*9OXt90tb4bIKE0$(t!s zneQtO->s`Zeflm#8Gu}9kx|38GA+mMie%GnTn~}Vl0~+^wC?WthgdjH<-TVR@SJOI z&P=ms^I}?viX2&Jz@VdhZ#Nr0V)*c>DAgPs2Kkb_$sS412x7k2+PW{bi8u-!LH=gv2g{Kg}n!+s&5f}0VkLa+l=U{{!)0_k>R313EXX#xG)XQou1PR$@fHe_j zWntkB8wF5=ze3;nHQO8_Ol}$zjrJMJOrA0&LIT(tFJ0n2N$K~pq>_OcgDwGkVvf@N z;wTu&h1bRBKXRAchh4QQ=VJ>J2>|ar=AZV)x!=9}VE;Qb>O`I`f1BR3{QwLJRWORa z;_Mj@mW_+s&X^HG#|R@MssL*>N;W=&*Gd@I`kSm2ew#xNViLCV)NIgv-<<$>06ugH zJl@qcHC%l*DDxDjL2`1NG76b&fQ~RzVpL9HsdZQLyAke|yWWarBcee1smZ{W8?QXP zyufb1%=%k{D-yL>U#lJ8>f2{3>WXt8TF1r73B#%3D^!yxEtIfnrKYNL+vkcMAHpR@ zYvF(A4F?&JByCp0(`(lvQd8#+_m9tgPbLdGl~8RTZw_X1MD*n+Klc%AGMZ20D zQ)D;%THWSR6OV4VcV}qU<;#bXFMoUY)cCUh&;;voxB)n2OSW&<4nZEThj}E}pWQxy z@F1aMS(@hg+3v;!XXgs|m6c1=TuUXL&%v2@-_Tx^S&%RyDJFaxVoemN7no}Xi{5QZ z*Up_QV1a|eKQoXys6YQc41lrA^|MC-1iZ^DoZ$z5eK|+p_uE_;_c4Fq#KY*FAc5r$2kV1Jj>L zW{<5$Y=pb=MDiwS)+#=I3YdYGlksHYx^&Ax(18cRVaX~OB?pf&C)%WHmM=$_sz&LJ3e3S733fa|pEkhmYr2(euN62Bnp1}BdY*VtFMm1qNbD9;D1Lcl{|C-%d( zPo35A4~A^KxSgOKp>^rQyz@N95=j3f^^AXgEr!V@@CGeJy>vIrAG~3eB2h`jp5C=yh9`1?#R=+MTzFqkhaTKK#@`&o{@`cD%czmk*>oOJW zM(q^K)(`9%9Y=EbJ<3d;&XL=!PK_pvO~c=m$*ynTx;hVMYzc4Yk~>HrM&}TlGTs zJdG|IH99jxsnu(*%4%cF)}J~pDb~rb`mo-9V|u7fk$Gj!$deZywTdwH5Uc#qKQ4QX zpV6>$IbXJZuBsBO3HfFBn`bU`4{$rS!$+l;qT@u%*yLnyZ|hUD)5jg`OE>~IYgU9Y zp}DXcWz3}zYulE>yO$I-0%Z?_Ld>R3bHpzOZ)7&yRAvuxoZU$+3Ral{0!l&YGzwQA4cPPpd)5e7gC5o$ydF9tib%_SFa8m$#Mf)Hg6_1P)^R4 zN7#2KodSd-(m~P&_z}RxN^P!&kaI^i!m*=AM=B}3s;J?dqOjm_LXqi|vI@C~iNANoN?4*^nPw&v?A{ zv&K==wHa2TFq_&JHahhxN7jDUjHtJn_ER4;Kl3-(_BJR*t-3T5(Daa|GKqELm0eA& zKhhF*TVHXl&``K2RupPD3OP=T&bn;zq=JEQu_HQvc%o*#6LTHNB*Ie;WC%s_3`UNi z(>p*YG}#c?O_h|g=v!s>Fa-plIZ!w+m$d33HBenW=$aKFkd|=2aDybYJ?LFS!LnE} zkWGuJQ%ra!O~uw1b1~<0Z2Sf>4F>uOL0o3T8wp=0cR8~@n3+yIjH6c6sSCgO_Hs9e zf+3<2SLmiqw?HRxXIOmM3ddIVSePVAb(Et?xph$)Ccp0v8@330`yt|Dvxm-NXxgb$ zD~MOfx`c0o4dK|aV#Kew#^|KblVNjCKnE;P{5T36A&bNqbTADPZ|c;@IC{a%KFy)^ zfv$6A_ArQ096VUSGXc1%Aec_WrUcpiexI`4cB3ha7rzmdh^J3;#G(9TlZ(6B^Z`ct z{QyQpqWPKVkOA7A3tn#xX`0hFj#l=V#}V^#%MKgIiMOD@D|GLzLPIw91;k=-8oYS9YBTjxlduFQvCI zppa40bioRttZLpWb}wfL)8HK=Zsii!}r0P@$Ad5xm#n2CH)__f#8 z3atsA^4&?~$lPbA4juYS#@zNI$BPwD(8BoKQ5jo>zVqo8?ZbB4ciy$$<2q-B%QH@C zPXa;qJo~e$oTKIa?zK55|H!dceWyh{1P0O&ZpjB)58EzVuJJ5BO*!|UW%k82*Ck)v zl6*0#V-qM^w1YCmIGQICS;*HPvxNs}6M13CZSCl`L0-{9HvXF`s=6(d0hDv^`Ux%l;K7nI(*`VdUs-db7lJeOQM z4kh26jQ@@>&YdUG)CRO$@=v`g^w1&gmh_$N>RLs}Ke_RUw}K8Fz=3jmX&46{oiTMc zvbkM5ck0+bVJr#smN1YT_=Go<-fa$G7J^WeFKqrOHR$vYm%?G868MA<1Tzcq$W#m< zA0OtqW?e?pc}rNqzT`h$YaQUEG(R; z?Y_|EpQ3!CgTt__55>ijojOU2i>0o<(`^1uBh3p}zvkqe0&nvnUI3{pQ-Mdol@fG6 zEu(Qzdsy2p-MiBfIzBmbKR-YCL-=?xp><|si82hdLhr~U)O{8$sSD?AB2U}NlaFB> z9G<{*6G%WkclK-@z%W3vr+5mgQ6$KiF{o$B$R;YtvPbxd6CZf2;Z3PQiRT#aUxOV_ zLrrZpHfq{D!wdv~b0Zrm5EH$rD`KdNLg=c*17b%chPtcp&8GU?S}Mf1%1U_ zoAwf}4E>bvw2A!aesIyu9DrVT}5FdR@QDU?YT+s6EaiEDm7VIzue_K`F7|C zIBvaOyrF`j=@cw4$F}BSX6GWZ4YrY@fu=NBNw5$Hi`KXa3y!3K-lKixRq(^m{RM+iW z8GHVHr-z;H1=Qbq=+adx(OoF2yDLRO42LX>D=90BOWEDjzFf@w5kFJ38dQ_#ksSfZ z3NZVc74i<2)5i7d75X3u;fMnx6%?P$kLF0_8%t|o zsy0(tiK3B5eiW`2ZD#zjJ7KcX^W~#`#fQ_)IK7jL{VH5Aq`{LSj3FURO;JmknVU}$ z>#1zl<^0av>tW~49T2~~%7pl<+v&Pu3jaSvSocR)-)Y^II2K-^cn1M+QS3-jn2*)A zkMBcP%pUsozQGPK7HZWP~Gn&pR z9o6aEvus=+H#G#sU9S& z-OYsPkeISlu%QE&iAnu^VjfC<<{1;bfU&WO`jl^vm%6T8sodw>H*MLV?m2_*N<0`P zCNpmPy?IDymM%3E1LK_JxW1WaoVdXU*UHPg&my$qDMl9dbW7O?kxrUwQyo%x;Z{$L zDc{7DYrMy2rKSH3n-q;FpDEgeTpJ(;!pLSc`?Ym@20CX;gwQKu_}REq%$}jWB=7_v zXh~nozfoqV$n`f~;jLVjdm7ajW>gU8&o84E2Mu5mQG>C8rAO1+K$D9}0dp`#%P@n7 zmZORSqq6|sp-y&WNXzP}pR0{KHh8@_8M6P$AYazjln`}p{zAZ7rjuH7w=MtMb$tPO1tDr&iy3YI?!uhz2WokQ=AjS@{&!Dq|dlF;1xaDuqt+ z+pGTenkQ|x+R^l^h#Gt8;^!TUWMjLFQpZ*7X_g_BIYpt|fM3bZjK*w(J2!8Nb?m6B zqH<8hAt*Unb%w!vt_I&dP;s$=xjCAoY)Vh%9cBMUmBn@ct!VP=tM}pMOX?v+ECA)i z=3@aQzb8&jml}z~nq?_W@d03%d&&yG?*tOc**mEE@^dum_?;Hbn-`s;3q|HkdE_ZR zP}I&qHYMNI*Un*#Ti@m+-3JLqbAYnzqzH^j}HTbPv|? z05L`*u>n|hv1|G#BwL@DANU=KsI??vPwg22D|PG9bsAe4aloJJp@x=LLv z$&jYp+*}sddBwdznZ$u9DBx>dAc?RGKU1o63JN$5zztLSvG%}D=6VW)h!-vdTU8?Q zD$%D|Q+YOW?}EX=^TMlWA!rr*`Jd}A6PiO37spbZ*LC^;x23&RmzgbDQdDwKQuJJT z?5(HU2f1+s0me)bLnt3UjI~M#PtjO3P3L14Mi;DI1~)-(z!hCuz{!nR#%*{U=LoWW zyrOREL-yT9k+8j=HWB;UpaZg96yL0C!o4?~Zmd^+MV#U4UNS0ankQYGiH0{}si$;vLF6sas5P2q}aB8`%toCXf-*DOZPHp-dx zx=6SNi;Ia#(SaxI^_Vi{E}8<;gwSwazH$X7Ik4r+seiO=N&Gog86Yme0*3>~29OTY z_7pR6W;>;dABz!dBQ>hc@%m)#XcI{ZiRrUv%XZpSz3PJgz(aSI?uZ;sXhV2w$3H98 ze^#1U9bG-EgXnxjKkrr#9mh$|E|`($Q|0?zvBp|i*UjKVb5T1n;44VP-W?`3Rg9!} zqNMBeO>XE3Faw)Tj5anKLotah*M#uG*jRIlw+df5}q*N2P|Ox{4*vrTlc4?`7>-$K z6m25pg`wpD`Sct#MtJLM)^_;L>hgc<9?_Buz@3cE`%wbj+=KNy>+XQk&5c000;mf; zSDDbHSNI3D2qHmVdD1QLYm;S*_B%c zn2al2yx$g@^wENUZOg6H_pWPdIzZ_#1_@#i(+#`z2U3&6yR(xRE`&LNj&U1K7c^2; zHRogCBWiStvB^8ID-e%Hn*>XVWyC_kN%-hRjV5XLpG18tKm_0$WFv4W)(nt{cEe;; zx2Q3cUD}uD1h0TVhP*Rqp%NV1ZCzks&)~a}9@f4)AwQ_j`wlzRIcUJ5_}nArvwDXl zpE$AoAYAg1dZQtvc;L}R@S2q5>bSlsGh$@s4;aLvYl-UWKKgOFgg3E$10)Ht&7+uf z%k%ib%mP~xGNHRE*iF$d5(0wmRKq`!J3vhItnsd)-pt!b&FxY+KgJ(uHE*V$>`3~UD^L@4h9DA7(kp@d-j zuB@tx^jadJ+W`YAQ5AACB4N_G)nC@{Lu}Otff%h3&~pu6s!7qsNa~ zcpnh7F}H(mlox>`39bJIR+QQgq<= zLbWZ)z~S(E{#>Uu$rDTL?8rpKPsOF4%$WmZC}5>#sV>Y-$CS=BqS-c**#n0EXKFgq%D9GO)4)B%#xQMMM8yaHiIkhcR67MML7{dbtO>n1()rV#PFnfszY z(75CyKovVa4uSL44b4R^!TJMh!I7z38jVf=(Wn?sj>>p^@ZIRq3xVxGYUokowAzX; zie8opuW4eFrcH|)Mq^&tpUMS>HMS9xWniCptV*_P^>zKeGwnfh8{sb%Zg6cK8h7hS zPmj?@$1Cu|LUDJw=f8`)$X8XV5G+A=mVCps=KR34o~i!d;k5IOkF)h*#ge-EKb{Xm z?@pTkG)hfZ`J0wIgK&ZGT5h{OCi2;U3O0=KV2qV!>wWCMV zzAwiKidY3|>?sEYg}nJ2lcw71;?BRm3+mhl8Fu~4qqEg_Er7nKVaL(EJ4pEohliP` z!4Pdq-xX-*z(pgB5o7<+x-|mSzfD?;k`#Vev;?V=HRi*$Yny43y2_bRET04ofnm@( zonGm}Ntvl%Y_}V=5AmN9N!2=cBbES!FR-ym$;66|U8glKV9ZH2&wiSo51&2_dB+6i zFeBLu)i1aF2OskG4$-+(H7{td!A^PbIih^UQ_TAI>{&x@bBu{Ru^TARic3m53kp0? zs@G0J(#Mk0SX6oc(Tuw&FEmx}FjZ`qK?H$TyhXO^jKVC;vO4SjciLy3(WgHk9ru|} zb3-RY7%Mkn%Y}?dZzm=Ofz0_wPZZU2E(*azZH)Q1r0TNXQdj@BWmP_!=eSa-op5+< zYC60?_9EAD%>}*X>zAoV)O1yXr{pcZdEW!q7h=FRQWz_23p@x9FRYpa356UA5~_0DSA_dW;0es_uyKZwkJB(a*lB?@Z7BC z`(rNX^oR98A7$8f$Bl~5pPyoU(+%Hg5CKI46|u~5*hFVviU~}i7&O$V?bJzSl{!M> zp{*VIE`_<7g5hk8$L=dH5N%`)%Myu>Zl9Ahs?An$MJhc$Fk}T1L9Au>B@=%W*HrGt zn*-B}3U4rZ$|%|)Q|Hsc9Ws7vxSx*OBJM;mC1svrpkl;{6ZdZ4wga0Ey5aU6CoXhK2_^lMg)1fn9gCPc z5cKWDiDl@hkzjO`c3ZImQSSabZjii>K$8ZPVaxvVn#ye0H?*yKE>eo0rK+2 zbmd4b3?&k{{&eM?b)lb^5UKYXqN=Iqo@M8O4(7i+52QPx^K*DGe%oB@&H`;0DgWWW zOcT#0|53%-Is56dT?(b@y5jPP3mv{)rdDd-1Ke~*V7=ir*q70qS^KYFpWrD@_0y|Y z%p)Jj()8_fu&yNNppf~^d-Do^S(4ABrpW%PVVpt`44%1zMo#L~<=?wHExT##jtdvO z-8S1c7mbvedZ3yhhK5)D8pS$vXh8fAXH|rxd(@+&ix1lJI9heOOhZeup&)65ksSRn#D2kX()9ZF#INbAxV(O$ZX&sz(XZ(2mzu(}RzCX&m z%2WU2MmDu#_-J4h-`@o9Q{0*lFwZ&qxuT-t<41QeI`o=IAeSusmkMx%L)kHrfMr-F zEpv=o=Qej30{Cw)i$AwCl>O81FOn^F8tWF+Q@!MmH6Jp+F1qOa>TcMVo}Yum8rdUX zXJ4pl{U~eQ1PyVY?S0fU+Sl4R>0Fq&W5nl`{YR`-zPzV$)LYZEZqH}7J06!f_T9|B z&ChGxw9ht`sJdL?ar0}ss706h1##LwHD5MesLx$mbgoZ}@?6TOxQ?r}Ivy_=dwz3x z)f_cZ<$mw#oS)9>^s=HQw$ zbU$oc@Btwt8$#gGqYIuUBYJNZKMjHaV8d9AgI5vR{`AUBYXW-KgioC}PXjRkDz`qC zLQ*^Kqu`FwIi-(Jy&@@k`?hVI<)tOFfBLKZ(zEB^KN}3Qu{I}-U1E1ZRe>bpxmBya z`bi96Y{j8Rfw^J!SZaw84hH0*#MamM!gNJqHJc0I3mqO#ZBsIMIJq;!5y2G^xNd2g z=F`}4_3Bk%Eup%0c4spV=`dal_W0h5D;ou88_me7@@w7E?5asEqCuzU^%W;YmMx7x z;r6fhE}8nKf8$JduafX9>%V+}I-m5)`^&Ar{&;r6@ymxUTBlYNbnlw%nDTjX?dTyx zBF(2wv^i%~o%`~rTcldF`Jt%83sqg;rw+RRVfzfPk)Jzi*S}75$vwQKz%?GeFHCc| zzn9?tXsc(;ajB_kF0+U95wM!CFq7P$aad=bwt0`s$=1$JaKWS4(Gyd{p9|9gtpq)Y zW>gEJjB}gAkTh`Jn@v+lu7S|%jvM#xxey0NHu#2*nCA1RZnU$tjmBiGua9^$d;pOq z!QzTG_j(hFLxn~|2Ty+@_4|qWZT+<~8s{?jWTSsw+{I~~#zfV>s45>(cHpc0l1J$$ zGamJ+FATH@En2u@$!E9j0gc|Oo}(P5%|7#dlEpIHD!GokWL-W>*7!8uG1Ik7b*nv6 zaiqZKqwUK*t|Ry%=X!F+Nh)3xlY$~HEO#d!SlkL8+Pbl9@Mgj??hfESch)^)b^>a$ zuBxL}br_~xUPq3+rqQ#Db9Fw7m}_Z%(p{AGs2j1x^^!Ug9lhxSR`7tf$}Zm(o8LZ3 z55EmBr_PUca0vbIIAxK=^TBPqW$rJ!c(GBXA!u(^&AGs`q9yhk-m=~q@IxBfDk{q5 z31>7+>u)W4KU?=^mZgvRmut_QP5%rEm9z2F%h#G?yL5@Z*ov=4V;tXVunuw_ z@J7F{W+z-7^2$56j&HPF=@7ds{KcU!^_{vkICkBqtb8gs`AKTs;foK4DqakIS1_|~ zK+39_#oNoaZ1$Kt_d-@%Bcsj62vQA~g&cId)t!xhxtxwj6uXC~62kTE9X%c@YD4J}68%PIVJN5B8uWrF#N!6z^C zR`>gF+}_q`X}k74=G7NTq@CPZ^J(_fdu#88hUB01y7c6|eX=ILVE3NL?Y+y#eofjx*tsZuj%J@et{X>=Z=G@A z{)2}J$){%7B^O`UIH%e0;oXeZDy#QbXI&aFr!b&O?Nm(c+49XkTAs2ETgo2nI9VTT zx1)N|zR1Y8Z$iDtB)erq*ym_B6qi^>&RA7=Z^KhB?*=EYchP(PYN6fo+~-+$3bBBg zPa!ox;Ktv+O(J3(I2l0_2571h9HCQ9P2Fe?ptjiM7pkM`!yE%EUV(cElN}Qf{BX!t zlw%3X-XNrgBJ$vyX_3JNkb6x~t|pv5y?NU<^MobSm7adTfZzVBe)zvzmp)7ebYa4~_xn z&~~UlU}JZ?!vaf1C6xy2&&QToTN~6&>!r3^ZMmCMySBaEruGjQv+8lbWXHCIALb{` zG@X}!{j${@_s6G4Bz2muRN6hxY*Oy&TSk@zMwULGHMUqE_sgxiRF__H&Lrw^bhy-> zTi$666IGRz28?U*MQiGa#tHO`t?|fW*qXT`G&cod`+LEG_41-{K0tCAEEMuw*%IHn zb2==o+bJ~;7(7UA*Re?5di-1O%TamczQXCl%f|KB4W?*os+Gj!V43TBF3IN($Q4>W z@v7eGmp-Lo-q!5WyNyH67h7AqCZ98#JbBNR7wx>fB=VOnn!o(Z0<{?}uWxvebzcJO zw?RaZq@>;`H{(q0%a;TE&zN=4aDDcA(w!?;$~0Ge|)W^hTe}1?uVfTdurV z6;wUtmJscCO(`xq#@@ZwWa8v4ejiLt6nUihW?sgYjVDusqFbC@8D}_g^5j$UQ?vI< zT#4G+WB9Tq`ubDa*H!PyAG{-Zm2k}NdAWS_W=r7!q&R2=t@|6wk*dxbwS3#`&$MKIcD!38M(G$9oP2R*G);K)1D=12iAYOshzAe&Cw*m>O=30 zote(M_eVO8@ZA3_DQQUe^nRUdPNZzw6u7Hg)-tqs;*J3SD#zK~&wJc?Vd;H8`+iT& zhv;G%Arf6N6+?sbsf|! zMMYbK(iESkmfMXi8H(pXLt;&%)xqEz#e%w!lHyB?@_YL1C{@pC|5hniuHbN8T7sK& z#@dAnyDdf)`uA)rid#D?Ma<>vkV#&PAD5f966NW7)h~OLeM0R_QVY=<>9@5{QW{!) zR?MrlP!pXyq5fPmtV6JIVQt_c_p<0AT7rf>tdts?a=EG`M;JfAumWT~dIbGEinENX zHG1CtaF^J~NMTq?%3nFz*-V_5Zyy~S3qrMQL2pv|tgO(xR+t^O7rI#1xWKf_A z3Hy8Zf~qV=fkgK_qTd|ZE{Li3HI$NBfc9Fp%XUfSV`t7(LyUle6r5bpB3}?QK?qQ& zxVpG3%KxQG4I45}B0%!8Ph;kagMT3U4VgS)!gaLByeYq%s0=tD(SuPUpNNg^gR-8m z2O1)Fc%rSfiKZp5dE{Zzh5&!bWmCgL1?EOGGt4~oVNOmCp&p8g#;1lF%1KI)s)HIF z%7E+cHXb<+|Ab$le5L)ZndL8D2FG5<4hn_bjJcZLC?6~HwUNi^S>XCI!DQh`35VTFE6 zC>(%LX$?V8K7aYb5AZoL1KR)qllF=KmH;RT- zf+*MHF)>1(5OP%7oSu@B>X;EBSBVdPie3r!VCkxeC3;s2D;QW@#YDg+Wg|zj-_by^ z^querq{zW6f-w_{5Pa(r^3HetyZospw3C-03!qd8}J$3kD zhd>nvNu}4QYN&Wyv}!lssgCHW@zSK%-ADd@FfgFlg;7*pyN_*33`hbW_FH_6~%76<2DRu65Ja5#)f(n2|mwu;2;0#bAI3U+No@6D) z0CAQ6{8Ldu!Nc0hF6wZC7~cV453xoTS49Z_>$U}P1v&S5r>4a2DDLvO8daA;#uLGK zL{JmPuub~?#mO(*8@MGncpmK3ooV+$0C`zhECZit z&5)g-NB%DI4KBh6wxO@c#*n|^k2g#67Qm0ds}G0!naDF#MdqxS9!h9ejKrJt6d4Es zb4COn{s{rVHBYaucF&%WIAgvg#BMCfIe(JfMYzfhC_o^gD!~#(cvVtf#WBtC#2;~d zbRBZhPgYyoa@w>qXjil0s!+L7QfqU4LG=rm{dwewUa7_p*tO}hns@8lnyom~4$^k^ z^yy<6DCffJWY>WdVD}|UXQ4p|(f!Q&J7Uae)GeDfq5r~GGiz0c0TM{$52&v^hRxLv z!W2HL>$LD5+x+0>G?K9Ru{rah?oMRkqPX_?THbokN4RRnPDNG@)vr2(BpPFhrDf=i zSA?u1qhqM%(WA1sfLK7+Y{nkzn}_?)GcmdP#)*j$oiPt*W`;#a z=dQA{>#k=j;dhh7F#fy;XJvM<%6dL?S%pg37Mit>a~_u z1NaSF(;(@!I{kO)vxjVw9X70#3r8&fk{Y?kH?-t257KItD_^ zotzEQf^B;iPs6K{5_=dL1bikYF6_hBhle6jq9p_rnSXn)91tHL9<~Af6ZB7IW9Suq zJ$_gZ=nckQp)U02Q>c?ZAMkXTelVY-z+4JcZ$#aPg zSZ6%8M;3!)5#4=w{dyD?07yZE%~%!Xs~o7Di0D>nMoI6`OW>Y@$0Nex>{J>wXgp5T znyU||PW*P^3~>o@ROvC9s;s2s&U?E^SGk8O$3mK;SeHUVDkF29f+#n)hLU8oPs6!= z`?~I_0#;|FBsp1W$ORfOY@oszru|37K%?NaVRKIV+V&o`L_Dj4?WqTu_?%s0zdg;F zEjv_%LQYoQeU$=jFFxI2*;KE=pEmcP9yGVTAj<4?*RtpGr|!xDE8%BKL-bn@>b3>Y z-meHPI^%NCGN7lK=ruUI76(2@X}2Cd9zWY8&e7Q0Go`Hl-pbGOPnT{@yWtvA(yAix z{obM?0VP{p0Cf2_&Ti7{)b-mve;dBykDLt2O&!q0oFme}R=Hluve zk#Ju9!OUl!XHWA|s>X!<9o#z}y%PB_#XC~=nb(6=vut>b)^tC`S&5pA=t59B!M2@v zTr@x$Z$wE+{}xy=Wg1vWr(~y9U`X~j%PIf4dkbjBbJOs3Tj*!csgnn z1>p;75q28>03z2xhXAPAliIdyzDe)&@)wuMh1ZwczG1_4wCcn@pqTy&S6owFEk2#n zhV)VrBKBbP;_nC!+s%O#T>M(wv+`(aswb0SA(=L9+eRZ9$yi`^_-j_>u;--2`tb+m zDvvI?f4DxY4TQqC837XwW;}OFLF<9V7~2F#BlCYMi7U&c(C05s9=IDsV+VOMD8P;# z-Yb*nkgt-x$|OsMhd*v_wo*>uoj04WSw%$5GPj8^qUNlpKn}GJ>4|!S@(|6<0YX8u zUg8IO|NeN@w*JzIW$W`MWFNppd42dwj;0~2e{ic!Yvb>AqGQk2=9I!Hz$sK4elmsu zCy~@K%fmosj{qie8EL~;EMLwXx}cySMB@u4AiY*5at~6EW`L80653z|>F^4ipqyL8 z2cs7dcmbyH$cAPl3)u&Y@O>KuRu*TM0N8+D^EWZa;uJV&BulU!KZBy6ho+|sQfK5g z0r4@dZ19fBPmx0W3GT_3i8mY7Xf?17d;T~*ek!Lqb?Hov^02V}5tE|tPE>ZF_Jf)r zL%eWqA#*n=G@7m%#N#!i5hw3$#cj(hT6aLwV-ASw^R~_x`LJd6TxO$XkY7LF__EX!hKafg}T5$6U?6^dcI-7kjf5u{O z)mBofAfk-Jk|TkR%w{2p+g9k0aLCeV@|kHG$czLmUA}yI|3h@1moMu=4O{=Es{98? z_ju&3T%K*)+Gk1cGoa)MIAu3cZWw2>n@Pp=Dft&KKIiabqVm0aC-}s!(KB;$@7|rF z@UZQ1r4mjV6b{Eq?QD*?ey|fn*RetWy2auW$>%%s;oVn@t=COjw9yY=>C_PQYh!eb zhIT{OkxQ$He|=ylX(EIimo6PBO&|H!U(KUUwJh=HL-x<&?!&`LTFk(E6eAHQ&O;KNpq)_>}mV77zc7HR}&>~E0- zdL$h%1M|jJ6Ac5~6%XGY4pLF_r@kMPquzN}v2n}^rL2wZvoEhia!6ZgB3~0Ua=~R* zCn@eVgiXN0!s5OEe-t4ZI11gHVi@r3 z_-@>&v~M2gEjU1FL0a0DEp7epOd<7lGZE^))E<#Lm!Po_n%2rnnrLgLcUSBj`w06T z-F3fi-QYhJxfXmD*+)I(uABBc7bqt@nRG)uZMlBa(!zDPH@bFm4lid+U<~CZPX~?)EN}nJ!q-5nUk?ROBFU$~t zfKyc-kmzihe^kZhTEwh6wQthezpu!e6C194jrt9rdba7D^n`UAjZA|^h!XTFOk0_$ zTC}$g30!?rq~09M?uakv3sO$>HB1UA|MK{R^V9iSdqO^GrZ!HdcX+{#vg-^7`}JjE>H_~R=7F*If$D=Sykj2>n=%FgQc zh;F|U@?oXVlLk@B6z&WODMi1C786@P!bJX=a&SxvVq@x7Y#%Ylk7HS1M&cxkKu~tJ zqikr~rcEGDAENxhiU^cTAfv|8(h{_W2&stEBN3Up6d4iMMo6fj!WUS5juF;5sLM11 z1A=;Oj|uWU?1Bb!PL=8%QMtm?O>e{FwnI|+HWqUZf@nip9%t!pN@tm4OF$_4V?;H? zqqUP9wFHdAuyuBgd_>MCxtJ=Gkm$T6zh1StHQx#y(J(^oZx>b|Ou;M1WoOhA6CL8? zD|nzc3DfO)@p$0~cV4jq;D(uQcyj;ea~uq5=~s*M!Whp9l>8{9o;_;-yHZkC7A8Z` zS%Gm80fjb~Bw&3#yIwegIjoQubcwgh51ekN^dBenLu;l6LqJBK=@0ls-$nb`yTc8p zS(9kjWU_NBc~nX(&H2Eyb*y5hVH`fX^)qHonY1#}E^Ap`#vi|4gr;Sw-iCk`Ec>u& z9PU`Qq%jq7;_10?bpPwDy}oxg={kyC=hLxv7HdhWHqkJCwD1&zU0%^eLelYpxBGGL zF&vWjMR!DTyUFjyt2wi0oEvbK)CvkvpiqmMY(d!D~Hw6uo-~in+wzp2FhkjT<+ZxH@v= zM*>Plql*C#Bq@IW{Q0`N&E>{~?gD7t`s4{oCDT|iB!lCX1iYxq23F4qP#7?DC{xq) z!9Ai6|JkO^q$yJXTZ*5aO=enI#qkM=+uo;iiQl|qhfO}t_d_bHhe zJgp@H@@nKGyZ7ny^s-#clu5z|!GDXsk+6t)^;do@yry4-`Tnm@H$H*a;N~AK88Tt< z!7I(#Tr*&)#;dYZ=7p)3R>^3*@p5VOubTQ=ZTZj%54ODhs<^P(bLC9=?rXRE46==D zr_pd*q%&_xT*2McJmuCot~l?mnuTiQ6ogq!FgSMI=Sm7V;J=3)W1MNSrGZPE`c=1ftMf|5=lpntv*7?fR z`R2_l-cMW8p?SW{CHq!6vx`PAU;EQmQzXXRkUWh)+`HnC;lFDd*EQYgAK&BKFaACd zfBUM7RTKL7+gFROHdWBSeKm8_|F=(fG3S(Fx5T}*?rO6&IoaSSco*+KjA5%2hL7#5 z`Q@995>lx^{;&bXPGi1$)ZxPwfLBRc5<1<(bDx3ViOy*?WssTLwd>e1=h35O{;PiZ z4(fgY$DF%~Zrwz2!``=S6(>xbB-#uCYEyJdiIDv9G$SJ;J$z zufVEj@{P)zwj%dL#PM~FTLF8+;q?iUS7&IRRR*nWJ0w*CQlwzjvSGz9m_vdxZ5l?lF6#OcE0PwgX3-8gO9hpXy0=D{Ew+> ztE!iiRY}7FTSX0z0xC;u!DU~c`Vvd}8m7PL>+3&GagKU|&obo2E?g!_!Ld%Y(40{ZeK*eR}!*iT&y`8oy=?nI!)6Jx@J>>aCDw0LbkO!pztrHhHV`FTnzawR`*?B{Ld<#zVSkwr`g z!ktY*>pPHts7<0Xa)X5dp*V@=AVp;UA8QwE1`3T2J&!hicl^mK`SWLrEQYxE9(ZmU zMfi9<-iQZR03v|7pc1g9jH!vkQN`v9(V&NOSeU@PUETX@wLt%wr7)=Hdehu{8g25# z126RiJYbIO9^#C+8HB0Oj&JHb_^Qw786=hbvc1p=pA2}1aDh*(tpH8=Z1IPmKJ?Y*r;8W@uMk#l?FPJIDxIc&V zvwt+Swr*-IbOmDx?>(7>ODtH)rh`T?kP$489OOeUPWPE*M?%$C8Vv0w;I)k0(c4Sl zP^V4gi!UZ-QV%Qz*w*n}`2=0vzhD74C-AF66$*MnzLWL6%e~{T(%bTJooB^L05>K&{d7kk{I(U5}3lSFzbdF{eqcpUS9FfCT!} zrkVB;hI%k(wJ(`9Jjs|Agput|Z#LUaOS}|(dmsQebO$Szkd zMYK*-7(Ff%KGL8Y=dNro3VS*xzWG)^s)|iQG}K+yf`I~1s50#rW+XL3x)WaJZaQWkm0!qcF}WWPnQVG44ju^C;U79(+a&co{hs zeSY@S&{FG ziU!KaU~6OKg%1Ia>=>a8LqIrIEZe&EMjjUMd_jOqW59c2P@Cg|k04i1&we2m07h?C zoJB|wVkOC-g9q$E&8M5<7rJ`~8a-_DfQ1EEWo3hOBAm%;ElwV9VnSBqFhCU?RI#=opX7ugVdjk}FQIzlHg;kF}mP zZI>3NdXCI>yI5V_T+ou*D6lf#;Xp8==%qWYHqlNusFQba&P5 zldt01i4xXV)jmBQWA41%f#QFB`sWnq`u4?(T@tjny-BB`>UofbvX-(Wu(qeH)yzHzOZ zD8XOf2(FB9vEz4y2?Cgld7)3oIu-b;kA^FS06rf=s0uf`elE^t*)nen(PPV&Ed{yy z%-ydmYS?>Jd{|h!Z!Kbbm^d+tDjF=jhvK4}*f<{FTUtku0;zZ%g#pHn`wab#BC}yt zdH|f%H5c5#Nmc8ejR=%OiPO0I{vyRdnqzV=CVO5;-}LKyRgVLI0&L`kK!@4jO)^1P zRDrqQk{`{lfLOB!Fk6~^Iq`MhQ-^qa`v+Di#vn%2BJ_FxR)@p;nicgoYWe65Paff{ zywI4q(P*ZZ!yXVhfLk)!)L-EhR7{}@vAma>jC zUjMC#tM+Y<__J+W5axp(J7(L4VQ(0b_VrWxA`5F}VRS-JP~PrSv8NS9eY$Don(s9m z&h|w(r`0?lO{7cTh@#L?OQOCcxRFaZcSs&XS;JAa*|eBP4O))`n8mboG!%ZqfDpcj zVP~x$dZF%Ax?Q?FL{#GA(+K$=c?c8nhV|?3vd_U*zV{$*iWRZXsoS6HAp!KRzF1DV zlQAo}&3XW1x3`b)-!F$L*F&~(ErF64klM?`gDVATFj*mtk+0#)nP5(HNP;e9&0^E* zH*Q4LWG|5q%bOYd8&dS(p_3d{(hT;}iY#0CE943Q$FA`skE8_nk&G~QxPO4A85#zq z!Meg=ou82+JL@@nJ%7ZYHmyjV?lS&&AZ^^}1Cz%07f07EaGme6Y=Cm!Yt|Al*}m_X zGYm?04g-l5Z2~8*slBCJhK&3^qk|aZkQW;8v(wtIBqEJr*rC~J? znnMwOpPRk*UTg37cf5bRj(x1%YT!!#c z1!p?2D{Rn^2=dD!_U|{Gb3ORz4YjWBlfPnn$@e%d`L+#PAK?4$sFb_))u|v-dlhC- zyJE4yn1@g1Pp+lR1IGskT7x4CHokgGpQrS8RF|jqWoCAPm9p*I8~QE~Yk0W2J_qcT zAK~0XM&^2!tw=#`+x1IAISj&2sgfb=8asa6n;^%=g8tG&FlyL>@?qkRzW!hs;6jxD z{S5-bJ|;v&C`DP*Gxxj+6<%|?uTjE!bR~?;<>jZ^cm_NzWF zZ+iUVACb%?*N52&myiF-i`R=n4S!0E;y|@mOMf zZM*p)5;ZCwYT#Pxqy2b3wrJ3;ZEef02Cmee8zqsEj3TF?RwpfQIO8HJEKXr#^_fCw z?yx@6Yt`Fsctt7jn}h+Qi&<9|D>H#zG2a%v6o4JUl&$j_=VJo8DW|7y`ETwPl#kz9D+t1{#K(nWtS@G6aD1aL4)SQk^x_wIC03(p+l9F<^rx3TsseIsSze1E!4tP zC;e8LFHhmwH#UE#yu5;~q)Z6TF{tJiqg<#ibH^40A|#sSDC^j@^A$?p^BAgWo7t8QueUNA>ZXKmU6{)RfCHJiT}C-}lfrT=Rnm=t|D#vDc4n zQa+`zZG_r9XmoDM5tB4P^m5{}yMzW>4o9^E!xaTnJ$UZSIM9LcvY{jagAo~Gu7zo1;S z*NZ)L#S%e3Dk3V=$YT3uVf6?r3A)+QORn4I@(mYVmr`o)OW0Z3Qx&7UPVbWkes|oF z7g}Oq`*CRIvQDfgRQ71FRpw^Gp{x1w1(d^n+@heMD-MMo@?BqLM$>sB?8E*XcPL6g z@FAIqojdJ(d@@kK@(!t~ACuoX8*spo4AO41st~7)JY1T&`CJi3elpv0Kp6Nl>>{d` z*=Ia#1OM5H9SA`N|M`JzF$?R+hmnzT-K~y1U~r6+n6M?5*e%#iIhrCTT+c~Hr*_iy zVg_+~$dH9355Nz)MoI&gg)V2J-X_Wsu9pMuu|78cT}F5h zd^+b3=r+NeE7ZW@VHG5n`28N8LI@uHr^%53uHU1#J(mR-ulfQ#KpLVpRh&)yeq1^N z_cG7dE2nuxv7&t}_qlkQij1U0w*kjz)II)v7q*6X_0PERu4^lb$G0ro6v(j!a!YWKYzUrk8>$4MEH+&l6da-{B$5(^ z9{hR5ic#G;jkM7Vu{!rkIz4%;${}V9sEYW=wWq_$RtLkwyZK%W-@29ct2RMLucj`7 z#=D}$h#%rRjW-r2df#Oe3hTaq$MpXA$&+qpJi5y5EiBi*Y?^k@O7i;I(=P^E8&`CnN84*NtTNa+Irb9n)U_e8=ss4LPM{k59 zF&p+GhHK`^TeofV2?$_+pJSlIqXV{AO+~Y^DNW#ZGQDZNXLogYuAb!QPhxTL{rgM7 zr-=6E0wxOO^3|&%4jg(!d>CMF1Cc_#T=FujOfXM;`V&)&$+osjo=E*YoL%?jW;;Gl z*|@r1$v23*!MK>0Vx2Pt-!tdkNM1b$aW;13zk}^ASPL+bf^ITUhSA;~T>E(-=_?A- zm+1L?FWz#8y{M;7?Yg-7D%@7VID}9#%8F+IQljR{bwr&~-Xg=0%(*2Cjnw8on;JR2 zTD65FMS^0L#Gh~8?6aQTLP78dkAWHw-IHJlelYo~^ceWna1*d={ue#LdmZK1(Lb+H z$p_X{9$BLtytAFb2LCC_5yBY0I@&u`&bPod$D<%7V&A^14<8_$ryMy#d6Yckp@1GC z;A9m5JGhkl!U15U30iyGdnZZ%N&6&&@JOXeFDJWSCNeqRf0dHWcP;6}(s-mL8GOE11RO$<2b%D0> zBaQ8)2Sg{wL7{%V{OSC2@nui!d7#zhwR3rQLJb411G|mPgVJEjmS3AC>4plHT_s2{ zI3ou1>OQL5^}))iPInLdZL+|$Xgko`lCn!tjSd54PMu#6D?3yzK{bkNuNBl z2Z`?7O8Iz+y`2+}VN*y7?V~wIgpO>)h;fV&wBv<6SUk<_sXNOeO4Z0&+(aVdN%dA^ z-+$p4!P3guvaIdhOOyiqbFgMqw=JRaH+s-%Sz0!4m&OVQ{wK29KmSxi{3SJl% zRbr?o%)@qeZlQ22d1u`Gt6QL;!x%sx!`E>C16m6@bsx+o1h>bJ9*yeAP?(~Q?s$FK zxr=|G$>iC85x%mACbeAF41>L*8)osP;Ugx3O_X z$4@N%>?aZ(=sICe(KLh)JghBdh%UGp*r?7g1p>sU<>^S5Lr0HplFAt{G%KxlbB8~) z9UL5hpo7+~g`(7qoyp$l=+OyV9okas0~Hk-PHMr=lOaYU%{ef7{6F4^EUTX*Gqu6S;{E3pd+~9HYWG>2iK2#Qy&Rf70jK{11gD$mnHm?!>RbM|!v| z`SRcTtW+cBV=r*n>11qUHj@#l^<; zfilCz#4jJ_6tz2p9&}Vl8)RiBYc0p}v-0LBRGl+%AM`sW3&P(QxvO4!M` zXSyN7ey82Lw|Z)yHX_4z+pfPlf{m*HIl{^kItDC&W~g&KJiKnSN}p(54&gu*Aem5T zytZEF`xo3U%6B&8=$Ks)?8>oI579mDa#!QY1y})h`|3r<(_d~T(RSVxZ&5+dt zd>{Lw#=)GXPGNdvV@@=qx78RveEzoUv??b_veEevTNs1id*=fQg=53t^*fVlSXNfX zHRH-fqj_AAFAr1b=$edJnPTn+g+JIInAz^g$f>$QGYU@Dqp)N-PyXBY7QKTBUYl8z0Y|1aJc^;=vt;u?b#1#6UO|s(;Ka>7Ze-^ z`tdJpaZD^)utMG9+{#Xgn|?Qq{21RF;&nc3oRp0Z7NMhL;)G$b+yQQG$-;$gL}%Oo z>+ZzElv0kMKxP1EgozIN9bhb~NLP*XEwm(|t-g6P}Bu`dUo;Mp2*21Lt z|78sSy|ta+t%sa_*h#&gCuUv7W9IylXO9ciQS6}^vk_=b%%vB3_1I^^;RWA(IHQFW zbywxTsaKR^nG5I2vk@qE3nb}V(>7VD?1r~QD@KHn-aLQVvdQLPl|0V{kKO*wf%3MY zwGRkDsYlPM6&sfS&JNSD)C1eNH4vY1XQW-mf;*M`e2A~k#T9QP zy7!cqXTQ$z*;nghZwdy18q2c&wEjz?ySG3@CxbQCb0^R@0A{K(OHCqX;H`)cdeOb zW;dwXt>!*q?TNt1I@ce+<}> zEN5jo#l{KF3w0Yyw23a*oLQTK;K#%z|MABkkTZ03x7h~gzG-B?4>ts!mzvt$k`fH_ z*u`@PpZ|iGQ3NBF#O*qI^xNoOf$}*cvJsfEIdcdV_3P!WENeKB2qO+%SlHWOafIdJ zvu$nf-M@MB4LVR*6_Wutjwa7jHP^x03;Y(WTM*=yoL3Odwx=usrJ%*^&PG=@$q8#^ z5q4lh4d($)MA*)qv$KLO@~~T~P!s>INDALFR72xLO3Id-ulGbnk&+Al`GS(CT+ zB?8)#hv_b(^G@$opXqRIYWy9dPHa?E4!cUvoPnH?GN+XvM&Lp!PHF_!#|G5WGO2Sox$;=#ojP*vP`fYR zzVT?VnHUX@A9!Bs4fNVTYs|ibNT9%bVza#&6O}^46pdfd*W+GCJJLns4Ik$4iyIMI zyRX9=0~erbfuULR;o(FJ+dNB2C8kC;s{CdA?%{TAP2@1g{ZUt!Ko~>r0U)Dvm;ld1 zBG@DQS533GFCx84(B;tm#l(QwHBo-Gc!7gtfDL+kA1CUZKY#w%u__QRic_q?=g*s0 z(Ny)rLbz!#ekrQ%-MO@`u7iFu?cI8UcWxg^F_t>q|YR;WBL&g zGE^g1V^R$okEMxyHmM*T>Ag(Vj6qS|08j*-H5zE0{~w zQ$K7)4T*@G(Byv?VkQPEm?jObBa-2d&+>Z)^3So8|pSCw?`0-FshTq%Qyqy&mER_)tTK z5AW7nQ(*VD>nMGN4|V?KI<`Bc#GyVCx8LBZAxt{Ocheyd)PDPxar*SZO3>h?rDyZV zEuRuT?O5}a;WD#V$Evr0bjvA^z~;5q>?&?XKG@85ccIjyxb(m6l@jItHgp%c;5kf< zr%z*K{(SZ76dWvQcU+Aof*I3*P(jNcwP%kXLrrG5yzXAtW^BUg6o~5T2!Rfy7hw(o zDh}2FRB&xo!usGPZWFtymDa8r@NC8XdntwPmxIE;Ejt@9P;tYh%XJUuHSIqq`qII3 zcZkU|6Ja9x+); ziC*FG!ZtLT)>c;RH7v->o2%K|Z$QshqfrPv;`=mO6)z-}$dO!bCyCxQMAb*YzYBg8 z**CMw9+P7pbHvb1GaOtVZT*eLj-7IMMaNE@SVzL-n*{}4b5jE&6IO&$!_X9P&4@;B;tk>V+Y>EL70vI`AYPka#7vi;ns_5>qlOccOOrFl2j63atW1D z>)A#0DrpXegafaxsUaM)Q%^N>&R~(wW>Q*&rMV>KcnJ$x2@U+oekfdM#%-Z8%unDj z0yaQU_LA1*%I4L~l~SVR=lMn;J2({5JktbAAIUsEJOW?8XV``NRXyHu^Yxuirj=)y zy{uTdvKe9&hH!*xvjq{8b`H)YUJq7O9Wtb@qB!K{Yw)Tr{m1Oee@EqV!tL6D*}u=< ze{kNG;!!YiADe$y3p+PlY2Q3=$DVbBo_EALDeE>*b^uYWn;s!dS_6R2yWiamWV|2!|Sbtn#Bu4@=Eu9uHC z7Z5y*9xI=U&-mQ8@{T0~3T+ZI@82tZGpgM8)l+HFK$nRIvon*vKUFO*J`r_ZclX2K zyezvRZ?r$WeXG)=6S!~hE}O`JY-_f$>7t~l4HFGESmw#nsq*-A?%ai^UP{^gs?{S6M6k(J#YA3u&0_uj5;!%#d+;eX;_ za&W-8djnhgtXJRHdfc}r*@%5u=R=HKZ&z3(Z?D)bHGflEozdzYrHXXGP)08)bwUAG zy5X;5rjxXLx2)d2C3EJ;K>6bRE?Tr2;Uk(Fk}biKm2hdLL>vqOp^KGYVXW7L6qRiRR`qX4vDv zdb5=*W+Z&3gwVnPL4(v2=ebF<~VcNa0NN$Bg2reE`VO#&M`7 zrQ6v0QW|yYbO|15LV{v=?x0Y7CWY;h>hj(C=^a0)2}&?Qau`B|{Ct5kNUII34)v>v zfj&TSAxvmAdmv`;Gi>9ZB-`!6O!&4@OOI%hYdYe&#EvIf^6%Su&a!M9GSU{hF1eaA zh6V{~AT9@mw6JU`|FY@|$K(3->u@|}&6wpy{;hC@2`tECGfzPtfmtSyD~1gNtr@%g zl_(@TMf)zWKbahlQC)cII4v;AuMfea2&D$C20~tPH=&hbUp=#VGB`JN@yF=DsJ^cT zohqrOKj)YTj0B=9wZ4_LHP6c-kG7;EC|xrz`Yhl~)&#D_jb(cdJDqF4e|KS(FXx?z z59vthE!ObDWwo>8KPBn2s7AGM_%(J(a(KD=>!~!jd7u(V)g3yk@9a04Md4M{mE3>c zAi5$WC1FXxKpD0q-9WsoHHT-8gbve2z*j?M=t~(KlTFPequQ(LcJXS9gToP~Tc>9n zhnmL7Q)tDw--AN;x2_rlw1Mz+zsk}0PJR67uP&|4`^Pp8aiYXutdGmmdGX=}O*wv^ zIrFXt{n{;~1*x5#4J_GWr7K1mm)W-L;zIRE>Y;7Yj4haZbCW=!<6Jv*#wGys{7lji z`49;&kP{;Zai1J+C66M1&u};KMv5^~@Lt<<=nJ^0PWuV-#O@iUe-Wih6@Xa5Hu*B! z!Zd2!JC+;jDhU-7u^->uTf&H!Sr&jO(_?!_-(opo)k2>1)hkz04C*A62q*Z7TYM9(T*ID_6YyZ(^{PaN&mXy%Yz0B8nDao8fZa9;G1rPdCf3 zmIh@3ODw3BI<(CO@JaCk_b4sh9QF;Xh*mB@Y3Q!{jr_#>udDd<07s!R5tg^ywW`9+ zGSTFz_1q*jZS^Kf?V@S61+M`xcF>@4c!jWWR(^fzU(q$O0F7`q&Z=emmhRrQOA|&IEb)D@vAW-n{WY*CIs|zN{9kZT z1MEg4YQGWMlVL!03{DZ81`Zg6IGm(8z!4F}%m9Eqd7h!`2+L_qLnQJ(2{I1SHvk|* zEmou(;gGU%V-9f_q>PiwKabe;v>4HVZ_?&2eUMDsmC0H5lr?h?J(!+e24$bZJvAkz zzrG)Al>IsLX3^yi9LU1Z?e{!BKRZ8}df8%E!m04qD_1mtBCoi4@y8j7H?wW#e3?L2 zY#>lDvIHq&7!11{g05hY0r`9E*o)NDpeYWMCy&II!0rL-VLlZnb=-XOBK1|H8EFSc#?L)y3dST9NQ+n# zfBg7!ZUGFo9g49SQQf$rk?Gx-gXf$g&Hj*h*rH2v5XfZrsvoV#WXmF`t@Ym7v?3$OCM~T2D z+$Zdsg?Y$pyBH|9+~nZ*6Uyq%R6c1g8bQ}hh)eI+PNXwjWkYtajd||uEV9f9&7M;< zdfx-RC8g%eAR6+e<8)_^CR1y^+{16UYmso>yIflF#v*UCf81Z1D!=vyIQ*TSKQTXS zf}7_-@VG%bI%gMbl4yC|M9lT|>$bnZYJw;FVqo2g8R~kYM+^8kpy5=sLuJLqqXrLN z0Ed;^WbfppuCDG%KJ@lh-+c2cx$$zqh>+}op--PZV+AgqJfyZCpI-`F?fsi1cl%+= zPnstClPSpG58nMRP;~F7b5OBU$F561%Je;^u(4A@aB=D1rUN>s>zaFMU2lE6JNP7< zXQ;FHVGR!<7m)R5jbffsVM`Dlf??24O_rC)XtB|lCjoRuU@Fr0Bbo3+O8%CaJ*%Au z5&$UF_NFE|^t|7rf`?|!WqnaQ#2)#`pSV?K5id3KQqnSxT4ruNu$TmpyWB@=JJ>n$Yv zXt`U`!;#e)O9llQZoWB6OAEfh8Vbd*KH4dFSq;=vx8VtF2ue2uf?uc1ef$1Bv;TpR ze@#v2!qJ5pyX;V7)fVeFZ=4N6yCuCBE$(&j#*mvfb9i%0?!y}5vJbz!6C6G|e*$g> z|M@a`_M@pWu=ZMozY@QDF8ivO0cu1yK=^c;I<>fl)Rfwlx{a_$F+r9m2Bp!MzArC- z7=;^}%`$khYrValzepM6(LUP}XH82o{BhZ;Y zzYr*b;t|8tj^+Mno~04IGQXFVNw&VuR}WKQ_6q9`siu9krV9_~Z0Agsvfq3Zg{YIa;y9il=OTd}7f@6Oj>Q>-|67#Ge&t z2MHk`A0~&xO5#Y8LYU-OOw|}VG{$gs22)`^HBGmhi_0X*yn+J4ehQZvp+Ak-hXbgV zm;e5`!Yh!9p8j}mcMJAJU`9jXe8Ke-)6L}@TH{?DBdg^B0qZauTeC(#I-fl+`9prp zS+b4QBi*&SQ9BnC2Y#w>5ikSD0pkcJ}le|cd=(ns@F>PmVA#Vh4Z=q@V$?q=Ni zerc)Lv?Jkp6K)X=p}x9L)3$JREWGQ7xHLk&BNYxGDgmND}vJTPL&km&gM zwU8Pq$D8R6LU&P%{$T8=B8%Gdo8Wt-HxCvJEjF`8q=?iiu-{AfG_-~_6HDd>s3@eA zC^VRF4jVZ#`7U%RVcRS6K3F&iIT9|Fy@TJ3fGt6D?jKA&&Ybb3wpR+xeZ!!+yBSPk zT2UG>&^xp=uNVeMzY5*OV%Gv(^Xsh>Cv$#^u5Rs z7u10fa?@0zl6DWH@HbDi9E469_?uYiPWHDi2lY z$S3@e`SQ~Ne}c?Qi%Wq@i_7kiT~mG$Gbu-?+^MnnQO3qU9O3Fxl(OCQ)cNz#InZATsqNMKx>BL2O^iZ3?6p zp*%Q%lcEvEH#Hke>JrEF%2sy5XznS_<{jsM4+&X;F{2ZrGZ z_1?FXDM>H{`E-x~p#=~NcMceL38gNZwm*EZl4L(*1DBT_Y#eOfEZ%GVx^~^cuj<>U z4?Q2<4MAQ1ikXxp%>uTklJerkE+vo|Js(hsYpMLvHXte2VXt|g_Uj>XTsDcv}g4EDieQZt`PDN$)ME8r`17h_O|jbM-oGUEdR^pxC5 z3F4d7eEKRaXDC?pD~3tjJt7&T*l%D1q&<$?pis!3-+uiD&!l;jGb8$>7(?$^N2+4M zw$d&5wJNgR%~lz{Xj$S)-8Po>)LaTFCH#HSAn`YOlz2p#IO6nZvG#~jql$BLH?O<% z=BtKV7DEgRVVNnXHzSZm@FO%dTKZh}qA`gsEh*6zzhy=NiX#qy5gK-%Zi#nC!}IO4 za#T&-iLoyRwR{A&yTt6mp(;K6z^7w&^}UX^38~$9zj61hWD<85iSa{wI1F=RxmC-) zH39BCee|fR(qX1~OM!lVqCv2KMwxeTq>_wT?=BJ%cZ{oETs2TqVa_#ve3DdM>v;^W z{rPo1Ej5_AL`ZjLDHTOZnC_Zw!JOvn*I%zUE2<1HfBzod88wYVH+maBv4aYYGF1qbHb;5QqjE&Yq;xCfhd zMEs!1jivn%$O#yDq1eQ=3tFqN{&B{P-oh^ESw2~AOp>X4&9>MN#hf+HeL9EETW{Zi z8`B*feWBqBRPL?jJhucMJVF;`k0UNuT)++ZGGH&wU}oxxzNv=~hu-t(*Sq)Gr&~lt zC#2d7%;d_Qdnmp+i$I5FTOf^a4B%t70CTh(p)y7ZZg>?>75d=3yjYz@vf;T&4{mTW zgWI&@siLbCjB6Im^Z!^nwPgi)cQaZb9+@MxHax*33IKfZ_)EU*2T7jXwM!SQ5~>FP zo6u}<7E#nE@VH_KquIMls%`tWZOVRu@8RgyuhKQ+=-Zq1flor0brqR(Jj?W_Yd^iS zZ}WT?cg3a1-VM6G|Ky#A{T~c$*Cp|diR_HcgZvk1!q}FQQ$5QaFn6x+b-mYTxBb;Z>Id3&5;lY@W^E;Gq{HF@d}T^x#P6>=zhV^=#j+-7P)FX;kUAe4F!#Oi<7bV z+>RZ#<4+f>PCmfYND$!y6fpzRH!v72HrLAB?)+kkg>7X?eN z?pmtE(M$>MlA{UtYz@SKmd^-q%s-z&Z7#3wAlgyifA8&FrMhDm{rA6dU!3Y2*1^;N zN1NKnz@Pii?A$wX!m|N|^9}B=2>Cyb23$J#JoC0Z4NG0btVAN7F{D&rTfjM_L-_TA z2%9IKsk9WpOBckdBk1!UJYZSja|BxSKwr=n2+t!%3jm*77{rcL282w4>rAMjFk`3aOUdC`WSt$I9iV0jUsHvl0uC0p~$5eFz1u76Iw-y#V`)D79 zr3D5|K(n^7K?VD{b-K16I)#!MD7OA1j+D&(N|DVjo7KCZi3JA z+Mo9-2gbb}SX3LXlHPOfv-JxqkF5`Dv`Mnq;S7NbX9!3Cr~N6nXp$wB1R~s!$y7Z{ z4I&5q`Lkp|=HrVq0}bB??W|qp-R$;kWX0!f@B?Q1FrxsbJ|p^cb8ALc&pp7MnvKZV zDvcgBN-30KnkI4m$`w}^7r}FzcHF_y}j`nOWE^Teb|wzE_6THv6G)J7@BXxm`RKRPn;? zg?^;#&Cd}1gezxd^?_m$ZwRmP2OVlI`+fMcs!G@^g*qee1-vz0O#DSssb=Lw=Fu7F z=@C8FCpgR0z`GtRlet3S`^$~BHT}fp6`oJ-K1-_o`Ajz`Bj87rx7(9o=ShLTo2+LC z-k>qH9Pb-E4w&oM$*eR-7Rv0QrbP4yxc+$N+AfJ!#3>=G#@Pc^v0#*FLK>p6EAg)7 z>XCz)P^5GckPn}?mVSOeh+M5-3F89gWn>1*ZY6mUT{oI3O{FyQ1w3F9hMwQ`^t>F> z3*?dy8}N>SW=7uwiLICV49X-fG9rQrk^uMDL3d_fTQ?2}f`KOC)Mo#fQOe5mfL?1( z)&kFdB9d^x1)2^>Le#06DYIZr8No)U*@FnMM?rgprsgggAIPz0mh{R1J4ahUl*!XQ zQxxGTn%$wpdwDf57p}lZte5an@qVhA+R#>HB57q~b6B;}E1!<~V|6tR8*s!K0^_;J zHWH#Djko3H5D%b$7!4krlb5&ko(Cpxkfa{2jN%W%;zziAegOeSd=M%tE*?AxK8`~F z{;u}+EX)|5=7G&T5!T8oZ?bXYS+7TFd>H$SGkZi>IypOo#oVSxB~)+C`4gDYen_Ff zzU4Ub;KJ(@Eb2Hh#0}&_XyvjF9yb6Re!ZNr5%as(pFcOh&67(#_@IV*Fy-Ml(D7+L z_KcV|-H1GG;J3`Sep*Y_Bx5u7#Rm3dr>>q;L;Z`Q&6wo~rl#45*&yHEQ|RYslCiMu z__p6VDmnJ!M@(e*-Qybnq~An(k1HszbDBPV;)DrQ({g5@sNV?Qti3iiHctBv-Qz*sItHYI?|;s`#=2|G1feKPmA+$r zR5ss)Z1aDgg}mbT$(gloVxGfJwKs3ZOD=MsEMq>DzZ3~o38qFtC)a8WEQ9LitA^c6r3Ittvp%>0`uu&fVk2GpfBSyFm-7~3^fWOuMh18)k( zc?alB5#tj$VQvvsCyjty(KDy~JEJym(D3@XD=Wo|fJNzZ8R1ZpT%{gk5Zh?~poqYR~Wo-+#R}>07lWSI1^DVniGVs2n5)`N-10E-6_DQtb zb30de&&|-)H-z)^Dv53hPaD2u%&3%lhc!25y3CqoD>)WD201G%EQ}fHgmfptG`>t_ z{7W^*@@@deC!uS>0zh&LvvbWQ^}ml~HtA@7&hX|2(aizXc$}U=JJBqF{jxH)z+>9{h{~piqkX&v?RY`jwZ)-q41f9_J5=x}qf=Sr18R>|xPZan!|y1ghX z$g*wKa-*0w7Ls_nhwl3G&v}(|84P{D-Cki|m{W_$Az0OP*0m|qrg><^Qq?7O+T69D zh3(Ovva;;-+Yb)q@Qxn8zqFv)pt?fOGL5CQ%a?1e)t#iqE1TVcq|0!J<^zh60G@)H zj9^L2$dQGQAMcH;oAiJ#7p6WN9(0$K>W~o0jA~NVa+m5;Vg&!V!-vn3u84um!EV=$ zPnTSc!y!Ncep(4p%G`g&#+Ti-Ul^ zcEG3Cud`ctnmn1&tXPKWftN$f_b*&c@*A z=iOV$oZ);Qty{3Wz$!J4UmKa>rXf776$26YjiQUA4rPLIz^L13UERia(Qc3|uK>Kj zYAYP*p6nudEOsTv%G`Ep(MFpuf!&W~_DWr1=*oNoTDTW>Ltf`0=ue*2a!;95cz z=9zYi-@%B3XMQTmN|-qW*@(WC9Xm!%`6w5F=Z*dzB9Sn)BG`ijg1D=>pDE#VjRY0q z{9)6DzlfQnF#Y-Rs!e1bI)8@2R1Swdj&f*fxoDIhL`iaLYOH#j#E^!UAC@&(cRr%! zZg5|0>ZBG{-FW2Tg2P9P@5D6b7Z*<%+GCr!vILy@gTlJQCRlsUJD$tSM6j zD-9$F>j~_;)+guh{Ti{?rnz#=%OBy7Vg|L-Ip1x-{5H-{J9ayzD9+kB!s+bCuZHK| z^dJ3qj-IJq?#3Xmf`o_XGVMo=epD`$ObBA&UJ%zYZ-mj6TrL%&Djslcrh<87|MsO# z5r;FCy&F#2taS)KO@I}u?uj*yc&{R0rzO+<7&HVx0+;N(!op=X=lL^7Y$0V|V65+i z%Brw83j@V}asEo*oNipd#Gv41NQS~#pHTg7G!`Y9i=#Jhp2*N3zsoEKheKR|q@>8` z=qFl(0{V-?MGEC6;@kcO>wA?xS!SP*lr(GjvT&94myde1O}hI**bxrFc0I*@=q_k= z7+OBLCVx$U;<{f5pG6nO`bGR2BP-ptPJ|g z?F)j}igzMC;{Z+GKZc(5{yQIbQ=F%mdc2dUmUz+fMB8Dp)2Oq}mfXqD7sv$9aLM7l zEuJ=QFZ(~S?lD}gr4*XyE^7v(N5J18G9tH-QX;@PfvUxAdVj5buyhAVbVU}$sdFqX zHr4)NbaiPgelq*_)47ne&tDf-0x#*>_-v-*Y6emVA!#V+i_ey|6$Q0{IG4I3BV)0C z*@eHj02v&L!73{J@E8Mw&7q;1y~79>zGL>2*{HH%R*)C5AGL|oNli=hB4zOlXI)r6 zw{co_b~X(kWdKMZb~=Rj)lI+0?z>0#%|!Fc^4FkDX}At%1+Au`Vvkeqo@hvIymFrDW7rHUjHn(N~AnfKV&i*)2uN z%77qT4Dsp$ZE5H(VhB`godw55MfYESIxB4}T^jPZDdwye_*S42d9JBf&AlBvcj9lh z47?Xo1EUxAui4IOH!u{G+opy1D){A6gY)-;L-9%Ara93yv+x8s%C8U(2jk>NSd05y z1nTm1I}_eA#We}cE&rY>z|EH~T!4p&XbnqZ^aZgpvORjR1?B_dRk8<8NI3*`7I1*j z0>)j&;Rg!U;d3ZGpe4b;XvA4h;KH;eHiA8oQ_`4oFjQ4K%sXQO$(jrxXUVQzfl^_P zPyj{t6+ooPw3qnLQmeDSVVew|X6Ru!c3=PizbQu04+MKXY8@^V?sQ+k<&S#7Q20$H zYG-ZzfLz0d3$apGedTaM16rp61DYOAHlFgqbGLyOi`P@*A8uWYFO@L=?*8FPANt3= zKb!UG5EoD6xg9tQfeeZ&P8DNOsO~`ZVRw04SsDYIuDu^azC}HVcOuTMz zr7wD-hn5b^fYv0&<~=1kM73>EX*_?sdX{C06E51?MJY~6#vjh{r0?A-Co0ua5ggxjqUkuP@_VD~ ziH*f7gAfeC9Ze0sbg#(<*wo@uftv(^ZEh{psPM2bCwu$lD_1I_ZGLo97zQ>s*5Lp` zK_O=*6dQzzmS29oS8&d}_rDcZG<bsGL#XID@f12~(9i#cj(5$x zd+*)?&EDAFh;Q!S-(MnRuDd&=Y#P$~A7BXYz{R=EeH9ealal0m^{NB3LK<)`BjW)% z#cP#7JEB4+p;FjHaURL5Q>QNQ^0LmI4^_4L=_oH{4KqvHK2*J|<=`{Hke;=!mBX5P zdGgB?M^qRXnKG`=Q(&Lrl*apttmk0}B#_IjCQn|d*&7{O#GsY{aJ`qh#;4|y8_!a| ztqEib%`rOW$m^UA-6a$=-Qf17bY;XuiNokHdFJ>I!L=RoP1h;GZk&L0Q z?A6n<)3`!q|3L=Za}KTh0f~xu0WA)Im3fbo0xEfcgDY1I%`6$|r$X9U>ov&0fZgEp zZb`OaG&lLsI16P~9}wVDo$VzLErt)vD4W&4a!>w;3umnjMFaQ!4PFEWN`lD)QgQ@NI<8p!C~=2l zz`T6P?xifWASL{0=EQ)2??djA5ydIHgv?^Vo zUYoca)%RRpu`Hr&;!dpry%RRj5mtQoGGsb=+hJIR7_X2c$Peay?g6ZIVy&Fvu(VtVSFK;1YySzZ2&-PZj( zxAVU-%@)UQwG(C7#_8mN{le#GmPoWj7rqMe0Um^)VxOw23<$AimIC0bBj37A)lTl`vSOhUNla)0a*H1=9rgv}8B})|K?N?kogvf(IoI z?JCEPoU*Ob8uR#j9=W$~OM{3^trIN3U!9p#J2LoOc=nuXsyt%E?u`V>L+3GR8NY;a z0rgAqyBe2AGheM^0Q}?JwQI&T^Y_5er%dnL=NV_ZYESzP9Ugs-hgdAa%OP)nd8_jSY-KWi}*e?LzP~uf2I8EwuvX3@Rmt!-~h>Yg%uq0PUD&j z`}BWF-OdgU!b&a*O@4%5&F-jfdax#Fq6OP3N?mFiipW&Ism@H<=!12=z)zhaCO~T( zO+e+XkPEQ+yLR|6GuL+zBM>9NAOXl>_>sbjTe2|ViugD z?OY&dT^lbEqNMvu|KtNezkf?4Q*WLOnsB?Q_c0Cli2;FWNv47f=vJ8_o+Drva|wakmQ5ZTGIPr5l&ezFYkL9`7H)aT^#H^!^D%>y4ntC?x@{!|

    w}E2tF5N$FdUm{Jka+-;a~s;DaP~Dzs?2qEBs>Ep^UWZ!DK)9 zcv*~Ry`j4nWXW$l0X}2;t2G4R6UQu)kuOaq^Ohq%E8IuNj#;7nNQFlkhGNqOyy}Fh zJQWW63wfrK6V@q*t_lp~K^9nXOd^;`pv8loOF(Z`Tt4PLfkJXiCLj6eAool#hU6`h zH)@_)e>`9nH@8{JYPEX&;Jq-M_^0EphNpTY81 zCiNpEJ9XOK*M0ou@hg>M+dMAXvg7wFl6SC^x<}ctFL~FZy?3>dxYtR0LuNl)pI>|L zicsMtJ&~5%YRYpAa7cxKRCZ#4b(56BbgmK*mS-_;Rm@?%wTrS3pSx8R- z$VR6Cqhr z3H)dj_Pn0rk?I$_OTaP`RUwmi# ziYiVKkJ$vd%1pAcL1A3EVRZhEZQIfuU*5WPxGCHd=jFLSZXdt$qCRID*!V<} zfGv;qO(*X6Y&+>Iu*d z1LKNs==3$ljF~ZOmS8jNzx#US#0N!9R9(a{S|*2{Dlh-2H`P09;IALi*lBcA2pFDd z$A)~JqItX8Ki*&&-_DyGG4C{cOQQ4KG0)W=tmOa>-Ahhx(8!U-0BiL9fS%-1I2L3~ zzzX6P0O36>N7I} zL8Ik3SW6-*?Q4X6HU$TK32S-5V1YA4I=hUT04LW^_h~uV0G$8STQ5^$hYEg}6bI9` zb~KXQZY-4KGG_FHaMn`%l%c7$@OPz@u>XTAglLq;$wu{|An4d$AQGVo8H0i{-g@Xd{D|%29cM*SU8zS2E4euav31J;ef(cJLuiIfJD?JAKYpf zT?+GW%Gx&VBpAI2;$r+>AUNZ+1!4TNFC&Z1!qbqPC=9X)zGRrSWPFH zhsuN9r(6B}qOkEEHE@fJiBH82)=o<1ZX9@* z)Qt}9PRKpu&T>rXw+QT2$JY+ad;|bJno&Z(elUc<+5`y}r-dFy7PcO}?o_t+F%D!f z4x~-#)#sR?m;GD}M3fz#1!o%?`Jh(id#j{$1Cr4K1a}?g$w(m6vT(P1k+# zKQX>`ONQ~Pt{2xf4_+tIKwVpmT3!BX(dY=`kZ17iyqj*+$s43KV*12l}e$Ary z_YSJfN9T4ogB8grl4po;N@bC1*3!QkUQ%2m^$Vb2(%vVgWqIb4*G#Un&}LW=G&ImY zwQnD*@hPf)p|o;}&su4{XS<|E-v)`{i-hBn{G8#;@Y-_<)61aTiLu6F1AQt!zf|>o7-LKjODiA%CD=h84vnshxZ7JY+Ym5BCzCCph`iXA7gIpL-`TZNuKeY$h>n|5 z)8eFjJ|`-jN#5acI_8sxw16g=HM-}v{!ra(oBkZegQse>NB4vmT}VD(Y`YaVgyWt1i}0$QHDy<#Ls z1Hz{#e+fxJKI#cOiK=pyPv*p^?YTeuGJ?G>n}5H9C+lD zbfZ-22`H!N&4in`)Fhmd1ggRIu8~yPG#{ zvflgTU~=+k%;I5&v5bS>l3X`AV3n2x#ryW~@FAh(N8bBdZ9Sn{3V+?8! zv0~2)tgX&+5_emucxA`#xUbO%=FhvLpY&q3_R{BL7@kvQAOsK`>9zF7 z`d99`b`9C72U!fk<%h%X!xj7}%CJhIY+&P2fR9goCd};m+T|E@>7> zKPW!@K}PIk6@f8aM({In+4O9pC~=Tyfq8w**Ymaqzg^!|)1gT1%cFLpiePA3tWwQ* zyz`K4qWl)`&ZTxL9Jg-*_%?4I9m=aX`1mUgp&xmox;Ojb!^k+tmoHvGd^$2LphJ^!rB7Ixp=Ron#k)pJ*h*W?Q79t>GW2x5 z_M3<0(0L+jYFCYDnybN?imcBRR(g#Z1nZtn4i3*CHT<~xGjx}6)6b-JjhiHvc<%i3 z_Czzu2>qUH?#Scz_AO~AGO6nHzeq{F_HRDFp9y5jR+9%;_GSUoA(5IE>g`|Sn2q4- z)KC?Z@2O{0hG(syh~aC*E3{Bfl|6seO=GLDpjWC_8ylT}udp!Md!D=dkL;yz)*@nR z4_s>FphwZ}HJ-5-q3E=MNO8P{ns9b6EK_tA?Y^FPgn=CV7nX+zj3_WUD&fT+w=nkD zM17d4gucn!9>;?Y9X87MgYlpE5iL{w`s%Wku94FljK4&-mo;y{U{87*^WtfHhHVQ> zJTzg-A@A-}OeYjy>NV@}#(Mh^&WDZuOp%`wBvUy}t=ohJV@x`4n%k%CUD;oK%?DmH z{^a&~S(cUL_@hBDnCV>d_4(v`BGN=9&)+S%#qDZ;o;x7l3I->14WYZfd|3|Vm~;jY zY)X=ae?ZJQh4`(?dpm79-XnOYd1GbfpV9Z9JefXW!UEXY4xekjee26|kkPo2p8nbz zh=XKr-F>>)(-WMCqEl_-u?rVwkQ~p3?00=Qv%mNv70Zteq$(GQu8Ifq(&mUhf^8Pf z7L*iuw;2@^V?ak(jl7cViNt^st@^knk@H!gm#AVa#QXS$!D|djeJI-*b|TD^F=NjN zB-J7gEi^z^Jh|BY1pT-}hZSSc8fH)-H$xcf*=Zvr;9pFwPEh>LzfI>$6P1b38l%}C zFET0Z$-dOWuol=flK<}9o4A9=ZZvcfRlKgaadVzPReFA*I6K>9{w<$tr%Y8$a%F}~ zSVY8ky8U{&%E~hT6)Pg5qnCwCwq6ON)%2@81`I{i)sORvSc8HMj!=N;yO0D=ky8fj z$x}vM%UtB)fMT;_R!9Fh*t@qMm62(`Rlry7Nn-KvyO7N;Tk>2g4Ajy2L5AlIGDmdU zj=2+If6}D+r)MzGq&}DK(goY0llHu#y8G!Fz}o8alWI?aVep0e^Uw~kb$*&ieT`Yi z)vH%oDIJ&&1znVw&LDcIghaybPrJ*8>e_kb%N84+qHtk{dlFj>a&s3VYw;^2&hzx* zEETtJAJb(DY(JZ)L>Wo!4l=+vzkC@3iu&l!*RNMFv}CSo8z;0 zI*|fz=j4o~i=HvV&oWH-BuY+JKS?f??>UmN|1_|eU%K>#oi-|G;W`0`FH8PvY{Bm1 zn!+L)1S<9AWLdOqXCJ*f)OoU<-MLezJf}$X&W=QX*IXnn8s0qdFD`&MY|EBiYXs#- zj&tAPfy=NKsCqo2auwuonkB9J+}!5Ry*k1dUApLck@9Zc>l|jk-YuiHvu#*$I!Ci& ze(_~SH4~Nr8FV*;-j%WsCqMC4iZGZ<@jNSV>U0E6c^2xL(JiHLN zZ|j|0N4g?G4aviWRR9R|oAUA@eQDw^zP-3x8_CF|9qFfY1v&-u%W&$_?c0;KIa-gK zmGKptwlI9*lF=mMRf{5uCBNf*=z}Y6lz3xPlZC#H=^=I%Jr~aR^}jr%iaV|NU5*+^ zVbIvI!frzB<|!5k6`iG}KUHr@l=4&Sy={YO!=e&h;i)a^{o43e>ASa0lke)*lsu$} zb)x{JxJ25jHo}Gr!*!r)rK7*r+!RPhIjLQu#y5h0;!-B#=a(w+OZYVpB_}PNnVKz`srV^O<)RyS#j1B!Ymw9b@gg0E_!kJnUw7Zc=WM4 zz?T{QHPs<&^u__(y;dZ z@(n6O@{S1YY=_1Bno4qHaKjZvHcDx2W-vUhK7Iq($CNgoW)UF>Zw3Ltl0Y|%OsAE0 z(L2#YPHsM+ErLRAZ#;@%exbY(uQFP^c-b;H*l2Ctg$ujyzSYMA&K%~`_%^+y$;v1w z1?&{G@9?u9C)IzR1RB`aW8k1c?Rt*K{mY79X73Da0VLq$=qQk>NVECz>DhkAV`3in zOL42$WUil6inQ52%ayBdYdCWzwd$!?>?0gHcyOm4K}*Lg^&2#(obyF*=OKI2NLOQ2 z?3Ai$vkp@U=TCDE zgc)(eV?X)1%iww7*MkNRW``GlW>DLkxe$H}=M*&v&m#}nRXn1>fB*u34^E#vxq>-L z?tT6 z@>_TuB9wzmz)En|&Y32tuuT$2Xch((7AD4QU~()fDk|c^vXo6+WEOa`)1eFFt`s-k zGXsNy?wiF##P;F1QB?`0Dn1%?9Febuv0ARQA!6TJ{Qj9p zk+tPW{)X^u=ht^SWIPT7X{6j@TRofSmoN_|+EFRJnKKVh+(INU6ZYT8gzR<6q=?Z% zPJ0i#g5U>vGcnn|jyAYQz*%+8h5XnI&7y|T&|-!99R=YKvB)pCa5?F(2m5jv>}ya9 zn$MWg?xBLbm=Q9fv|~&K85*cI+;llBt;IfotgI|rG4ekreYyiU&!;b6_z8e-cKzCA zPYsbsigo8|Z$A4Vb?vh&iTJ|A0AIc#l(BUO3C38K%o5Q&_QORI!Vz@S+HVFCo3Rhy z%WuRwF@%p?f-(r1){%&pdc)rMok0GIDk`ug-zuO*IDjU1Il z`w7vvxA+}u+HTz*pKk&huzyH1<%AJO*YFpO4lF-;n3=vpX04Y%(Lrgz0yc1DN2Z}| zWl_%l?29)sQHSIT)k76wuP@8h@Vr~;4;B1>UO}F-Dr{mSDODjVE;ONkMRJ>o%5E%yy zAOWKI?w~yk(@CDhl8-vA;Z*r}1t8S1`8u=0_{=EcX)lnsR6e=%p14J} z^E4WGoCPGhy53f6ki$Wt%>)zyA#h;8Id{nrX(b}qfr;}g_86NR=< zjFL-8P6I^FIF>h0y-kz&8}-9mJxtLYS-Ng~^VA7hQ{Egl4wz)@cP+y4$74!Pw(o&g zc-;{%6mZ|~B05fU9!^%`36@S2{Zt@aZ&>t?hresnwa znq%~%t|~><-<;O45G3G-f92u(vo94z?EBF=)nTODy~IGzUH-olLr#oJ>QB{3xC9d% zf1J219Np;oDT9?fun@!cVBn-ltf$V+%Cbc$$3p@de#ysY7KIa20Nb|R;0%eaNN8^7CteNEnTTA7&3865i?4y<}qn{Lb7fC8FZ) z!(D`qEGsWhw0$yGdCt5s)jU#Y-+!SX;li;Utsb8t9+PxHPG(q;5K>jKar+JL3`{+$ z1^9E}3)7~+OG6^?|JTEBg&zgWyxY+7?%E@asGRlk#SHvHaq%jwOMWnNnx z!OBv&%}nRip3vPxRH7a$JFPbwWLwZDuczx3XWss)@A%=!sN#3(!P$AmsV>_6FDU5P z%jxD`I!2Y9zZE^1R`1|_cEw3w(%Mf#E(*lQ+fdGS5*lcsUf6f$$vrbFmO+St%*;OVju#dTk@4Dq$_il(4=HDs zJ>b`A*O7Vj9J^)#8g?_Y5T=KD7$PU59aNE(f-hr`m?=t>l_)Q!75g1M%Idu_C;`pQ zJ264Q^0d;=;jXVRq8TuJc#xmp+{KI6umOst>B!i-XA1XLJYkU$#w-9h81UscVojvj z0zAb>iTn_1c}U|MshaQ2I+Jl6`4=xXzf7D&%G$_dvnJL5+%SKpN`)@5iyAtxm*;rV_y)C%+1+hY zlZe6Xb5<%zN3F7cyK)*ClpFpNNRj*3z3mP(*)(+WJ=QUm=dqvvY21HzBM_k`u<`z? z9WO5)7LdhWuF?1_d)QU=(2VI_hp{~M$xWHHYXR@#VeFW`i%29rH)>QvNB z$YDBaBa~%*r|y8QADt)K7{hrI$R8`7`U84*BApK(9_>lfpktON+i3aB^ zW=Z+u*20Jh1yQ7dEEZN$O7?$jV#ueD@$sdx2UE6f(>7oEK3qnVJ|_KeU(@-npaYvMXGz6iq)Wjyb}V*~E=+4_xFUv(XqIby_aLL9#W^{>)tr&zS0=Ec{yOI{ zBLl~&)r`wiF`6VZdgj1zxK`Fcmvt&md)4r!KdceiucGs&b=0bd8FKjZ6-$J#L5=Um zMmumMX2u@s&W#lYJ;HGkbQ#@d-Y?d7Ft>!{pF(mA0!U`jKYahWf4?mFEgBru>upEq z6MQ*})IpqY3yXeA78tZ)qQ-aul3;3M0MJhDrmb1meMR!+%V6>fJ_Cw~wG&9Mq-_-P za4Vln6njdn#?WI85<8T|#9emwOr%}Fj`ZoVbtpeJ)0Uv@rGEn=eZEeI;6t zru%t^$`}m<%;gnaqBr!-u!R{XswcrW5aG4G!2x`?@17fbWJ&GS@a?;;Q$s!#8@#(} z7)K!t=mOcaeEXg=^#?QOkxsDeqfftJ z$H57nx$W1jeuu?QXOoxQmiL5?4KV*5qtrjX)>xX%P7Jw1ub&O zxpOJ29}NTEQ2tz>I$fq+ySen-EVanVIXcPB)i*!|@Q=Us={EAlwQDaR+)d0`e~I!2 zPK6Gn`03NKOgnjBe}Bvv_?iNA-{|a&;az6g5c3brxvl4cM|Q(X_tsKU`$yh^uq9&9 zJkSFFf!{I(Q(k)mL&H5Nu}}c82)V!d8i}M3`~%-c1ksGis9UB}=8`z|QZgI+of-R< z!wg18&ss9>xnb;dJnsS9*8H{tc8bQ2ooIjZyD;hzWMo&uf1t8aLX4 zV(B_SS^450Pd#L{>1Ws+rmp6$Tw?7b`B7U{hnR6}cYXVzimG$uY@dV;=Gz%a)2muzZVnrFnO0c9WT1HjkGV!h&h#u4 z6$Ak=1oEenSoFg{w~_~98%zE-IvXNU9De4f+O%u;>rv`&rq>@K?P=fMhhu!{)sn6G z2O3mE)GB{d3%k%r1&1?A!AnXB3N_fYto;eB8v3=dg|26mY`5A8MmoNn>>`c@z%j1{ zQEr=m))!bZh;gB82?9o5Awz*;7}?5d?@F`=l3n|D�C>#;DVrHdtQ4bTQu%6pA8s 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